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>
ComposeSmsActivity.java
package com.elvis.android.blackcontacts;
/**
* Created by elvis on 11/3/15.
*/
import android.app.Activity;
public class ComposeSmsActivity extends Activity {
}
MmsReceiver.java
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
}
}
SmsSendService.java
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 中 ^_^