Answer Incoming Call in Android 6.0

前端 未结 2 1421
醉梦人生
醉梦人生 2020-12-03 15:35

Is there any way to programmatically answer incoming calls in Android 6.0 without root privileges? I tried the following approaches :

  1. The internal ITelephony.a
2条回答
  •  悲哀的现实
    2020-12-03 16:20

    After searching a lot to do it, I publish the code I use in Orasi. Hope this will help many programmers... Note this code is extracted from a soft with other functions, so some code may be not used in all softwares.

    First, the function to answer, on all Android version, and to end call (without AIDL !):

    /////////////////////////////////////////////////////////////////////////////////////
    // Controle le téléphone en utilisant des primitives selon les versions d'OS
    private void PhoneControl(int nControl) {
        if(nControl == PHONE_END_CALL) { // End call, all Android version
            try {
                TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
                if(tm == null)
                    return;
                tm.getClass().getMethod("endCall").invoke(tm);
                bIsEnding = true;
            } catch (Exception e) { /* Do Nothing */ }
        }
    
        if(nControl == PHONE_ACCEPT_CALL) { // Accept phone call
            if(!bCallAccepted) { // Call déjà accepté => pas d'action (évite double action)
                bCallAccepted = true;
                if(Build.VERSION.SDK_INT >= 26) { // Pris en charge Android >= 8.0
                    if(checkSelfPermission("android.permission.ANSWER_PHONE_CALLS") == PackageManager.PERMISSION_GRANTED) {
                        TelecomManager tm = (TelecomManager) this.getSystemService(Context.TELECOM_SERVICE);
                        if(tm != null)
                            tm.acceptRingingCall();
                    }
                }
                if(Build.VERSION.SDK_INT >= 23 && Build.VERSION.SDK_INT < 26) { // Hangup in Android 6.x and 7.x
                    MediaSessionManager mediaSessionManager =  (MediaSessionManager) getApplicationContext().getSystemService(Context.MEDIA_SESSION_SERVICE);
                    if(mediaSessionManager != null) {
                        try {
                            List mediaControllerList = mediaSessionManager.getActiveSessions
                                    (new ComponentName(getApplicationContext(), NotificationReceiverService.class));
    
                            for (android.media.session.MediaController m : mediaControllerList) {
                                if ("com.android.server.telecom".equals(m.getPackageName())) {
                                    m.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
                                    m.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
                                    break;
                                }
                            }
                        } catch (Exception e) { /* Do Nothing */ }
                    }
                }
                if(Build.VERSION.SDK_INT < 23) { // Prend en charge jusqu'à Android 5.1
                    try {
                        if(Build.MANUFACTURER.equalsIgnoreCase("HTC")) { // Uniquement pour HTC
                            AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
                            if(audioManager!=null && !audioManager.isWiredHeadsetOn()) {
                                Intent i = new Intent(Intent.ACTION_HEADSET_PLUG);
                                i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                                i.putExtra("state", 0);
                                i.putExtra("name", "Orasi");
                                try {
                                    sendOrderedBroadcast(i, null);
                                } catch (Exception e) { /* Do Nothing */ }
                            }
                        }
                        Runtime.getRuntime().exec("input keyevent " +
                                Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK));
                    } catch (Exception e) {
                        // Runtime.exec(String) had an I/O problem, try to fall back
                        String enforcedPerm = "android.permission.CALL_PRIVILEGED";
                        Intent btnDown = new Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(
                                Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN,
                                        KeyEvent.KEYCODE_HEADSETHOOK));
                        Intent btnUp = new Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(
                                Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP,
                                        KeyEvent.KEYCODE_HEADSETHOOK));
    
                        this.sendOrderedBroadcast(btnDown, enforcedPerm);
                        this.sendOrderedBroadcast(btnUp, enforcedPerm);
                    }
                }
            }
        }
    }
    

    Second, the permissions:

        if(Build.VERSION.SDK_INT >= 26) { // Permission necessaire
            if(checkSelfPermission("android.permission.ANSWER_PHONE_CALLS") != PackageManager.PERMISSION_GRANTED) {
                String szPermissions[] = {"android.permission.ANSWER_PHONE_CALLS"};
                requestPermissions(szPermissions, 0);
            }
        }
    

        if(Build.VERSION.SDK_INT >= 23 && bUseScreen ) { // Permission necessaire
            if(checkSelfPermission("android.permission.SYSTEM_ALERT_WINDOW") != PackageManager.PERMISSION_GRANTED) {
                Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                startActivity(myIntent);
            }
            if(Build.VERSION.SDK_INT < 26) { // Permission pour Android 6.x et 7.x
                ContentResolver contentResolver = getContentResolver();
                String enabledNotificationListeners = Settings.Secure.getString(contentResolver, "enabled_notification_listeners");
                String packageName = getPackageName();
                if (enabledNotificationListeners == null || !enabledNotificationListeners.contains(packageName)) {
                    Intent intent2 = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
                    startActivity(intent2);
                }
            }
        }
    

    Note that there is a permission for Overlay, not directly to answer phone call.

    Notification receiver service:

    package mss.micromega.pmignard.orasi;
    
    import android.annotation.SuppressLint;
    import android.annotation.TargetApi;
    import android.os.Build;
    import android.service.notification.NotificationListenerService;
    
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    @SuppressLint("OverrideAbstract")
    public class NotificationReceiverService extends NotificationListenerService {
        public NotificationReceiverService() {
        }
    }
    

    Manifest:

        
                
                    
                
        
    

    
    
    

    Regards.

    Edited, I didn't use the good account

提交回复
热议问题