package com.sogou.sogouchat.os; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import com.sogou.sogouchat.bean.ContactNode; import com.sogou.sogouchat.bean.DownNode; import com.sogou.sogouchat.bean.MsgNode; import com.sogou.sogouchat.bean.TelNode; import com.sogou.sogouchat.os.DownloadManagerAsync.OnDownloadCompleteListener; import com.sogou.sogouchat.os.DownloadManagerAsync.OnDownloadConnectListener; import com.sogou.sogouchat.os.DownloadManagerAsync.OnDownloadErrorListener; import com.sogou.sogouchat.os.DownloadManagerAsync.OnDownloadUpdateListener; import android.app.NotificationManager; import android.app.Service; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.Parcelable; import android.os.RemoteException; import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds; import android.provider.ContactsContract.Contacts; import android.util.Log; import android.widget.Toast; public class MsgService extends Service { private static final String TAG = "MsgService"; /** For showing and hiding our notification. */ NotificationManager mNM; /** Keeps track of all current registered clients. */ ArrayList<Messenger> mClients = new ArrayList<Messenger>(); int mValue = 0; // LinkedList<ContactNode> mContactList = new LinkedList<ContactNode>(); LinkedList<TelNode> mTelList = new LinkedList<TelNode>(); LinkedList<MsgNode> mMsgList = new LinkedList<MsgNode>(); ArrayList<DownNode> mDownList = new ArrayList<DownNode>(); int mMaxMsgId=0; Context mContext; SMSContentObserver mSmsObserver; private int mMsgType; private Intent mIntent = new Intent(); private Bundle mBundle = new Bundle(); private DownloadManagerAsync mDownMgr = new DownloadManagerAsync(); private DownListener mDownListener = new DownListener(); private Timer mDownTimer; private TimerTask mDownTask; private Handler mObserverHandler = new Handler() { public void handleMessage(Message msg) { Log.i(TAG, "mObserverHandler handleMessage") ; switch (msg.what) { case ChatAppConstant.SRV_BackMsg_New_Sms:{ sendSrvBroadcast(ChatAppConstant.SRV_BackMsg_New_Sms); } break; default: break; } } }; public IBinder onBind(Intent intent) { Log.i(TAG, "onBind") ; return mBinder; } private final IMsgService.Stub mBinder = new IMsgService.Stub(){ @Override public List<TelNode> getTelList() throws RemoteException { // Log.i("IMsgService", "getContactList") ; return mTelList; } public List<MsgNode> getNewMsgList() throws RemoteException { // Log.i("IMsgService", "getContactList") ; return mMsgList; } public void fetchContactDb() { Log.i(TAG, "fetchContactDb"); // android.os.Debug.waitForDebugger(); if (mTelList.size() > 0) { mTelList.clear(); } doFetchContactBox(); doFetchMsgBox(); appendMsgList(); mMsgList.clear(); Log.i(TAG, "Print list ++"); // Iterator<ContactNode> it = mContactList.iterator(); // while(it.hasNext()){ // ContactNode node = it.next(); // node.logTo(); // } Log.i(TAG, "Print list --"); } public void fetchMsgBox(){ Log.i("IMsgService", "fetchMsgBox") ; doFetchMsgBox(); } public void handleSrvForeMsg(int msg, String arg1, String arg2){ Log.i("handleSrvMsg", "msg"+msg) ; mMsgType = msg; switch(msg){ case ChatAppConstant.SRV_ForeMsg_FetchDb:{ fetchContactDb(); sendSrvBroadcast(ChatAppConstant.SRV_BackMsg_FetchDb_Ok); } break; case ChatAppConstant.SRV_ForeMsg_Down_Msg:{ Log.i("handleSrvMsg", "msg file ="+arg2) ; mDownMgr.download(arg1, arg2); } break; case ChatAppConstant.SRV_ForeMsg_Read_Sms:{ // setReadSms(arg1); } break; default:{ } break; } } public void downMediaList(List<DownNode> msgList){ Iterator<DownNode> it = msgList.iterator(); while(it.hasNext()){ DownNode node = it.next(); addDownList(node); } //Start down timer if (mDownTask == null ) { mDownTask = new TimerTask(){ @Override public void run() { Log.i(TAG, "mDownTask run") ; // TODO Auto-generated method stub if (mDownList.size()>0 ){ Log.i(TAG, "mDownTask mRunning="+mDownMgr.mRunning); if (!mDownMgr.mRunning){ DownNode node = mDownList.remove(0); if (node.mShortUrl.length()>0){ Log.i(TAG, "mDownTask run start++"+node.mShortUrl) ; mDownMgr.download(node); } } } else { Log.i(TAG, "mDownTask stop TimerTask!!!!!") ; mDownTask.cancel(); mDownTask = null; } } }; mDownTimer.schedule(mDownTask, 1000, 5000); } } }; @Override public void onCreate() { Log.i(TAG, "onCreate") ; mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); // Display a notification about us starting. showNotification(); mContext = this; mSmsObserver = new SMSContentObserver(mContext, mObserverHandler, this); Uri smsUri = Uri.parse("content://sms"); getContentResolver().registerContentObserver(smsUri, true,mSmsObserver); Toast.makeText(this, "server create", Toast.LENGTH_SHORT).show(); mDownMgr.setOnDownloadCompleteListener(mDownListener); mDownMgr.setOnDownloadConnectListener(mDownListener); mDownMgr.setOnDownloadErrorListener(mDownListener); mDownMgr.setOnDownloadUpdateListener(mDownListener); checkSavePath(); mDownTimer = new Timer(); } @Override public void onDestroy() { // Cancel the persistent notification. mNM.cancel("server start", 1000); // Tell the user we stopped. Toast.makeText(this, "server stop", Toast.LENGTH_SHORT).show(); } private void showNotification() { } private void sendSrvBroadcast(int value){ Log.i(TAG, "sendSrvBroadcast") ; mBundle.putInt("CastType", value); mIntent.putExtras(mBundle); mIntent.setAction("com.sogouchat.action.CONTENT_CHANGED_ACTION"); sendBroadcast(mIntent); } private void sendSrvBroadcast(int value, String body){ Log.i(TAG, "sendSrvBroadcast") ; mBundle.putInt("CastType", value); mBundle.putString("File", body); mIntent.putExtras(mBundle); mIntent.setAction("com.sogouchat.action.CONTENT_CHANGED_ACTION"); sendBroadcast(mIntent); } private void sendSrvBroadcast(int value, Parcelable body){ Log.i(TAG, "sendSrvBroadcast") ; mBundle.putInt("CastType", value); mBundle.putParcelable("parcel", body); mIntent.putExtras(mBundle); mIntent.setAction("com.sogouchat.action.CONTENT_CHANGED_ACTION"); sendBroadcast(mIntent); } public void doFetchMsgBox() { Log.i(TAG, "doFetchMsgBox"); // 查询发件箱里的内容 Uri outSMSUri = Uri.parse("content://sms"); String[] projection= new String[] { "_id", "thread_id", "protocol", "read", "status", "type", "date", "address", "subject", "body"}; String selection = "1=1) group by "+"thread_id"+" -- ("; Cursor cur = mContext.getContentResolver().query(outSMSUri, projection, selection, null, "date asc"); if (cur != null) { // 循环遍历 cur.moveToFirst(); while (cur.moveToNext()) { addMsgNode(cur); } cur.close(); } } private void addMsgNode(Cursor cur) { MsgNode node = new MsgNode(); node.mMsgId = cur.getInt(cur.getColumnIndex("_id")); // record max msgid if (node.mMsgId > mMaxMsgId) mMaxMsgId = node.mMsgId; node.mThreadId = cur.getInt(cur.getColumnIndex("thread_id")); node.mProtocol = cur.getInt(cur.getColumnIndex("protocol")); node.mRead = cur.getInt(cur.getColumnIndex("read")); node.mStatus = cur.getInt(cur.getColumnIndex("status")); node.mType = cur.getInt(cur.getColumnIndex("type")); node.mDate = cur.getLong(cur.getColumnIndex("date")); node.mAdress = cur.getString(cur.getColumnIndex("address")); node.mSubject = cur.getString(cur.getColumnIndex("subject")); node.mBody = cur.getString(cur.getColumnIndex("body")); if (node.mAdress == null) return; mMsgList.add(node); Log.i(TAG, "addMsgNode+"+ node.mBody); } public void doFetchContactBox() { Log.i(TAG, "doFetchContactBox"); // the selected cols for contact users String[] selectCol = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.TYPE }; final int COL_ID = 0; final int COL_NAME = 1; final int COL_Num = 2; final int COL_Type = 3; String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + Contacts.DISPLAY_NAME + " != '' ))"; Cursor cursor = this.getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, selectCol, select, null, ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); if (cursor == null) { Toast.makeText(this, "cursor is null!", Toast.LENGTH_LONG).show(); return; } else if (cursor.getCount() == 0) { Toast.makeText(this, "cursor count is zero!", Toast.LENGTH_LONG) .show(); } cursor.moveToFirst(); while (!cursor.isAfterLast()) { TelNode telNode = new TelNode(); // 遍历所有的联系人下面所有的电话号码 telNode.mContactId = cursor.getInt(COL_ID); telNode.mName = cursor.getString(COL_NAME); telNode.mTel = cursor.getString(COL_Num); telNode.mType = cursor.getInt(COL_Type); // Log.i(TAG, "addTelNumNode---"+ telNode.mContactId); // Log.i(TAG, "addTelNumNode+"+ telNode.mDisName); // Log.i(TAG, "addTelNumNode+"+ telNode.mTel); // Log.i(TAG, "addTelNumNode+++"); mTelList.add(telNode); cursor.moveToNext(); } cursor.close(); } void appendMsgList(){ Log.i(TAG, "appendMsgList"); Iterator<MsgNode> msgIt = mMsgList.iterator(); while(msgIt.hasNext()){ // Log.i(TAG, "appendMsgList 1"); MsgNode msgNode = msgIt.next(); // Log.i(TAG, "appendMsgList 2"); TelNode telNode = getTelNumNode(msgNode.mAdress); // Log.i(TAG, "appendMsgList 3"); if (telNode == null){ // Log.i(TAG, "mergeMsgList NOT find"); telNode = new TelNode(); telNode.mTel = msgNode.mAdress; telNode.mName = telNode.mTel; mTelList.add(telNode); } // Log.i(TAG, "appendMsgList 4"); if (telNode.mMsgList == null){ telNode.mMsgList = new ArrayList<MsgNode>(); } // Log.i(TAG, "appendMsgList 5"); telNode.mMsgCnt++; if (msgNode.mRead == 0) telNode.mNewMsgCnt++; if (msgNode.mDate > telNode.mLastDate){ telNode.mLastDate = msgNode.mDate; telNode.mLastBody = msgNode.mBody; } // Log.i(TAG, "appendMsgList 6"); telNode.mMsgList.add(msgNode); } } TelNode getTelNumNode(String tel) { // Log.i(TAG, "getTelNumNode"+tel); if (tel == null) { return null; } Iterator<TelNode> telIt = mTelList.iterator(); while (telIt.hasNext()) { TelNode telNode = telIt.next(); if (isSameTel (telNode.mTel, tel)) { return telNode; } } // Log.i(TAG, "getTelNumNode Not"+tel); return null; } private boolean isSameTel(String tel1, String tel2){ String sub1 =null; String sub2 = null; int len1 = tel1.length(); int len2 = tel2.length(); if (len1>5){ sub1= tel1.substring(len1-5, len1); } else{ sub1= tel1; } if (len2>5){ sub2= tel2.substring(len2-5, len2); } else{ sub2= tel2; } boolean result = tel1.contains(sub2) || tel2.contains(sub1); return result; } class DownListener implements OnDownloadUpdateListener, OnDownloadConnectListener, OnDownloadCompleteListener, OnDownloadErrorListener { @Override public void onDownloadError(DownloadManagerAsync manager, Exception e) { // TODO Auto-generated method stub Log.i(TAG, "onDownloadError"+e) ; } @Override public void onDownloadComplete(DownloadManagerAsync manager, Object result, String file) { // TODO Auto-generated method stub Log.i(TAG, "onDownloadComplete"+file) ; // Log.i(TAG, "mDownTask mRunning="+mDownMgr.mRunning); sendSrvBroadcast( ChatAppConstant.SRV_BackMsg_File_Down_Ok, file); } @Override public void onDownloadConnect(DownloadManagerAsync manager) { // TODO Auto-generated method stub Log.i(TAG, "onDownloadConnect") ; // Log.i(TAG, "mDownTask mRunning="+mDownMgr.mRunning); } @Override public void onDownloadUpdate(DownloadManagerAsync manager, int percent) { // TODO Auto-generated method stub Log.i(TAG, "onDownloadUpdate"+percent) ; // Log.i(TAG, "mDownTask mRunning="+mDownMgr.mRunning); } } public static boolean hasSdcard() { String status = Environment.getExternalStorageState(); if (status.equals(Environment.MEDIA_MOUNTED)) { return true; } else { return false; } } private void checkSavePath() { if (getSDPath() == null) { Log.i(TAG, "SD is not existing."); } else { if (Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState())) { File sdcardDir = Environment.getExternalStorageDirectory(); String newPath = sdcardDir.getPath() + "/sogouchat/"; File path = new File(newPath); if (!path.exists()) { path.mkdirs(); System.out.println("paht ok,path:" + newPath); } newPath = newPath + "/media/"; path = new File(newPath); if (!path.exists()) { // 若不存在,创建目录,可以在应用启动的时候创建 path.mkdirs(); System.out.println("paht ok,path:" + newPath); } } else { System.out.println("false"); } } } public String getSDPath() { File SDdir = null; boolean sdCardExist = Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED); if (sdCardExist) { SDdir = Environment.getExternalStorageDirectory(); } if (SDdir != null) { return SDdir.toString(); } else { return null; } } public void setReadSms(String tel){ Log.i(TAG, "setRead tel ="+tel); ContentValues cv = new ContentValues(); cv.put("read", "1"); Uri smsUri = Uri.parse("content://sms/index"); mContext.getContentResolver().update(smsUri, cv, "address= ? and type = ?",new String[] {tel, "1"}); } private void addDownList(DownNode node){ Iterator<DownNode> it = mDownList.iterator(); while(it.hasNext()){ if (it.next().mDate == node.mDate){ break; } } if (!it.hasNext()){ mDownList.add(0, node); } } }