当黑名单号码打进来时,自动挂断,并且在通话历史记录中删除该条记录。

挂断电话的操作可以通过PackageManager对象来实现,但是在android1.5以后,该方法没有暴露出来,需要通过AIDL来实现。

一个是ITelephony.aidl,从网上搜索下载:

/** Copyright (C) 2007 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.android.internal.telephony;import android.os.Bundle;
import java.util.List;
import android.telephony.NeighboringCellInfo;/*** Interface used to interact with the phone.  Mostly this is used by the * TelephonyManager class.  A few places are still using this directly.* Please clean them up if possible and use TelephonyManager insteadl.** {@hide}*/
interface ITelephony {/*** Dial a number. This doesn't place the call. It displays* the Dialer screen.* @param number the number to be dialed. If null, this* would display the Dialer screen with no number pre-filled.*/void dial(String number);/*** Place a call to the specified number.* @param number the number to be called.*/void call(String number);/*** If there is currently a call in progress, show the call screen.* The DTMF dialpad may or may not be visible initially, depending on* whether it was up when the user last exited the InCallScreen.** @return true if the call screen was shown.*/boolean showCallScreen();/*** Variation of showCallScreen() that also specifies whether the* DTMF dialpad should be initially visible when the InCallScreen* comes up.** @param showDialpad if true, make the dialpad visible initially,*                    otherwise hide the dialpad initially.* @return true if the call screen was shown.** @see showCallScreen*/boolean showCallScreenWithDialpad(boolean showDialpad);/*** End call or go to the Home screen** @return whether it hung up*/boolean endCall();/*** Answer the currently-ringing call.** If there's already a current active call, that call will be* automatically put on hold.  If both lines are currently in use, the* current active call will be ended.** TODO: provide a flag to let the caller specify what policy to use* if both lines are in use.  (The current behavior is hardwired to* "answer incoming, end ongoing", which is how the CALL button* is specced to behave.)** TODO: this should be a oneway call (especially since it's called* directly from the key queue thread).*/void answerRingingCall();/*** Silence the ringer if an incoming call is currently ringing.* (If vibrating, stop the vibrator also.)** It's safe to call this if the ringer has already been silenced, or* even if there's no incoming call.  (If so, this method will do nothing.)** TODO: this should be a oneway call too (see above).*       (Actually *all* the methods here that return void can*       probably be oneway.)*/void silenceRinger();/*** Check if we are in either an active or holding call* @return true if the phone state is OFFHOOK.*/boolean isOffhook();/*** Check if an incoming phone call is ringing or call waiting.* @return true if the phone state is RINGING.*/boolean isRinging();/*** Check if the phone is idle.* @return true if the phone state is IDLE.*/boolean isIdle();/*** Check to see if the radio is on or not.* @return returns true if the radio is on.*/boolean isRadioOn();/*** Check if the SIM pin lock is enabled.* @return true if the SIM pin lock is enabled.*/boolean isSimPinEnabled();/*** Cancels the missed calls notification.*/void cancelMissedCallsNotification(); /*** Supply a pin to unlock the SIM.  Blocks until a result is determined.* @param pin The pin to check.* @return whether the operation was a success.*/boolean supplyPin(String pin);/*** Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated* without SEND (so <code>dial</code> is not appropriate).* * @param dialString the MMI command to be executed.* @return true if MMI command is executed.*/boolean handlePinMmi(String dialString);/*** Toggles the radio on or off.*/void toggleRadioOnOff();/*** Set the radio to on or off*/boolean setRadio(boolean turnOn);/*** Request to update location information in service state*/void updateServiceLocation();/*** Enable location update notifications.*/void enableLocationUpdates();/*** Disable location update notifications.*/void disableLocationUpdates();/*** Enable a specific APN type.*/int enableApnType(String type);/*** Disable a specific APN type.*/int disableApnType(String type);/*** Allow mobile data connections.*/boolean enableDataConnectivity();/*** Disallow mobile data connections.*/boolean disableDataConnectivity();/*** Report whether data connectivity is possible.*/boolean isDataConnectivityPossible();Bundle getCellLocation();/*** Returns the neighboring cell information of the device.*/List<NeighboringCellInfo> getNeighboringCellInfo();int getCallState();int getDataActivity();int getDataState();
}

此文件使用了NeighboringCellInfo.aidl:

package android.telephony;
parcelable NeighboringCellInfo;

将这两个文件按照包名目录放好。

创建服务CallFirewallService:

