package com.fruit.launcher;
import java.util.ArrayList;
import com.google.android.collect.Lists;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.provider.Telephony;
import android.provider.CallLog.Calls;
import android.util.Log;
public class LauncherMonitor {
static final String TAG = "LauncherMonitor";
public static final int MONITOR_NONE = 10;
public static final int MONITOR_PHONE = 11;
public static final int MONITOR_MESSAGE = 12;
public static final int MONITOR_UPDATE = 13;
private Handler mHandler = new Handler();
private DataObserver mDataObserver;
private Context mContext;
private boolean mbEnable;
private int mCount;
private int mMonitorType;
private ArrayList<InfoCallback> mInfoCallbacks = Lists.newArrayList();
interface InfoCallback {
void onInfoCountChanged(int count);
}
public LauncherMonitor(Context context, int type) {
mContext = context;
mCount = 0;
mMonitorType = type;
mbEnable = false;
}
public void registerInfoCallback(InfoCallback callback) {
if (!mInfoCallbacks.contains(callback)) {
mInfoCallbacks.add(callback);
callback.onInfoCountChanged(mCount);
} else {
Log.e(TAG, "Object tried to add another INFO callback",
new Exception("Whoops"));
}
if (!mbEnable) {
startMonitor();
}
}
public void removeCallback(Object observer) {
mInfoCallbacks.remove(observer);
if (mInfoCallbacks.size() == 0) {
stopMonitor();
}
}
public void removeAllCallback() {
mInfoCallbacks.clear();
stopMonitor();
}
private Uri getMoinitorUri(int type) {
switch (type) {
case MONITOR_PHONE:
return Calls.CONTENT_URI;
case MONITOR_MESSAGE:
return Telephony.MmsSms.CONTENT_URI;
case MONITOR_UPDATE:
return null; // update uri
default:
break;
}
return null;
}
private void startMonitor() {
ContentResolver resolver = mContext.getContentResolver();
final Uri uri = getMoinitorUri(mMonitorType);
if (uri != null) {
mbEnable = true;
mDataObserver = new DataObserver(mHandler);
resolver.registerContentObserver(uri, true, mDataObserver);
mDataObserver.onChange(true);
}
}
private void stopMonitor() {
if (mDataObserver != null) {
ContentResolver resolver = mContext.getContentResolver();
resolver.unregisterContentObserver(mDataObserver);
mDataObserver.stop();
mDataObserver = null;
mbEnable = false;
}
}
public int getInfoCount() {
return mCount;
}
private void updateMissNumber() {
int count = queryMissCount(mMonitorType);
if (count != mCount) {
mCount = count;
for (int i = 0; i < mInfoCallbacks.size(); i++) {
mInfoCallbacks.get(i).onInfoCountChanged(count);
}
}
}
private int queryMissCount(int type) {
int count = -1;
switch (type) {
case MONITOR_PHONE:
count = queryMissCallCount(mContext);
break;
case MONITOR_MESSAGE:
count = queryMissMssCount(mContext);
break;
case MONITOR_UPDATE:
count = 1;// queryMissUpdCount(mContext);
default:
break;
}
return count;
}
public static int queryMissMssCount(Context context) {
int smsCount = queryMissMssCount(context,
Uri.parse("content://sms/inbox"));
int mmsCount = queryMissMssCount(context,
Uri.parse("content://mms/inbox"));
Log.d(TAG, "getMissMssCount count=" + (smsCount + mmsCount));
return smsCount + mmsCount;
}
private static int queryMissMssCount(Context context, Uri uri) {
int count = 0;
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri,
new String[] { "_id" }, "read=0 AND seen=0", null, null);
} catch (IllegalStateException e) {
System.gc();
}
if (cursor != null) {
count = cursor.getCount();
cursor.close();
}
return count;
}
private static int queryMissCallCount(Context context) {
int count = 0;
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(Calls.CONTENT_URI,
null, "type=3 and new=1", null, null);
} catch (IllegalStateException e) {
System.gc();
}
if (cursor != null) {
count = cursor.getCount();
cursor.close();
}
Log.d(TAG, "getMissCallCount count=" + count);
return count;
}
private class DataObserver extends ContentObserver {
Runnable mRunnable;
public DataObserver(Handler handler) {
super(handler);
mRunnable = new Runnable() {
@Override
public void run() {
synchronized (mRunnable) {
mHandler.removeCallbacks(mRunnable);
updateMissNumber();
}
}
};
}
@Override
public void onChange(boolean selfChange) {
synchronized (mRunnable) {
mHandler.post(mRunnable);
}
}
public void stop() {
mHandler.removeCallbacks(mRunnable);
}
}
}