如何在Android上以编程方式自动应答来电

时间:2018-08-16 07:23:24

标签: java android telephonymanager

一旦尝试检测到我的应用程序中的来电,我会尝试自动应答。我的应用程序已经检测到何时有来电,但仍然无法接听电话。我正在使用telephonyManager,并且本教程Answer incoming call using android.telecom and InCallService,本教程Answer Incoming Call in Android 6.0和本教程Can't answer incoming call in 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 个答案:

答案 0 :(得分:0)

我正在满足相同的要求,因此共享了适用于所有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();