Android初级教程反射+AIDL+内容观察者监控黑名单号码代码模板
对于想要拦截一些莫名的陌生号码,就需要电话拦截功能与删除其电话记录功能。拦截的主要业务逻辑,分别是在一个服务里面进行:1、注册电话监听;2、取消注册电话监听(当然注册于取消是在服务里面建立一个广播接收者)。删除电话日志的功能,是靠内容观察者和内容提供者。
下面给出实现电话监听,取消注册监听,内容观察者监听电话数据库状态的主要代码。对于以后开发此类产品,不需要去查看系统源码,复制粘贴这段代码就行了。下面给出代码:
一、注册电话监听与内容观察者监控电话数据库状态:
因为是在服务里面,因此,注册写在onCreate方法里面
<span style="font-size:12px;">@Override public void onCreate() { // 注册电话监听 // 通过电话管理类TelephoneManager tm = (TelephoneManager</span><span style="font-size:12px;">) getSystemService(TELEPHONY_SERVICE); // 监听电话的状态 listener = new PhoneStateListener() { /* * (non-Javadoc) 该方法用来监听电话的状态 * * @see android.telephony.PhoneStateListener#onCallStateChanged(int, * java.lang.String) */ @Override public void onCallStateChanged(int state, final String incomingNumber) { // TODO Auto-generated method stub // state 电话的状态 incomingNumber 打进来的号码 switch (state) { case TelephonyManager.CALL_STATE_IDLE:// 挂断的状态,空闲的状态 System.out.println("CALL_STATE_IDLE"); break; case TelephonyManager.CALL_STATE_RINGING://响铃状态 System.out.println("CALL_STATE_RINGING"); //判断是否是黑名单号码 //获取电话的模式 int mode = dao.getMode(incomingNumber); //如果是拦截号码 if ((mode & BlackTable.TEL) != 0) { //电话拦截 System.out.println("挂断电话"); //挂断电话之前先注册内容观察者,新生成的日志之后(数据库发生改变) getContentResolver().registerContentObserver(Uri.parse("content://call_log/calls"), true, new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { //电话日志变化 触发此方法调用 deleteCalllog(incomingNumber);//删除电话日志 super.onChange(selfChange); } }); endCall(); } break; case TelephonyManager.CALL_STATE_OFFHOOK:// 通话的状态 System.out.println("CALL_STATE_OFFHOOK"); break; default: break; } super.onCallStateChanged(state, incomingNumber); } }; // 注册电话的监听 tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE); super.onCreate(); } /** * 删除电话日志 * @param incomingNumber * 要删除日志的号码 */ protected void deleteCalllog(String incomingNumber) { //只能内容提供者来删除电话日志 Uri uri = Uri.parse("content://call_log/calls"); //删除指定号码(黑名单号码)日志 getContentResolver().delete(uri, "number=?", new String[]{incomingNumber}); } /** * 挂断电话:反射+AIDL */ protected void endCall() { //tm.endCall(); 1.5版本后,把该方法阉割掉了 //想用该功能,实现方法 //ServiceManager.getService(); //反射调用 //1.class try { Class clazz = Class.forName("android.os.ServiceManager"); //2. method Method method = clazz.getDeclaredMethod("getService", String.class); //3.obj 不需要 因为是静态方法 //4. 调用 IBinder binder = (IBinder) method.invoke(null, Context.TELEPHONY_SERVICE); //5.aidl ITelephony iTelephony = ITelephony.Stub.asInterface(binder); iTelephony.endCall();//挂断电话 } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } }</span>
因为用到AIDL因此,要把在相应应用中加入两个文件:截图:
若用到了相应的功能,直接复制核心代码就行了