Android APP - BlackContact 最后实现


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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值