您的位置:首页 > 移动开发 > Android开发

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

2016-08-15 22:58 429 查看
首先对功能简单分析一下,既然是黑名单功能,那么肯定是写在服务里面,需要一直在后台运行着。

一、拦截短信

短信在接收的时候,广播发送,监听广播接受者,拦截短信(有序广播)

将广播的优先级级别提高到最高 (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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息