MTK方案上基于Android N拦截黑名单中的短/彩信的方法

--- 作者 zuhui.zhang


安卓7.0原生系统增加了在framework层拦截黑名单来电和短信,但不会将数据保存到数据库,因此无法查看到被拦截的来电和短信。在安卓7.0之前,黑名单的短信默认是不会拦截的,为了实现黑名单短信拦截功能,需要对短信数据库表中的字段新增特殊的值,以便标记黑名单短信。以下具体说明下笔者对于MTK方案里的短信应用中拦截短彩信的实现方法。

一、拦截黑名单短信

涉及到的类:

com.android.mms.transaction.SmsReceiverService:短信接收服务类,

MyBlacklistManager:新创建的类,用于判断号码是否在黑名单、添加号码到黑名单、移除号码。

a)   实现思想:

在SmsReceiverService. handleSmsReceived()中,判断新来短信的号码是否是在黑名单中,如果是,则将Sms.READ设为1,同时将Sms.TYPE设为MyBlacklistManager. MESSAGE_TYPE_INTERCEPTED=7,然后保存到短信收件箱。要查看拦截短信时,只要查询数据库过滤出Sms.TYPE=7的短信,则为被拦截的黑名单短信。

b)   具体实现方法:

插入拦截字段:在SmsReceiverService .handleSmsReceived()中,在insertMessage()->storeMessage()函数中判断是否是黑名单,若是,则在sms表的type字段插入拦截类型的值(MESSAGE_TYPE_INTERCEPTED),read字段设为1:防止在launcher上显示未读短信数量,并MyBlacklistManager类使用一个布尔型变量记录已经成功拦截短信。

只通知被拦截的短信:在handleSmsReceived中,在insertMessage()调用之后,通过调用MyBlacklistManager中的autoReject()判断号码是否在黑名单列表中,如果是则只发出通知(隐藏部分信息),但是不会亮屏、发出通知音和振动。

其中autoReject()方法和方法中用到的变量如下:

// blacklist table uri

// private static final Uri BLACK_LIST_URI =Uri.parse("content://reject/list");// for android 4.4 to 5.x

private static final Uri BLACK_LIST_URI = Uri.parse("content://com.cmcc.ccs.black_list");// for android 6.0

// table field name

private static final String REJECT_FIELD_NUMBER="PHONE_NUMBER";

/**

* check if the number should be rejected

* @param number the sms/mms recipient

* @param type reject type, inBlackListManager class had define

* @return the result that the currentnumber should be auto reject, true:in blacklist, or not in.

*/

public static boolean autoReject(Context context, String number, int type) {

   System.out.println("autoReject number:" + number);

    if(context == null)

       return false;

    try{

       ContentResolver cr = context.getContentResolver();

       Cursor cursor = cr.query(BLACK_LIST_URI, null,REJECT_FIELD_NUMBER+"=?", new String[]{number}, null);

       if (cursor != null) {

           if(cursor.getCount() > 0) {

                cursor.close();

                return true;

           } else {

                cursor.close();

                return false;

           }

       }

    } catch(Exception e) {

       Log.e(TAG, "--autoRejecterror = " + e.getMessage() + ", e object=" + e);

       return false;

    }

}

c)   Sms.TYPE各值的含义如下:

因为要查看黑名单短信,所以需要修改数据库sms表的type字段,type=1:表示是收到的短信,type=2:表示是发送出去的短信,type=7:表示收到的被拦截的短信(在会话、短信查看、黑名单查看界面需要用到这个字段)。

短信type字段所有值都包含在Sms类定义中,和数据库表sms中的type值对应,具体如下:

Sms.MESSAGE_TYPE_ALL=0,表示所有类型的短信;

Sms.MESSAGE_TYPE_INBOX=1表示是接收的短信;

Sms.MESSAGE_TYPE_SENT=2表示发送的短信;

Sms.MESSAGE_TYPE_DRAFT=3表示该短信是草稿;

Sms.MESSAGE_TYPE_OUTBOX=4表示在发件箱中的短信;

Sms.MESSAGE_TYPE_FAILED=5表示发送失败的短信;Sms.MESSAGE_TYPE_QUEUED=6表示在队列中的短信。

MyBlacklistManager. MESSAGE_TYPE_INTERCEPTED=7表示被拦截的短信,新增的值。

二、拦截黑名单彩信

修改com.android.mms.transaction.MmsPushReceiveService和用于拦截彩信。彩信通知在transaction/NotificationTransaction,而且要修改util/DownloadManager,transaction/Observable,transaction/Observer、transaction/RetryScheduler、transaction/TransactionService几个类。

