1. 首先需要将自开发的 APP 设定为 default 的 SMS APP, 因为从 4.4 之后的版本, 唯有是 default sms app 才能有权限修改 SMS message.
2. 那么要将APP 设定为 default sms app, 需要完成四个动作, 细节上很多网站都有提到, 这边就不再赘述, 列出修改后的 AndroidManifest.xml 以及新新增加的几个 Class:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.elvis.android.blackcontacts" > <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.WRITE_SMS" /> <uses-permission android:name="android.permission.RAISED_THREAD_PRIORITY" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Black.NoTitleBar" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter android:priority="1000" > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".CallReceiver" > <intent-filter android:priority="1000" > <action android:name="android.intent.action.PHONE_STATE" /> </intent-filter> </receiver> <receiver android:name=".SmsReceiver" android:permission="android.permission.BROADCAST_SMS"> <intent-filter android:priority="1" > <action android:name="android.provider.Telephony.SMS_RECEIVED" /> <action android:name="android.provider.Telephony.SMS_DELIVER" /> </intent-filter> </receiver> <receiver android:name=".MmsReceiver" android:permission="android.permission.BROADCAST_WAP_PUSH"> <intent-filter> <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" /> <data android:mimeType="application/vnd.wap.mms-message" /> </intent-filter> </receiver> <activity android:name=".ManageBlockInfoActivity" android:label="@string/title_activity_manage_block_info" > <intent-filter> <action android:name="com.elvis.android.blackcontacts.MANAGE_INFO" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <activity android:name=".ComposeSmsActivity" > <intent-filter> <action android:name="android.intent.action.SEND" /> <action android:name="android.intent.action.SENDTO" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="sms" /> <data android:scheme="smsto" /> <data android:scheme="mms" /> <data android:scheme="mmsto" /> </intent-filter> </activity> <service android:name=".SmsSendService" android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE" android:exported="true" > <intent-filter> <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="sms" /> <data android:scheme="smsto" /> <data android:scheme="mms" /> <data android:scheme="mmsto" /> </intent-filter> </service> </application> </manifest>
package com.elvis.android.blackcontacts; /** * Created by elvis on 11/3/15. */ import android.app.Activity; public class ComposeSmsActivity extends Activity { }
package com.elvis.android.blackcontacts; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; /** * Created by elvis on 11/3/15. */ public class MmsReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // TODO: Implement MMS receiver } }
package com.elvis.android.blackcontacts; /** * Created by elvis on 11/3/15. */ import android.app.IntentService; import android.content.Intent; import android.telephony.TelephonyManager; import android.os.Bundle; import android.net.Uri; import android.text.TextUtils; import android.content.ContentResolver; import android.telephony.SmsManager; import android.content.ContentValues; public class SmsSendService extends IntentService { public SmsSendService() { super(SmsSendService.class.getName()); setIntentRedelivery(true); } @Override protected void onHandleIntent(Intent intent) { String action = intent.getAction(); if (!TelephonyManager.ACTION_RESPOND_VIA_MESSAGE.equals(action)) { return; } Bundle extras = intent.getExtras(); if (extras == null) { return; } String message = extras.getString(Intent.EXTRA_TEXT); Uri intentUri = intent.getData(); String recipients = getRecipients(intentUri); if (TextUtils.isEmpty(recipients)) { return; } if (TextUtils.isEmpty(message)) { return; } String[] destinations = TextUtils.split(recipients, ";"); sendAndStoreTextMessage(getContentResolver(), destinations, message); } /** * get quick response recipients from URI */ private String getRecipients(Uri uri) { String base = uri.getSchemeSpecificPart(); int pos = base.indexOf('?'); return (pos == -1) ? base : base.substring(0, pos); } /** * Send text message to recipients and store the message to SMS Content Provider * * @param contentResolver ContentResolver * @param destinations recipients of message * @param message message */ private void sendAndStoreTextMessage(ContentResolver contentResolver, String[] destinations, String message) { SmsManager smsManager = SmsManager.getDefault(); Uri smsSentUri = Uri.parse("content://sms/sent"); for (String destination : destinations) { smsManager.sendTextMessage(destination, null, message, null, null); ContentValues values = new ContentValues(); values.put("address", destination); values.put("body", message); Uri uri = contentResolver.insert(smsSentUri, values); } } }
3. 完成以上动作后,即可以看到下面选单 -
4. 将 BlackContacts 设定为 default sms app, 将会发现所有的短信将不在显示在 Messaging 上面, 那么我们想要沿用原本的 app 来显示讯息, 就需要将不拦截的短信,
新增在原本的资料表上, 做法如下 -
void InsertMessage(Context context, String address, String body) { ContentValues values = new ContentValues(); values.put("address", address); values.put("body", body); ContentResolver cr = context.getContentResolver(); cr.insert(Uri.parse("content://sms/"), values); }
package com.elvis.android.blackcontacts; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.util.Log; import android.os.Bundle; import android.telephony.SmsMessage; import android.widget.Toast; import android.net.Uri; import android.database.Cursor; import android.content.ContentResolver; import android.content.ContentValues; /** * Created by elvis on 10/22/15. */ public class SmsReceiver extends BroadcastReceiver { private final String TAG = "SmsReceiver"; private BlackInfoDBHelper dbhelper; private SharedPreferences sp; private DevicePolicyManager devicePolicyManager; public static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED"; @Override public void onReceive(Context context, Intent intent) { if((SMS_RECEIVED.equals(intent.getAction()))) { Log.i(TAG, "Message Received!!!"); dbhelper = new BlackInfoDBHelper(context); final Bundle bundle = intent.getExtras(); try { devicePolicyManager = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); Object[] pdus = (Object[]) intent.getExtras().get("pdus"); for(Object pdu:pdus) { SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdu); String phoneNumber = currentMessage.getDisplayOriginatingAddress(); String message = currentMessage.getDisplayMessageBody(); Log.i(TAG, phoneNumber + ":" + message); if (dbhelper.isBlackNumber(phoneNumber)) { Log.i(TAG, "Block!!!"); dbhelper.insertMessage(phoneNumber, message); //deleteSMS(context, phoneNumber); //abortBroadcast(); } else { InsertMessage(context, phoneNumber, message); for (int i = 0; i < 5; i++) Toast.makeText(context, phoneNumber + ":" + message, Toast.LENGTH_LONG).show(); } } } catch (Exception e) { Log.e(TAG, "Exception smsReceiver" +e); } } } public void deleteSMS(Context ctx, String number) { Cursor c = null; Uri inbox = Uri.parse( "content://sms/" ); int count = 0; ContentResolver cr = ctx.getContentResolver(); c = cr.query(inbox, null, null, null, null); Log.i(TAG, "Count=" + c.getCount()); try { while (c.moveToNext()) { int id = c.getInt(0); cr.delete(Uri.parse("content://sms"+id), null, null); } } catch (Exception e) { Log.e("log>>>", e.toString()); Log.e("log>>>", e.getMessage()); } finally { if (c!=null) c.close(); } } void InsertMessage(Context context, String address, String body) { ContentValues values = new ContentValues(); values.put("address", address); values.put("body", body); ContentResolver cr = context.getContentResolver(); cr.insert(Uri.parse("content://sms/"), values); } }
if((SMS_RECEIVED.equals(intent.getAction()))) {
这个细节是花了一段时间去摸索.
6. 以下看看演示的结果 -
使用黑名单发短信, 则看到短信会放在黑名单短信记录中 -
而不拦截的短信, 则继续存在于 Messaging 中 ^_^