zoukankan      html  css  js  c++  java
  • 模拟接听电话的方法,兼容华为android5.0以上设备

    /**
    * 通过反射调用的方法,接听电话,该方法只在android 2.3之前的系统上有效。
    *
    * @param context
    */
    private static void answerRingingCallWithReflect(Context context) {
    try {
    Object telephonyObject = getTelephonyObject(context);
    if (null != telephonyObject) {
    Class telephonyClass = telephonyObject.getClass();
    Method endCallMethod = telephonyClass
    .getMethod("answerRingingCall");
    endCallMethod.setAccessible(true);
    endCallMethod.invoke(telephonyObject);
    // ITelephony iTelephony = (ITelephony) telephonyObject;
    // iTelephony.answerRingingCall();
    }
    } catch (SecurityException e) {
    e.printStackTrace();
    } catch (IllegalArgumentException e) {
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    e.printStackTrace();
    } catch (NoSuchMethodException e) {
    e.printStackTrace();
    }

    }

    /**
    * 伪造一个有线耳机插入,并按接听键的广播,让系统开始接听电话。
    *
    * @param context
    */
    private static void answerRingingCallWithBroadcast(Context context) {
    try {
    Runtime runtime = Runtime.getRuntime();
    runtime.exec("input keyevent " +KeyEvent.KEYCODE_HEADSETHOOK);
    } catch (Exception e) {
    AudioManager audioManager = (AudioManager) context
    .getSystemService(Context.AUDIO_SERVICE);
    // 判断是否插上了耳机
    if (!audioManager.isWiredHeadsetOn()) {
    // 4.1以上系统限制了部分权限, 使用三星4.1版本测试提示警告:Permission Denial: not allowed to
    // send broadcast android.intent.action.HEADSET_PLUG from pid=1324,
    // uid=10017
    // 这里需要注意一点,发送广播时加了权限“android.permission.CALL_PRIVLEGED”,则接受该广播时也需要增加该权限。但是4.1以上版本貌似这个权限只能系统应用才可以得到。测试的时候,自定义的接收器无法接受到此广播,后来去掉了这个权限,设为NULL便可以监听到了。

    if (android.os.Build.VERSION.SDK_INT >= 15) {
    Intent meidaButtonIntent = new Intent(
    Intent.ACTION_MEDIA_BUTTON);
    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP,
    KeyEvent.KEYCODE_HEADSETHOOK);
    meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
    context.sendOrderedBroadcast(meidaButtonIntent, null);
    } else {
    // 以下适用于Android2.3及2.3以上的版本上 ,但测试发现4.1系统上不管用。
    Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG);
    localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    localIntent1.putExtra("state", 1);
    localIntent1.putExtra("microphone", 1);
    localIntent1.putExtra("name", "Headset");
    context.sendOrderedBroadcast(localIntent1,
    "android.permission.CALL_PRIVILEGED");

    Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON);
    KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN,
    KeyEvent.KEYCODE_HEADSETHOOK);
    localIntent2.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent1);
    context.sendOrderedBroadcast(localIntent2,
    "android.permission.CALL_PRIVILEGED");

    Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON);
    KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP,
    KeyEvent.KEYCODE_HEADSETHOOK);
    localIntent3.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent2);
    context.sendOrderedBroadcast(localIntent3,
    "android.permission.CALL_PRIVILEGED");

    Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG);
    localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    localIntent4.putExtra("state", 0);
    localIntent4.putExtra("microphone", 1);
    localIntent4.putExtra("name", "Headset");
    context.sendOrderedBroadcast(localIntent4,
    "android.permission.CALL_PRIVILEGED");
    }

    } else {
    Intent meidaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
    KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP,
    KeyEvent.KEYCODE_HEADSETHOOK);
    meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
    context.sendOrderedBroadcast(meidaButtonIntent, null);
    }
    }
    }


    /**
    * <br/>
    * 概述:接电话 <br/>
    *
    * @param context
    */
    public static void answerRingingCall(Context context) {
    if (isGingerbreadOrlater()) {
    answerRingingCallWithBroadcast(context);
    } else {
    answerRingingCallWithReflect(context);
    }
    }

    由于谷歌官方在2016年的十月份给5.1以上的设备更新了安全补丁,导致了以上接电话的方法不能使用了(参考https://stackoverflow.com/questions/40673922/regd-support-of-answer-call-in-android-nougat/41356688#41356688),

    目前只有一种方法可以测试通过,就是通过读取通知的权限来实现(参考https://stackoverflow.com/questions/41542245/programmatically-accept-call-in-nougat https://stackoverflow.com/a/43254844/7204388 )。

     

    但我也遇到了问题,读取通知是根据文字来获取对应的pendingIntent,然后再发送通知,但是有的来电话界面并没有对应的文字,所以是不能获取到对应的intent的。如果你有更好的解决方法,请联系我714094450




  • 相关阅读:
    百度地图 如何制作泡泡放大镜?
    百度地图 孪生姐妹地图
    百度地图Api进阶教程-点聚合9.html
    百度地图Api进阶教程-实例高级操作8.html
    百度地图Api进阶教程-用户自定义数据(标记和搜索)7.html
    百度地图Api进阶教程-地图鼠标左右键操作实例和鼠标样式6.html
    百度地图Api进阶教程-弹出信息窗口5.html
    百度地图Api进阶教程-点击生成和拖动标注4.html
    app设计需注意的
    JS移动客户端--触屏滑动事件 banner图效果
  • 原文地址:https://www.cnblogs.com/dongweiq/p/5882408.html
Copyright © 2011-2022 走看看