黑名单电话拦截
一、黑名单电话拦截步骤:
CallSmsSafeService 1、注册一个电话状态的服务 TelephonyManager 2、当有电话打进来的时候,判断是否在黑名单中 3、在设置中心看是否设置了开启黑名单拦截功能 4、如果开启了,且在黑名单中,那么立刻挂断该电话 |
挂断电话监听服务:CallSmsSafeService.java package cn.zengfansheng.mobilesafe.service;
import java.lang.reflect.Method;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import cn.zengfansheng.mobilesafe.db.dao.BlackNumberDao;
import com.android.internal.telephony.ITelephony;
/**
* 3、黑名单电话短信监听服务
* @author hacket
*/
public class CallSmsSafeService extends Service {
private TelephonyManager tm;// 电话管理者
private PhoneStateListener listener;// 电话状态监听器
private BlackNumberDao blackNumberDao;// 黑名单dao
@Override
public IBinder onBind(Intent intent) {
return null;
}
// 1、服务开启时
@Override
public void onCreate() {
super.onCreate();
blackNumberDao = new BlackNumberDao(getApplicationContext());
// 初始化电话管理者
tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
listener = new MyPhoneStateListener();
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}
// 2、服务停止时
@Override
public void onDestroy() {
super.onDestroy();
tm.listen(listener, PhoneStateListener.LISTEN_NONE);
listener = null;
}
private class MyPhoneStateListener extends PhoneStateListener {
private static final String TAG = "MyPhoneStateListener";
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:// 电话响铃的时候,查找数据库来电号码是否在黑名单数据库中
String blacknumberMode = blackNumberDao.getBlackNumberMode(incomingNumber);
// 检查当前的号码是否需要拦截,如果需要,挂断电话
if (!TextUtils.isEmpty(blacknumberMode)) {
if ("1".equals(blacknumberMode) || "3".equals(blacknumberMode)) {// 拦截模式为"1",即电话拦截;或者"3",全部拦截
Log.i(TAG, "拦截黑名单:" + incomingNumber);
endCall();// 挂断电话
return;
}
}
break;
}
}
/**
* 3、挂断电话
*/
private void endCall() {
// IBinder b = ServiceManager.getService(LOCATION_SERVICE);
//利用反射来找到,因为系统给隐藏了
try {
Class<?> clazz = getClassLoader().loadClass("android.os.ServiceManager");
Method method = clazz.getDeclaredMethod("getService", String.class);
IBinder b = (IBinder) method.invoke(null, TELEPHONY_SERVICE);
// IBinder 转成接口类型
ITelephony asInterface = ITelephony.Stub.asInterface(b);
asInterface.endCall();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
|
挂断电话核心代码: /**
* 3、挂断电话
*/
private void endCall() {
// IBinder b = ServiceManager.getService(LOCATION_SERVICE);
//利用反射来找到,因为系统给隐藏了
try {
Class<?> clazz = getClassLoader().loadClass("android.os.ServiceManager");
Method method = clazz.getDeclaredMethod("getService", String.class);
IBinder b = (IBinder) method.invoke(null, TELEPHONY_SERVICE);
// IBinder 转成接口类型
ITelephony asInterface = ITelephony.Stub.asInterface(b);
asInterface.endCall();
} catch (Exception e) {
e.printStackTrace();
}
}
|
Android平台源码和系统源码区别 Android API16平台源码: \sdk\sources\android-16\android\ Android所有源码:上面的源码只是Android所有源码中的一小部分 \aosp_jb422\frameworks\base\core\java\android\ |
如何查看一些抽象类的实现(系统源码):比如Context,PackageManager public abstract class PackageManager{} public abstract class Context{} 问题:可以看到这些都是一些抽象类,没有具体的实现 解决:在syso处断点,然后通过断点调试的方式,找到默认实现类 public void click(View view){
PackageManager pm = getPackageManager();
Context context = getApplicationContext();
System.out.println("------");
} 可以看出Context默认的实现类为ContextImpl PageageManager的默认实现类为IPackageManager |
TelephonyManager中的endCall()在后面的版本给屏蔽掉了 所以需要利用反射给找到 1、查看系统源码 IBinder b = ServiceManager.getService(LOCATION_SERVICE); 2、利用反射 Class<?> clazz = getClassLoader().loadClass("android.os.ServiceManager");
Method method = clazz.getDeclaredMethod("getService", String.class);
IBinder b = (IBinder) method.invoke(null, TELEPHONY_SERVICE); 3、IBinder转成接口类型,aidl a)搜ITelephony.aidl \frameworks\base\telephony\java\com\android\internal\telephony\ITelephony.aidl b)找到ITelephony.aidl的包名 com.android.internal.telephony; {@hide}表示隐藏的 c)然后在工程中创建相同的包名,将该ITelephony.aidl给拷贝进去 d)这两个地方报错,说明缺少这个两个文件,继续找 \frameworks\base\telephony\java\android\telephony\NeighboringCellInfo.aidl \frameworks\base\telephony\java\android\telephony\CellInfo.aidl e)然后创建包名,将aidl文件复制进来 |
问题1:权限 <uses-permission android:name="android.permission.CALL_PHONE" /> |
问题2:通话记录还有通话记录电话拨号的记录 |