Android APP - BlackContact 最后实现

来源:互联网 发布:自动充值软件 编辑:程序博客网 时间:2024/04/28 08:29


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);    }}


5. 这边特别注意到如果不加入判断语句, 则同一个短信 onReceive() 会触发两次, 填入两个相同的资料

if((SMS_RECEIVED.equals(intent.getAction()))) {

这个细节是花了一段时间去摸索.


6. 以下看看演示的结果 -

使用黑名单发短信, 则看到短信会放在黑名单短信记录中 -



而不拦截的短信, 则继续存在于 Messaging 中 ^_^


0 0