彩信接收流程MTK实现如下,主要涉及的包:com.android.mms.transaction。

a)  PushReceiver类,从底层接收彩信:收到彩信时,PushReceiver执行doInBackground(),接收intent,同时解析key为“data”的字节数据;使用PduParser解析数据,得到GenericPdu的数据(pdu),然后得到短信类型,类型为MESSAGE_TYPE_NOTIFICATION_IND时,使用PduPersister中的persist()将彩信数据写到数据库中(主要涉及pdu和part表),同时启动TransactionService(putExtra:TransactionBundle.TRANSACTION_TYPE=Transaction.NOTIFICATION_TRANSACTION),实现下载彩信功能。

b)  TransactionService类,和PushReceiver和NotificationTransaction沟通作用:执行onStartCommand()函数,发送消息到ServiceHandler类处理;调用handleMessage(),执行case EVENT_TRANSACTION_REQUEST--caseTransaction.NOTIFICATION_TRANSACTION,实例化NotificationTransaction类àprocessTransaction()àNotificationTransaction.process()/RetrieveTransaction.process(),前者是接收到彩信时执行下载动作(若打开自动下载彩信开关),后者是当彩信在接收时未下载时,用户点击下载后执行下载动作;

c)  NotificationTransaction类,下载彩信多媒体文件:process()àrun()àSmsManager. downloadMultimediaMessage()下载彩信到手机,同时启动TransactionService 使用action:TransactionService.ACTION_TRANSACION_PROCESSED,此时执行TransactionService. onStartCommand()àServiceHandler.handleMessage(),case EVENT_TRANSACTION_PROCESSEDàhandleTransactionProcessed()àNotificationTransaction. notifyObservers()àTransactionService.update(),case TransactionState.SUCCESSàcase Transaction.NOTIFICATION_TRANSACTIONàMessagingNotification.blockingUpdateNewSmsMessageIndicator()发出通知,彩信接收过程结束。

彩信拦截思想及流程

1、 在PushReceiver.doInBackground()中,更新pdu表:Mms.READ字段设成1,防止黑名单联系人来的彩信在launcher界面短信图标上显示未读数量。

2、 在NotifficationTransaction.run()中,若彩信关闭自动下载彩信开关,则直接调用自定义的updateBlacklistField()更新pdu表中Mms.READ=1,Mms.MESSAGE_BOX= MyBlacklistManager.MESSAGE_BOX_INTERCEPTED(值等于6)表示此彩信属于黑名单彩信;接收彩信时,若彩信自动下载开关打开,则在彩信下载完成后,进入TransactionService.handleTransactionProcessed()中调用更新pdu表的操作(若没有打开自动下载彩信,则会在用户点击下载按钮后,执行更新pdu表操作),修改字段值,函数和updateBlacklistField()类似。

updateBlacklistField()函数实现如下:

private boolean mIsBlcakNumber= true;

/**

 * for set msg_box as blacklist

 */

private voidupdateBlacklistField() {

    // for reset mms msg_box field as blacklist

    // (close auto download mms) when user click downloadbutton@{

    if (mIsBlcakNumber) {

        try {

            ContentValues values = new ContentValues();

            // mark as read prevent provider to notifylauncher unread

            // count. but black message is distinguishis read or unread

            values.put(Mms.READ, "1");

            values.put(Mms.MESSAGE_BOX, MyBlacklistManager.MESSAGE_BOX_INTERCEPTED);

            mContext.getContentResolver().update(mUri, values, null, null);

        } catch (Exception e) {

            Log.e(TAG, "--change intercepted blacklist mms error1=" + e.getMessage()

                    + ", e object" + e);

        }

    }

    // @}

}

3、 pdu表的msg_box字段各值的含义如下:

           Mms.MESSAGE_BOX_ALL=0

Mms.MESSAGE_BOX_INBOX=1

Mms.MESSAGE_BOX_SENT=2

Mms.MESSAGE_BOX_DRAFTS=3

Mms.MESSAGE_BOX_OUTBOX=4

MyBlacklistManager.MESSAGE_BOX_INTERCEPTED=6,新增的值。

 

以上方法希望能给遇到相同需求的开发者一些启发。 


引用查询资料出处

http://zhanglfat.iteye.com/blog/1453353

http://blog.csdn.net/hitlion2008/article/details/7166075

http://www.android100.org/html/201502/25/123115.html

http://blog.csdn.net/tjy1985/article/details/7228282

你可能感兴趣的:(MTK方案上基于Android N拦截黑名单中的短/彩信的方法)