需要添加 android.permission.CALL_PHONE 电话权限
android.permission.WRITE_CONTACTS 修改联系人权限
android.permission.WRITE_CALL_LOG 修改通话记录权限
存入NeighboringCellInfo.aidl文件
存入ITelephony.aidl文件
<span style="color:#3398cc;">protected void endCall() { </span><span style="color:#33cc00;">//查看源码得来的思路 //ITelephony.stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); //调用ITelephony对象的endCall方法,就可以挂断电话 //我们确定手机中确实有类:android.os.ServiceManager 但不能直接调用,只能通过反射的方式调用</span><span style="color:#3398cc;"> try { </span><span style="color:#33cc00;">//1 获得字节码</span><span style="color:#3398cc;"> Class clazz = Class.forName("android.os.ServiceManager"); </span><span style="color:#33cc00;">//2 获得方法</span><span style="color:#3398cc;"> </span><span style="color:#3333ff;"> * 参数一:方法的名称 * 参数二及后面的参数:getService方法的参数的字节码类型(该参数为可变参数,所以参数二后边有时还会追加其他参数)</span><span style="color:#3398cc;"> Method method = clazz.getMethod("getService", String.class); </span><span style="color:#33cc00;">//3 调用方法</span><span style="color:#3398cc;"> </span><span style="color:#000099;"> * 参数一:调用该方法的对象 若该方法时静态方法,就写null * 参数二:getService方法调用时的真实的参数</span><span style="color:#3398cc;"> Object obj = method.invoke(null, Context.TELEPHONY_SERVICE); ITelephony itelephony = ITelephony.Stub.asInterface((IBinder) obj); itelephony.endCall();</span><span style="color:#33cc00;">//挂断电话</span><span style="color:#3398cc;"> } catch (Exception e) { e.printStackTrace(); } } private PhoneStateListener listener = new PhoneStateListener(){ </span><span style="color:#000099;">* 当打电话状态发生改变时,调用此方法 * @param state 电话当前的状态 * @param incomingNumber 打进来的电话号码</span><span style="color:#3398cc;"> public void onCallStateChanged(int state, final String incomingNumber) { incomingNumber = incomingNumber; switch(state){ case TelephonyManager.CALL_STATE_IDLE:</span><span style="color:#33cc00;">//空闲状态</span><span style="color:#3398cc;"> break; case TelephonyManager.CALL_STATE_RINGING:</span><span style="color:#33cc00;">//响铃</span><span style="color:#3398cc;"> </span><span style="color:#33cc00;">//判断来电者是否是黑名单 incomingNumber来电号码</span><span style="color:#3398cc;"> int mode = blackDao.getModeByNumber(incomingNumber); if(mode == 0 || mode == 1){ </span><span style="color:#33cc00;">//中段电话</span><span style="color:#3398cc;"> endCall();</span><span style="color:#33cc00;">//异步的操作</span><span style="color:#3398cc;"> </span><span style="color:#33cc00;">//使用内容观察者清除通话数记录,观察通话日志数据库,如果发生改变,就清除黑名单记录 //可以在用户手机比较卡顿的情况下 确保不会 产生黑名单号码来电通话记录</span><span style="color:#3398cc;"> Uri uri = Uri.parse("Content://call_log/calls");</span><span style="color:#33cc00;">//uri就指向通话日志的数据库中的 表</span><span style="color:#3398cc;"> </span><span style="color:#33cc00;">//注册一个内容观察者 若内容发生变化,就执行observer的onChange方法</span><span style="color:#3398cc;"> getContentResolver().registerContentObserver(uri, true, observer); </span><span style="color:#000099;">*ContentResolver()就是一个底层服务 *registerContentObserver()向getContentResolver()发送一个请求 观察uri 若状态改变 变true 就执行 observer *数据库放生改变时就向getContentResolver()发出通知 uri发生变化 getContentResolver()就会调用observer中的onChange()方法</span><span style="color:#3398cc;"> }; }.start(); } break; case TelephonyManager.CALL_STATE_OFFHOOK:</span><span style="color:#009900;">//接听</span><span style="color:#3398cc;"> break; } }; }; protected String incomingNumber; </span><span style="color:#000099;">* 通话记录数据库的内容 发生改变时的 内容观察者</span><span style="color:#3398cc;"> protected ContentObserver observer = new ContentObserver(new Handler()){ </span><span style="color:#3333ff;">* 通话日志的数据发生改变时,调用此方法</span><span style="color:#3398cc;"> public void onChange(boolean selfChange) { </span><span style="color:#33cc00;">//清除黑名单通话记录</span><span style="color:#3398cc;"> Uri uri = Uri.parse("Content://call_log/calls"); getContentResolver().delete(uri, "number = ?", new String[]{incomingNumber}); }; }; </span>