監聽發送短信(Service中註冊ContentObserver)

public class SmsObserveService extends Service {
 
    private static String TAG = "ffffff";
 
    static final String[] SMS_LOG_PROJECTION = new String[]{Sms._ID, // 0
            Sms.TYPE, // 1
            Sms.ADDRESS,
            Sms.DATE, Sms.BODY
 
    };
    static final String[] SMS_QUEUED_PROJECTION = new String[]{Sms.ADDRESS,Sms.DATE};
    /**短信的type可以有一下類型
     *  public static final int MESSAGE_TYPE_ALL    = 0;
        public static final int MESSAGE_TYPE_INBOX  = 1;
        public static final int MESSAGE_TYPE_SENT   = 2;
        public static final int MESSAGE_TYPE_DRAFT  = 3;
        public static final int MESSAGE_TYPE_OUTBOX = 4;
        public static final int MESSAGE_TYPE_FAILED = 5; // for failed outgoing messages
        public static final int MESSAGE_TYPE_QUEUED = 6; // for messages to send later
     */
    static final String whereSmsQueued = " type =" + Sms.MESSAGE_TYPE_QUEUED;
 
    //這裏使用sms中的date作爲短信的唯一標識,value值爲address,雖然沒用到。
    private HashMap<Long, String> smsQueuedMap = new HashMap<Long, String>();
     
    private ContentObserver mmSmsDbChangeObserver = new ContentObserver(new Handler()) {
        public void onChange(boolean paramBoolean) {
 
            /**
             * 短信發送成功過程中 onChange方法會調用三次,因爲該條紀錄發生了三次變化,變化的內容是Sms的Type字段
             * MESSAGE_TYPE_QUEUED  ----> MESSAGE_TYPE_OUTBOX  ---> MESSAGE_TYPE_SENT.
             * 獲取實時發送出去的短信,在onChange方法中
             * 分爲兩步:1.查詢type類型爲MESSAGE_TYPE_QUEUED的短信date(發送隊列中?),存入smsQueuedMap中;
             * 2.查詢出smsQueuedMap中date已經發送完成(MESSAGE_TYPE_SENT)的短信,現在就可以處理這些短信了。
             */
            queryQueuedSmsInSystem();
 
            saveSmsInQueuedIfSent();
 
        }
        private void saveSmsInQueuedIfSent() {
            synchronized (smsQueuedMap) {
                if (smsQueuedMap.isEmpty()) {
                    return;
                }
            }
            /**
             * whereSmsSent 拼接SQL查詢where子句,date在smsQueuedMap中,並且type是Sms.MESSAGE_TYPE_SENT
             */
            StringBuffer whereDate = new StringBuffer();
            for (Long dateKey : smsQueuedMap.keySet()) {
                whereDate.append(dateKey);
                whereDate.append(",");
            }
            whereDate.append("0");
            String whereSmsSent = "date in (" + String.valueOf(whereDate) + ") and type =" + Sms.MESSAGE_TYPE_SENT;
             
            Cursor cursor = getContentResolver().query(Sms.CONTENT_URI, SMS_LOG_PROJECTION, whereSmsSent, null,
                    "date asc ");
 
            synchronized (smsQueuedMap) {
                if (cursor != null && cursor.moveToFirst()) {
                    do {
                        Log.e(TAG, "numberSent"+cursor.getString(cursor.getColumnIndex(Sms.ADDRESS))+" dateSent"+cursor.getLong(cursor.getColumnIndex(Sms.DATE)));
                        /**
                         * 既然發送出去了,就把此條date給remove掉
                         */
                        smsQueuedMap.remove(cursor.getLong(cursor.getColumnIndex(Sms.DATE)));
                        //自定義自己對這條短信的處理..................
                        //...........
                        //...............
                    } while (cursor.moveToNext());
                }
            }
            pringMap();
            closeCursor(cursor);
        }
        private void queryQueuedSmsInSystem() {
            String numberQueried = "";
            long dateQueried = 0;
            Cursor c = getContentResolver().query(Sms.CONTENT_URI,SMS_QUEUED_PROJECTION , whereSmsQueued, null,
                    "date asc ");
            if (c != null && c.moveToFirst()) {
                do {
                    numberQueried = c.getString(c.getColumnIndex(Sms.ADDRESS));
                    dateQueried = c.getLong(c.getColumnIndex(Sms.DATE));
                    Log.e(TAG, "numberQueried"+numberQueried+" dateQueried"+dateQueried);
                    synchronized (smsQueuedMap) {
                        /**
                         * 此date加入到smsQueuedMap
                         */
                        if (!smsQueuedMap.containsKey(dateQueried)) {
                            smsQueuedMap.put(dateQueried, numberQueried);
                        }
                    }
                } while (c.moveToNext());
            }
            pringMap();
            closeCursor(c);
        }
    };
 
    private void pringMap() {
        for (Entry<Long, String> entry : smsQueuedMap.entrySet()) {
           Log.e(TAG, ""+entry.getKey()+"  "+entry.getValue()+"\n");
       }
    }
     
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return Service.START_STICKY;
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        getContentResolver().registerContentObserver(Sms.CONTENT_URI, true, mmSmsDbChangeObserver);
    }
    @Override
    public void onDestroy() {
        getContentResolver().unregisterContentObserver(mmSmsDbChangeObserver);
        super.onDestroy();
    }
    private static void closeCursor(Cursor c) {
        if (c != null && !c.isClosed()) {
            c.close();
            c = null;
        }
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章