Android 四大组件之 Service_5_拦截电话号码

基于上一篇挂断电话:https://blog.csdn.net/whjk20/article/details/112916480, 实现拦截给定的电话号码。

目录

一、功能描述

二、过程分析

三、相关API

1. TelephonyManager: 电话服务的管理器, 

2. PhoneStateListener: 电话状态监听器

四、代码实现

1. 创建一个Service, 用于监听电话状态。

2. Service 创建回调onCreate时, 创建TelephonyManager/ TelecomManager 对象,并注册电话状态监听, 以及初始化黑名单列表

3. 电话状态改变时,处理拦截挂断

4.完整代码


一、功能描述

  1. 当前手机保存一些黑名单电话号码
  2. 当来电时,如果是黑名单号码,则自动挂断

二、过程分析

  1. 启动服务
  2. 在服务中监听电话状态
  3. 当电话状态是响铃时,判断是否为黑名单号码
  4. 如果是,挂断电话

三、相关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 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值