package com.example.mobilesafe.service;import java.lang.reflect.Method;import android.app.Service;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.provider.CallLog;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;import com.android.internal.telephony.ITelephony;
import com.example.mobilesafe.db.BlackNumberDao;public class CallFirewallService extends Service {public static final String TAG = "CallFirewallService";public static final int STOP_SMS = 1;public static final int STOP_CALL = 2;public static final int STOP_SMSCALL = 4;private TelephonyManager tm;private MyPhoneListener listener;private BlackNumberDao dao;@Overridepublic IBinder onBind(Intent intent) {return null;}/*** 当服务第一次被创建的时候 调用*/@Overridepublic void onCreate() {super.onCreate();dao = new BlackNumberDao(this);// 注册系统的电话状态改变的监听器.listener = new MyPhoneListener();tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);// 系统的电话服务 就监听了 电话状态的变化,tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);}private class MyPhoneListener extends PhoneStateListener {@Overridepublic void onCallStateChanged(int state, String incomingNumber) {switch (state) {case TelephonyManager.CALL_STATE_RINGING:// 手机铃声正在响.//starttime = System.currentTimeMillis();// 判断 incomingNumber 是否是黑名单号码int mode = dao.findNumberMode(incomingNumber);if ((mode & STOP_CALL) != 0) {// 黑名单号码Log.i(TAG, "挂断电话");//挂断电话endcall(incomingNumber);}break;case TelephonyManager.CALL_STATE_IDLE: // 手机的空闲状态break;case TelephonyManager.CALL_STATE_OFFHOOK:// 手机接通通话的状态break;}super.onCallStateChanged(state, incomingNumber);}}/*** 取消电话状态的监听.*/@Overridepublic void onDestroy() {super.onDestroy();tm.listen(listener, PhoneStateListener.LISTEN_NONE);listener = null;}/*** 显示添加黑名单号码的notification* @param incomingNumber*//*public void showNotification(String incomingNumber) {//1.创建一个notification的管理者String ns = Context.NOTIFICATION_SERVICE;NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);//2.创建一个notification int icon = R.drawable.notification;CharSequence tickerText = "拦截到一个一声响号码";long when = System.currentTimeMillis();Notification notification = new Notification(icon, tickerText, when);//3.定义notification的具体内容 和点击事件Context context = getApplicationContext();CharSequence contentTitle = "发现响一声号码";CharSequence contentText = "号码为:"+incomingNumber;notification.flags = Notification.FLAG_AUTO_CANCEL;Intent notificationIntent = new Intent(this, CallSmsSafeActivity.class);notificationIntent.putExtra("blacknumber", incomingNumber);notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT );notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);//4.利用notification的manager 显示一个notificationmNotificationManager.notify(0, notification);}*//*** 挂断电话* 需要拷贝两个aidl文件* 添加权限<uses-permission android:name="android.permission.CALL_PHONE" />** @param incomingNumber*/public void endcall(String incomingNumber) {try {//使用反射获取系统的service方法Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);IBinder binder = (IBinder) method.invoke(null, new Object[]{TELEPHONY_SERVICE});//通过aidl实现方法的调用ITelephony telephony = ITelephony.Stub.asInterface(binder);telephony.endCall();//该方法是一个异步方法,他会新开启一个线程将呼入的号码存入数据库中//deleteCallLog(incomingNumber);// 注册一个内容观察者 观察uri数据的变化getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true, new MyObserver(new Handler(), incomingNumber));} catch (Exception e) {e.printStackTrace();}}/*** 定义自己的内容观察者 ,* 在构造方法里面传递 观察的号码** @author*/private class MyObserver extends ContentObserver {private String incomingNumber;public MyObserver(Handler handler, String incomingNumber) {super(handler);this.incomingNumber = incomingNumber;}/*** 数据库内容发生改变的时候调用的方法*/@Overridepublic void onChange(boolean selfChange) {super.onChange(selfChange);//立即执行删除操作deleteCallLog(incomingNumber);//停止数据的观察getContentResolver().unregisterContentObserver(this);}}/*** 删除呼叫记录** @param incomingNumber*/private void deleteCallLog(String incomingNumber) {// 呼叫记录内容提供者对应的uriUri uri = Uri.parse("content://call_log/calls");// CallLog.Calls.CONTENT_URI;Cursor cursor = getContentResolver().query(uri, new String[]{"_id"}, "number=?", new String[]{incomingNumber}, null);while (cursor.moveToNext()) {String id = cursor.getString(0);getContentResolver().delete(uri, "_id=?", new String[]{id});}cursor.close();}
}

其中showNotification是显示拦截的黑名单通知。

endcall注册了一个内容观察者,当拦截成功后,由于历史记录中会有此次拨打记录。

这样内容观察者就可以接收到数据的变化,进而将此次号码的通话记录删除掉。

清单文件需要添加权限:

    <uses-permission android:name="android.permission.WRITE_CONTACTS" /><uses-permission android:name="android.permission.CALL_PHONE" />

31、通信卫士--拦截黑名单电话相关推荐

  1. 黑马手机卫士黑名单电话拦截 使用ITelephony.aidl和NeighboringCellInfo.aidl 自动拦截黑名单电话 附文件

    Android Studio使用ITelephony.aidl 和 NeighboringCellInfo.aidl拦截电话,以及解决 java.lang.NoSuchMethodError: No ...

  2. 30、通信卫士--拦截黑名单短信

    在SmsReceiver代码里添加对接受的短信发信人的黑名单检查即可: //检查是否是黑名单号码int mode = dao.findNumberMode(sender);if ((mode & ...

  3. Android开发实战《手机安全卫士》——8.“通信卫士”模块实现 JUnit测试 ListView优化

    文章目录 1.高级工具--去电归属地显示 2.通信卫士--黑名单布局编写 3.通信卫士--黑名单数据库 4.通信卫士--黑名单CRUD功能实现 5.通信卫士--JUnit测试 6.通信卫士--黑名单号 ...

  4. android 来电拒接_安卓手机怎么设置拦截陌生电话

    智能手机对于很多人来说诸多的功能都是摆设,而关于手机的黑名单或者是拦截设置我们就必须的了解,否则就不知道如何的防护陌生的骚扰电话.那么安卓手机怎么设置拦截陌生电话呢?佰佰安全网小编来教大家怎么操作吧. ...

  5. android拦截电话并且不留下通话记录,具透丨iOS 10 支持拦截骚扰电话了,这些事情你应该知道...

    关于栏目 苹果.谷歌每年一次大更新的新系统都值得关注,我们始终不建议普通用户提前尝鲜稳定性不佳的测试版,但我们理解想要尝鲜的心情,于是有了「具透」这个栏目.「具透」会挖掘.详解新系统的各个功能细节,并 ...

  6. 广播接收者android,电话拦截广播,电话接收者demo

    一.Android广播机制介绍 广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的. Android中广播的是操作系统中产生的各种各样的事件.例如,收到一条短信就会 ...

  7. Android拦截黑名单(简易版)

    拦截黑名单的话,一般都是去系统数据库里面取值,判断来电手机号码或者短信号码是否在我黑名单数据中是否存在.如果存在就拦截.而我这里就投机取巧了,没有去数据库.只是简单的拦截,将数据写死了! 来上代码: ...

  8. 【Matlab通信】DTMF双音多频电话拨号仿真【含GUI源码 805期】

    一.代码运行视频(哔哩哔哩) [Matlab通信]DTMF双音多频电话拨号仿真[含GUI源码 805期] 二.matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 [1] 蔡利梅 ...

  9. 苹果手机怎么查看足迹_苹果手机怎么查看被拦截的电话-苹果手机查看被拦截电话的方法...

    苹果手机是现在很多用户都会选择使用的一款手机,其中有很多功能都是非常实用的,比如在电话功能中的号码拦截功能,可以帮助用户拦截一些陌生号码或者是被标记过的骚扰电话,这样在用户使用手机的过程中就可以减少被 ...

最新文章

  1. Oracl 12c (课本)
  2. 中文版!Python入门学习的三件法宝!附免费下载
  3. 利用记录型信号量机制: wait(s), signal(s)解决进程同步问题
  4. bs cs架构区别_ehr系统是选择BS还是CS 架构?
  5. w3c html5 客户端缓存数据格式,Html5应用程序缓存(Cache manifest)
  6. Python登录界面
  7. 如何应对Spark-Redis行海量数据插入、查询作业时碰到的问题
  8. ROS学习笔记五:理解ROS topics
  9. MFC 教程【9_MFC的状态】
  10. 开启MyBatis(三)工作原理
  11. 车辆路径跟踪算法及数学模型
  12. ant 安装依赖bug1
  13. 机器学习与分布式机器学习_机器学习-什么是机器学习?
  14. python软件长什么样子图片_使用Python把多个图片拼接成为长图
  15. css 剪辑图片_css实现图片剪裁
  16. 【数据结构】7-1 软硬车厢交替排列 (13 分)
  17. Debian etch 基本系统 initial ram disk 的分析
  18. Chrome 技术篇-未安装的crx插件源码查看,crx类型文件解压方法
  19. 数据结构·堆·完全二叉树
  20. JS中script标签defer和async属性的区别

热门文章

  1. Navicat for MySQL的安装
  2. 【Python】爬取理想论坛单帖爬虫
  3. 光场相机重聚焦原理③——Matlab光场工具包使用、重聚焦及多视角效果展示
  4. ws2812怎么调亮度_笔记本调节亮度无效!!!!!
  5. 流言粉碎机:JAVA使用 try catch会影响性能
  6. 广东 - 012 - 汕头南澳岛
  7. net.sf.json.JSONException: Unterminated string at character 1801
  8. 【数据结构】两栈共享空间的进一步理解
  9. 案例分享 | 基于Linkis+DSS构建合合信息一站式数据开发平台
  10. x10ti怎么禁用核显_4800h和10875h强者对决,英特尔这回给力了