当前位置: 首页 > 知识库问答 >
问题:

如何在android上自动编程地接听来电

司马振国
2023-03-14

我试图在我的应用程序上自动接听来电,一旦他们被检测到。我的应用程序已经检测到我什么时候有来电,但仍然不接电话。我用的是telephonyManager,我用Android.Telecom和InCallService来接来电,这一个在Android 6.0接来电,这一个在Android marshmallow 6.0不能接来电。如果有人知道怎么做,请告诉我。我不介意改变我的代码,我只想让它完成,这里是我的代码。

类,在该类中检测传入呼叫并尝试自动应答传入呼叫

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.telecom.Log;
    import android.telephony.TelephonyManager;
    import android.view.KeyEvent;
    import android.widget.Toast;

    import java.io.IOException;

public class InterceptCall extends BroadcastReceiver {



    @Override
    public void onReceive(final Context context, Intent intent) {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);

        try {
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)){
                Toast.makeText(context, "Ringing!!", Toast.LENGTH_SHORT).show();
                TelephonyMethods.AnswerRinginCall(telephonyManager);//method that should answer incoming calls 

            }
            if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_OFFHOOK)){
                Toast.makeText(context, "Received!!", Toast.LENGTH_SHORT).show();
            }
            if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_IDLE)){
                Toast.makeText(context, "IDL!!", Toast.LENGTH_SHORT).show();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

类,我在其中调用telephonyManager类的answerRingingCall()方法

public class TelephonyMethods {

    public static void AnswerRinginCall(final TelephonyManager manager){
           manager.answerRingingCall();
    }


}

telephonyMnager类的

 /** @hide */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
    public void answerRingingCall() {
        try {
            ITelephony telephony = getITelephony();
            if (telephony != null)
                telephony.answerRingingCall();
        } catch (RemoteException e) {
            Log.e(TAG, "Error calling ITelephony#answerRingingCall", e);
        }
    }

共有1个答案

璩涛
2023-03-14

我在相同的需求工作,特此分享整个类,这适用于所有API版本。

public class CallManager {
    private static final String TAG = CallManager.class.getSimpleName();
    private AudioManager audioManager;
    private Context context;

    public CallManager(Context context) {
        this.context = context;
        audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    }

    public void acceptCall() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
                if (telecomManager != null) {
                    telecomManager.acceptRingingCall();
                }
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                throughMediaController(context);
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                throughAudioManager();
            }
        } catch (Exception e) {
            throughReceiver(context);
        }
    }

    private ITelephony getTelephonyService(Context context) {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        try {
            Class c = Class.forName(tm.getClass().getName());
            Method m = c.getDeclaredMethod("getITelephony");
            m.setAccessible(true);
            return (ITelephony) m.invoke(tm);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private void throughTelephonyService(Context context) {
        ITelephony telephonyService = getTelephonyService(context);
        if (telephonyService != null) {
            telephonyService.silenceRinger();
            telephonyService.answerRingingCall();
        }
    }

    private void throughAudioManager() {
        KeyEvent downEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK);
        KeyEvent upEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK);
        audioManager.dispatchMediaKeyEvent(downEvent);
        audioManager.dispatchMediaKeyEvent(upEvent);
    }

    private void throughReceiver(Context context) {
        try {
            throughTelephonyService(context);
        } catch (Exception exception) {
            boolean broadcastConnected = "HTC".equalsIgnoreCase(Build.MANUFACTURER)
                    && !audioManager.isWiredHeadsetOn();

            if (broadcastConnected) {
                broadcastHeadsetConnected(false, context);
            }
            try {
                Runtime.getRuntime().exec("input keyevent " + KeyEvent.KEYCODE_HEADSETHOOK);
            } catch (IOException ioe) {
                throughPhoneHeadsetHook(context);
            } finally {
                if (broadcastConnected) {
                    broadcastHeadsetConnected(false, context);
                }
            }
        }
    }

    private void broadcastHeadsetConnected(boolean connected, Context context) {
        Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        intent.putExtra("state", connected ? 1 : 0);
        intent.putExtra("name", "mysms");
        try {
            context.sendOrderedBroadcast(intent, null);
        } catch (Exception e) {
        }
    }

    private void throughMediaController(Context context) {
        MediaSessionManager mediaSessionManager = (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
        try {
            List<MediaController> controllers = mediaSessionManager.getActiveSessions(new ComponentName(context, NotificationService.class));
            for (MediaController controller : controllers) {
                if ("com.android.server.telecom".equals(controller.getPackageName())) {
                    controller.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
                    break;
                }
            }
        } catch (Exception e) {
            throughAudioManager();
        }
    }

    private void throughPhoneHeadsetHook(Context context) {
        Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON);
        buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
        context.sendOrderedBroadcast(buttonDown, "android.permission.CALL_PRIVILEGED");

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

只需简单地调用acceptCall方法,如下所示

CallManager callManager = new CallManager(this);
callManager.acceptCall();
 类似资料:
  • 问题内容: 当我尝试为来电创建自定义屏幕时,我试图以编程方式接听来电。我正在使用以下代码,但在Android 5.0中不起作用。 问题答案: 使用Android 8.0 Oreo更新 尽管最初要求提供Android L支持是一个问题,但似乎仍然有人在质疑这个问题和答案,因此值得描述Android 8.0 Oreo中引入的改进。向后兼容方法仍在下面描述。 发生了什么变化? 从Android 8.0

  • 本文向大家介绍如何在iOS中以编程方式接听来电?,包括了如何在iOS中以编程方式接听来电?的使用技巧和注意事项,需要的朋友参考一下 Apple iPhone SDK不允许使用此功能。如果您确实希望实现它,则可以使用一些私有API,例如CTCallAnswer(call);。 这将导致您的应用商店被拒绝。

  • 我测试了这个帖子的答案,但它也不起作用:在Android6.0中接听来电 IncomingActivity:

  • 问题内容: 我已经在Windows上(在本地计算机上)成功地将MongoDB安装为服务,但是现在我想将MongoDb移到单独的服务器上。因此,我将压缩包解压缩到网络上的虚拟服务器(正在运行linux)。 当我从本地计算机使用PuTTY连接到服务器(“ testmongoserver”)时,我启动了mongod服务器,它告诉我它正在侦听默认的28017端口。mongo控制台也正在运行,并允许我创建一

  • Android将WIFI详细信息保存到WifiConfiguration类中。当WIFI为ON和SSID时,Pass-key详细信息与WIFI网络匹配,然后Android自动连接特定的WIFI网络。如何禁用该自动连接功能?问这个问题的目的是,我有两个配置的网络(已经保存),我想在按钮单击事件上连接WIFI,但android的自动连接功能与WIFI本身连接。

  • 问题内容: 我通过asp.net开发了一个移动页来播放mp4视频。 我知道iOS已禁用自动播放功能以最大程度地减少用户带宽,所以我如何在Android上自动播放HTML5 mp4视频? 我已经在HTML5代码中放置了自动播放功能,但是它不起作用。 以下是我的代码: 此外,我已经解决了用户单击图像叠加层可以播放视频的问题。感谢Karthi 这是代码: 谢谢 问题答案: 您可以将’muted’和’au