Android 11代码实现自动接听电话


本文主要讲解Android11手机自动接电话的代码实现。

手机来电时的基本操作过程

一、来电提醒阶段

在这里插入图片描述
当有电话呼入时,手机会通过以下方式提醒你:

  1. 铃声提醒:手机会按照你预先设置的铃声发出声音,铃声的音量大小取决于你之前在手机音量设置选项中的配置。例如,你可以将铃声设置为自己喜欢的歌曲或者系统自带的铃声。一些手机还支持为不同联系人设置专属铃声,这样你一听铃声就能知道来电者是谁。
  2. 震动提醒(如果开启):除了铃声外,手机还会震动,这种震动强度也可以在手机设置中进行调整。这在嘈杂环境或者你将手机放在口袋、包包里时很有用,能让你及时感知到来电。
  3. 屏幕显示提醒:手机屏幕会亮起,显示来电号码(如果号码已被识别)或者 “未知号码” 字样,同时还会显示接听和拒接按钮的图标。部分手机还会显示来电者的姓名(如果联系人信息已存储在手机通讯录中)和头像(如果有设置)。

二、接听来电操作

在这里插入图片描述

  1. 滑动接听(大多数智能手机)
    在屏幕亮起显示来电信息后,通常可以通过在屏幕上滑动手指来接听电话。例如,在苹果手机上,会有一个 “滑动来接听” 的提示,你需要按照箭头指示的方向滑动屏幕;安卓手机也有类似的操作方式,不过不同品牌和系统版本可能会有所差异,有的是从左向右滑动,有的是向上滑动等。
  2. 按键接听(部分功能手机或特定场景下的智能手机)
    有些手机带有实体按键,比如过去的按键式功能手机,有专门的接听键,一般是绿色的按键,按下这个按键就可以接听电话。在一些带有物理键盘的智能手机中,也可能保留了类似的接听按键设计。
    对于一些使用蓝牙耳机或者外接有线耳机的情况,耳机上通常也有接听按钮。当手机有来电时,按下耳机上的接听按钮就可以接听电话,这在双手不方便操作手机时非常方便,比如你在开车或者手上拿着东西的时候。

三、通话阶段

在这里插入图片描述

  1. 使用听筒通话
    当你接听电话后,将手机靠近耳朵,声音会通过手机顶部的听筒传出。你可以根据自己的听力情况和周围环境的嘈杂程度,使用手机侧面的音量按键来2. 2. 调整听筒音量大小。
  2. 使用免提通话
    如果想开启免提功能,可以在通话界面中找到免提按钮并点击。开启免提后,手机的声音会通过底部的扬声器播放出来,这样你可以不用将手机放在耳边,方便在双手忙碌时或者多人一起接听电话时使用。例如,你在做饭时双手都是面粉,就可以开启免提通话。
  3. 切换通话方式(如耳机和听筒切换)
    如果在通话过程中插入或者拔出耳机,手机会自动切换通话方式。比如,你本来使用听筒通话,插入耳机后,声音会通过耳机播放;拔出耳机后,又会恢复为听筒通话或者免提通话(如果之前开启了免提)。

四、结束通话操作

  1. 屏幕操作挂断电话
    在通话界面中,一般会有一个红色的 “挂断” 按钮,点击这个按钮就可以结束通话。在一些手机上,可能还支持通过其他手势来挂断电话,比如双击电源键(部分手机支持此功能)。
  2. 使用实体按键挂断电话(如果有)
    对于有实体按键的手机,可能会有一个专门的红色 “挂断” 按键,按下这个按键可以结束通话。
  3. 耳机操作挂断电话
    如果你使用耳机通话,耳机上通常也有挂断按钮,按下这个按钮就可以结束通话。

安卓代码实现自动接听电话

  1. 添加权限
    为了能够监听和控制电话状态,需要在AndroidManifest.xml文件中添加以下权限:
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
  1. 代码实现
    旧版本安卓接听电话代码
    使用反射调用answerRingingCall函数
public void acceptCall() {
    try {
        Method method = Class.forName("android.os.ServiceManager")
                .getMethod("getService", String.class);
        IBinder binder = (IBinder) method.invoke(null, new Object[]{Context.TELEPHONY_SERVICE});
        ITelephony telephony = ITelephony.Stub.asInterface(binder);
        telephony.answerRingingCall();
    } catch (NoSuchMethodException e) {
        Log.d(TAG, "", e);
    } catch (ClassNotFoundException e) {
        Log.d(TAG, "", e);
    } catch (Exception e) {
        Log.d(TAG, "", e);
    }
}

在新版本安卓中,以上方法无法使用,查看安卓SDK代码frameworks下代码会发现answerRingingCall函数已经失效了,被acceptRingingCall替代了,
frameworks/base/telephony/java/android/telephony/TelephonyManager.java

    /**
     * @removed Use {@link android.telecom.TelecomManager#acceptRingingCall} instead
     * @hide
     * @removed
     */
    @Deprecated
    @SystemApi
    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
    public void answerRingingCall() {
        // No-op
    }

新版本接听电话实现,Android11中实测

 private PhoneReceiver mPhoneReceiver;
 
 mPhoneReceiver = new PhoneReceiver();
 registerReceiver(mPhoneReceiver, new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL));
 registerReceiver(mPhoneReceiver, new IntentFilter("android.intent.action.PHONE_STATE"));
 
 public class PhoneReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals("android.intent.action.PHONE_STATE")) {
                // 来电了
                TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                switch (tm.getCallState()) {
                    case TelephonyManager.CALL_STATE_RINGING:
                        // 响铃了
                        String incoming_number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
                        Log.d(TAG, "来电手机号:" + incoming_number);
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        acceptRingingCall();
                        break;
                    case TelephonyManager.CALL_STATE_OFFHOOK:
                        // 通话中
                        break;
                    case TelephonyManager.CALL_STATE_IDLE:
                        // 空闲状态,即没有电话活动
                        break;
                    default:
                        break;
                }
            } else if (action.equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
                // 处理拨打电话事件
            }
        }
    }
    
    // 接听电话
    public void acceptRingingCall() {
        // 检查权限
        final int PERMISSION_REQUEST_CODE = 1;
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, PERMISSION_REQUEST_CODE);
            return;
        }
        // 反射接听电话
        TelecomManager telecomManager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
        try {
            Method method = telecomManager.getClass().getDeclaredMethod("acceptRingingCall");
            method.invoke(telecomManager);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        /*
        // 非反射接听电话
        TelecomManager telecomManager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
        if (telecomManager != null) {
            try {
                telecomManager.acceptRingingCall();
            } catch (SecurityException e) {
                // 没有权限或者没有默认电话应用的异常处理
            }
        }
        */
    }

在这里插入图片描述
自动接听后,手机界面上还会处于来电等待接听的界面,可以再在最上层弄个UI遮挡住它,最优的做法是在framework代码层对电话进行接听及UI变化的处理,这里不再详述。
作者:帅得不敢出门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅得不敢出门

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值