基于上一篇挂断电话:https://blog.csdn.net/whjk20/article/details/112916480, 实现拦截给定的电话号码。
目录
1. TelephonyManager: 电话服务的管理器,
2. PhoneStateListener: 电话状态监听器
2. Service 创建回调onCreate时, 创建TelephonyManager/ TelecomManager 对象,并注册电话状态监听, 以及初始化黑名单列表
一、功能描述
- 当前手机保存一些黑名单电话号码
- 当来电时,如果是黑名单号码,则自动挂断
二、过程分析
- 启动服务
- 在服务中监听电话状态
- 当电话状态是响铃时,判断是否为黑名单号码
- 如果是,挂断电话
三、相关API
1. TelephonyManager: 电话服务的管理器,
- 获取它的对象: context.getSystemService(TELEPHONY_SERVICE)
- 监听电话状态:telephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE)
注意: 当解除接听的时候,需要传 事件: PhoneStateListener.LISTEN_NONE
2. PhoneStateListener: 电话状态监听器
- 电话状态改变的回调方法: onCallStateChanged(int state, String phoneNumber)
- 电话状态(TelephonyManager 定义) : CALL_STATE_IDLE(初始状态) , CALL_STATE_RINGING(响铃), CALL_STATE_OFFHOOK(通话中)
注意:需要 应用程序 拥有 android.permission.READ_CALL_LOG 权限, 否则回调中的 phoneNumber 是为空的。
因此,不仅AndroidManifest 中需要声明使用这个权限,而且应用程序启动时,提示用户打开 “电话记录” 的权限。(毕竟权限的目的也是为了提醒用户,可能会用到一些隐私信息)
* @param state call state
* @param phoneNumber call phone number. If application does not have
* {@link android.Manifest.permission#READ_CALL_LOG READ_CALL_LOG} permission or carrier
* privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be
* passed as an argument.
*/
public void onCallStateChanged(@CallState int state, String phoneNumber) {
// default implementation empty
}
四、代码实现
1. 创建一个Service, 用于监听电话状态。
public class ListenCallService extends Service
2. Service 创建回调onCreate时, 创建TelephonyManager/ TelecomManager 对象,并注册电话状态监听, 以及初始化黑名单列表
//注册监听
mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
private PhoneStateListener mListener = new PhoneStateListener() {...}
mTelecomManager = (TelecomManager) getSystemService(TELECOM_SERVICE);
//add block number
mBlockNumberList.add("10086");
3. 电话状态改变时,处理拦截挂断
@Override
public void onCallStateChanged(int state, String phoneNumber) {
super.onCallStateChanged(state, phoneNumber);
if (state == TelephonyManager.CALL_STATE_RINGING && isBlockNumber(phoneNumber)) {
boolean ret = mTelecomManager.endCall();
}
}
4.完整代码
package com.example.endcallremoteservice;
import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.IBinder;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import java.util.ArrayList;
import java.util.List;
public class ListenCallService extends Service {
private static final String TAG = "ListenCallService";
private Context mContext;
private TelephonyManager mTelephonyManager;
private TelecomManager mTelecomManager;
private List<String> mBlockNumberList = new ArrayList<>();
private PhoneStateListener mListener = new PhoneStateListener() {
@RequiresApi(api = Build.VERSION_CODES.P)
@Override
public void onCallStateChanged(int state, String phoneNumber) {
super.onCallStateChanged(state, phoneNumber);
log("onCallStateChanged state=" + state + ", phoneNumber=" + phoneNumber);
if (state == TelephonyManager.CALL_STATE_RINGING && isBlockNumber(phoneNumber)) {
if (mContext.checkSelfPermission(Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
log("onCallStateChanged - no ANSWER_PHONE_CALLS permission");
return;
}
boolean ret = mTelecomManager.endCall();
log("onCallStateChanged endCall ret=" + ret);
}
}
};
private boolean isBlockNumber(String phoneNumber) {
if (phoneNumber == null) {
return false;
}
for (String number : mBlockNumberList) {
if (phoneNumber.equals(number)) {
return true;
}
}
return false;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onCreate() {
super.onCreate();
log("onCreate");
mContext = this;
mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
//监听
mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
mTelecomManager = (TelecomManager) getSystemService(TELECOM_SERVICE);
//add block number
mBlockNumberList.add("10086");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (mContext.checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
log("onCreate - do not grant permission.READ_CALL_LOG ");
} else {
log("onCreate - already granted permission.READ_CALL_LOG ");
}
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
log("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
log("onCreate");
return null;
}
@Override
public boolean onUnbind(Intent intent) {
log("onUnbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
log("onDestroy");
//解除监听
mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
}
private void log(String msg) {
Log.d(TAG, msg);
}
}
AndroidManifest 使用的权限
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
五、 输出结果:
//启动来电监听
2021-01-22 16:21:20.891 9188-9188/com.example.endcallremoteservice D/MainActivity: clicked button to enablePhoneListener
2021-01-22 16:21:20.899 9188-9188/com.example.endcallremoteservice D/ListenCallService: onCreate
2021-01-22 16:21:20.906 9188-9188/com.example.endcallremoteservice D/ListenCallService: onCreate - already granted permission.READ_CALL_LOG
2021-01-22 16:21:20.906 9188-9188/com.example.endcallremoteservice D/ListenCallService: onStartCommand
2021-01-22 16:21:20.908 9188-9188/com.example.endcallremoteservice D/ListenCallService: onCallStateChanged state=0, phoneNumber=
//拦截来电
2021-01-22 16:21:51.007 9188-9188/com.example.endcallremoteservice D/ListenCallService: onCallStateChanged state=1, phoneNumber=10086
2021-01-22 16:21:51.013 9188-9188/com.example.endcallremoteservice D/ListenCallService: onCallStateChanged endCall ret=true
2021-01-22 16:21:51.341 9188-9188/com.example.endcallremoteservice D/ListenCallService: onCallStateChanged state=0, phoneNumber=10086
//停止监听
2021-01-22 16:22:21.003 9188-9188/com.example.endcallremoteservice D/MainActivity: clicked button to stopPhoneListener
2021-01-22 16:22:21.011 9188-9188/com.example.endcallremoteservice D/ListenCallService: onDestroy