监听发送短信(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;
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值