手机黑名单,拦截电话和短信,清除通话记录

首先对功能简单分析一下,既然是黑名单功能,那么肯定是写在服务里面,需要一直在后台运行着。
一、拦截短信
短信在接收的时候,广播发送,监听广播接受者,拦截短信(有序广播)
将广播的优先级级别提高到最高 (1000)
二、 拦截电话
有电话拨入,处于响铃状态,响铃状态通过代码去挂断电话(aidl,反射),拦截电话
挂断电话号码的方法,放置在了aidl文件中,方法名为endCall
在此处去查看TelePhoneManager源码,去查找获取ITelephony对象的方法
ServiceManager此类android对开发者隐藏,所以不能去直接调用其方法,所以需要反射调用
ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));

1,获取ServiceManager字节码文件
Class

代码:

package com.wutao.mobilesafe.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.telephony.PhoneStateListener;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;

import com.android.internal.telephony.ITelephony;
import com.wutao.mobilesafe.db.dao.BlackNumberDao;

import java.lang.reflect.Method;

/**
 * Created by 凸显 on 2016/8/14.
 */
public class BlackNumberService extends Service {
    private InnerSmsReceiver mInnerSmsReceiver;
    private BlackNumberDao mDB;
    private TelephonyManager mTM;
    private MyPhoneStateListener mPhoneStateListener;
    private MyContentObserver mContentObserver;

    @Override
    public void onCreate() {
        mDB = BlackNumberDao.getInstance(getApplicationContext());
        //拦截短信,注册短信监听的广播
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
        intentFilter.setPriority(1000);
        mInnerSmsReceiver = new InnerSmsReceiver();
        registerReceiver(mInnerSmsReceiver, intentFilter);

        //电话状态的监听(服务开启的时候,需要去做监听,关闭的时候电话状态就不需要监听)
        //1,电话管理者对象
        mTM = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        //监听电话状态
        mPhoneStateListener = new MyPhoneStateListener();
        mTM.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        super.onCreate();
    }

    class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
                //空闲状态,没有任何活动(移除吐司)
                case TelephonyManager.CALL_STATE_IDLE:
                    break;
                //摘机状态,至少有个电话活动。该活动或是拨打(dialing)或是通话
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    break;
                //响铃
                case TelephonyManager.CALL_STATE_RINGING:
                    //挂断电话
                    endCall(incomingNumber);
                    break;
            }
            super.onCallStateChanged(state, incomingNumber);
        }
    }

    private void endCall(String number) {
        int mode = mDB.getMode(number);
        if (mode == 2 || mode == 3) {
//      ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE))
//      ServiceManager此类android对开发者隐藏,所以不能去直接调用其方法,需要反射调用
//      首先需要导入aidl文件
            try {
                //获取ServiceManager字节码文件
                Class<?> clazz = Class.forName("android.os.ServiceManager");
                //获取方法
                Method method = clazz.getMethod("getService", String.class);
                //静态方法直接调用
                IBinder iBinder = (IBinder) method.invoke(null, Context.TELEPHONY_SERVICE);
                //调用获取aidl文件对象方法
                ITelephony iTelephony = ITelephony.Stub.asInterface(iBinder);
                //调用在aidl中隐藏的endCall方法挂断电话
                iTelephony.endCall();

                //在内容解析器上,去注册内容观察者,通过内容观察者,观察数据库(Uri决定那张表那个库)的变化
                mContentObserver = new MyContentObserver(new Handler(), number);
                getContentResolver().registerContentObserver(
                        Uri.parse("content://call_log/calls"), true, mContentObserver);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class MyContentObserver extends ContentObserver {
        private String phone;

        public MyContentObserver(Handler handler, String phone) {
            super(handler);
            this.phone = phone;
        }

        //数据库中指定calls表发生改变的时候会去调用方法
        @Override
        public void onChange(boolean selfChange) {
            //当插入一条数据后,再进行删除
            getContentResolver().delete(
                    Uri.parse("content://call_log/calls"), "number = ?", new String[]{phone});
            super.onChange(selfChange);
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private class InnerSmsReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //获取短信内容
            Object[] objects = (Object[]) intent.getExtras().get("pdus");
            for (Object object : objects) {
                //获取短信对象
                SmsMessage sms = SmsMessage.createFromPdu((byte[]) object);
                //获取短信对象的基本信息
                String address = sms.getOriginatingAddress();//拨入的电话号码
                String messageBody = sms.getMessageBody();
                int mode = mDB.getMode(address);
                if (mode == 1 || mode == 3) {
                    //拦截短信(android 4.4版本失效  短信数据库,删除)
                    abortBroadcast();
                }
            }
        }
    }

    @Override
    public void onDestroy() {
        //当服务销毁时,广播也销毁
        if (mInnerSmsReceiver != null) {
            unregisterReceiver(mInnerSmsReceiver);
        }
        //注销内容观察者
        if (mContentObserver != null) {
            getContentResolver().unregisterContentObserver(mContentObserver);
        }
        //取消电话状态的监听
        if (mPhoneStateListener != null) {
            mTM.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
        }
        super.onDestroy();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值