Comment raccrocher appel sortant sur Android?

je développe une application où l'une des choses dont nous avons besoin est de contrôler l'appel sortant, au moins pour pouvoir l'arrêter de notre application.

j'ai essayé d'utiliser Intent.ACTION_CALL d'une activité existante:

Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber)); 
startActivity(callIntent); 

mais arrêter l'appel semble être interdit par L'API.

pouvez-vous suggérer une solution?

par exemple: activer le mode avion pendant l'appel? Juste un exemple: ce piratage n'a pas marché pour moi.

44
demandé sur Lucifer 2009-03-01 10:37:55

8 réponses

capturer l'appel sortant dans un BroadcastReceiver a été mentionné et est certainement la meilleure façon de le faire si vous voulez mettre fin à l'appel avant de composer.

une fois que la composition ou l'appel, cependant, cette technique ne fonctionne plus. La seule façon de raccrocher que j'ai rencontré jusqu'à présent, est de le faire à travers Java Reflection . Comme il ne fait pas partie de l'API publique, vous devez faire attention à l'utiliser, et ne pas compter sur elle . Tout modifier la composition interne D'Android va effectivement briser votre application.

le blog de Prasanta Paul démontre comment cela peut être accompli, ce que j'ai résumé ci-dessous.

obtenir le ITelephony objet:

TelephonyManager tm = (TelephonyManager) context
        .getSystemService(Context.TELEPHONY_SERVICE);
try {
    // Java reflection to gain access to TelephonyManager's
    // ITelephony getter
    Log.v(TAG, "Get getTeleService...");
    Class c = Class.forName(tm.getClass().getName());
    Method m = c.getDeclaredMethod("getITelephony");
    m.setAccessible(true);
    com.android.internal.telephony.ITelephony telephonyService =
            (ITelephony) m.invoke(tm);
} catch (Exception e) {
    e.printStackTrace();
    Log.e(TAG,
            "FATAL ERROR: could not connect to telephony subsystem");
    Log.e(TAG, "Exception object: " + e);
}

fin de l'appel:

telephonyService.endCall();
29
répondu Paul Lammertsma 2012-03-16 12:55:07

essayez ceci:

(j'ai utilisé réflexion pour accéder aux fonctions de téléphonie avancées et modifier quelque chose)

// required permission <uses-permission android:name="android.permission.CALL_PHONE"/>

try {
    //String serviceManagerName = "android.os.IServiceManager";
    String serviceManagerName = "android.os.ServiceManager";
    String serviceManagerNativeName = "android.os.ServiceManagerNative";
    String telephonyName = "com.android.internal.telephony.ITelephony";

    Class telephonyClass;
    Class telephonyStubClass;
    Class serviceManagerClass;
    Class serviceManagerStubClass;
    Class serviceManagerNativeClass;
    Class serviceManagerNativeStubClass;

    Method telephonyCall;
    Method telephonyEndCall;
    Method telephonyAnswerCall;
    Method getDefault;

    Method[] temps;
    Constructor[] serviceManagerConstructor;

    // Method getService;
    Object telephonyObject;
    Object serviceManagerObject;

    telephonyClass = Class.forName(telephonyName);
    telephonyStubClass = telephonyClass.getClasses()[0];
    serviceManagerClass = Class.forName(serviceManagerName);
    serviceManagerNativeClass = Class.forName(serviceManagerNativeName);

    Method getService = // getDefaults[29];
    serviceManagerClass.getMethod("getService", String.class);

    Method tempInterfaceMethod = serviceManagerNativeClass.getMethod(
                "asInterface", IBinder.class);

    Binder tmpBinder = new Binder();
    tmpBinder.attachInterface(null, "fake");

    serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
    IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
    Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);

    telephonyObject = serviceMethod.invoke(null, retbinder);
    //telephonyCall = telephonyClass.getMethod("call", String.class);
    telephonyEndCall = telephonyClass.getMethod("endCall");
    //telephonyAnswerCall = telephonyClass.getMethod("answerRingingCall");

    telephonyEndCall.invoke(telephonyObject);

} catch (Exception e) {
    e.printStackTrace();
    Log.error(DialerActivity.this,
                "FATAL ERROR: could not connect to telephony subsystem");
    Log.error(DialerActivity.this, "Exception object: " + e);
}
26
répondu Felipe 2017-05-23 12:18:20
  1. créer un BroadcastReceiver avec une priorité de 0.
  2. En la colombie-britannique intercepter le ACTION_NEW_OUTGOING_CALL l'intention de son onReceive méthode
  3. appel setResultData(null) dans la même méthode

Cela permettra d'éviter l'appel, de l'ouverture (tant que votre récepteur est le dernier processus de l'intention, je pense)

21
répondu Guido 2010-08-11 06:42:53

vous pouvez essayer d'activer puis désactiver le mode avion:

android.provider.Settings.System.putInt(getContentResolver(),
        android.provider.Settings.System.AIRPLANE_MODE_ON, 1);

Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", 1);
sendBroadcast(new Intent("android.intent.action.AIRPLANE_MODE"));
sendBroadcast(intent);
android.provider.Settings.System.putInt(getContentResolver(),
        android.provider.Settings.System.AIRPLANE_MODE_ON, 0);

intent.putExtra("state", 0);
sendBroadcast(new Intent("android.intent.action.AIRPLANE_MODE"));
sendBroadcast(intent);
5
répondu Gung Shi Jie 2011-01-26 12:35:53

Pour Ilana:

public class ilanasReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
            if (getResultData()!=null) {
                String number = "123456";
                setResultData(number);
            }
        }
    }
}

en outre dans le Manifeste mis dans la section d'emballage:

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

C'est tout.

4
répondu Tony 2017-04-13 05:17:10

considérant le potentiel de merveilleux méfaits, je serais surpris si cela était permis.

ce fil indique clairement que L'API ne peut pas terminer un appel . D'autres ont essayé .

3
répondu Pat 2009-03-01 20:08:48

voici le code le plus mis à jour, qui fonctionnera pour Android P too, car il a une API officielle pour lui ( ici ) :

dans le manifeste, ajouter ceci:

<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS"/>

en code, utilisez ceci:

Java:

@SuppressLint("PrivateApi")
public static boolean endCall(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        final TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
        if (telecomManager != null && ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
            telecomManager.endCall();
            return true;
        }
        return false;
    }
    //use unofficial API for older Android versions, as written here: https://stackoverflow.com/a/8380418/878126
    try {
        final Class<?> telephonyClass = Class.forName("com.android.internal.telephony.ITelephony");
        final Class<?> telephonyStubClass = telephonyClass.getClasses()[0];
        final Class<?> serviceManagerClass = Class.forName("android.os.ServiceManager");
        final Class<?> serviceManagerNativeClass = Class.forName("android.os.ServiceManagerNative");
        final Method getService = serviceManagerClass.getMethod("getService", String.class);
        final Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
        final Binder tmpBinder = new Binder();
        tmpBinder.attachInterface(null, "fake");
        final Object serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
        final IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
        final Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
        final Object telephonyObject = serviceMethod.invoke(null, retbinder);
        final Method telephonyEndCall = telephonyClass.getMethod("endCall");
        telephonyEndCall.invoke(telephonyObject);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        LogManager.e(e);
    }
    return false;
}

ou à Kotlin:

@SuppressLint("PrivateApi")
fun endCall(context: Context): Boolean {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
            telecomManager.endCall()
            return true
        }
        return false
    }
    //use unofficial API for older Android versions, as written here: https://stackoverflow.com/a/8380418/878126
    try {
        val telephonyClass = Class.forName("com.android.internal.telephony.ITelephony")
        val telephonyStubClass = telephonyClass.classes[0]
        val serviceManagerClass = Class.forName("android.os.ServiceManager")
        val serviceManagerNativeClass = Class.forName("android.os.ServiceManagerNative")
        val getService = serviceManagerClass.getMethod("getService", String::class.java)
        val tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder::class.java)
        val tmpBinder = Binder()
        tmpBinder.attachInterface(null, "fake")
        val serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder)
        val retbinder = getService.invoke(serviceManagerObject, "phone") as IBinder
        val serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder::class.java)
        val telephonyObject = serviceMethod.invoke(null, retbinder)
        val telephonyEndCall = telephonyClass.getMethod("endCall")
        telephonyEndCall.invoke(telephonyObject)
        return true
    } catch (e: Exception) {
        e.printStackTrace()
        return false
    }
}
2
répondu android developer 2018-07-24 12:12:38

selon la documentation sur ACTION_NEW_OUTGOING_CALL

L'Intention de la valeur supplémentaire:

EXTRA_PHONE_NUMBER-le numéro de téléphone initialement prévu pour être composé.

une fois l'émission terminée, les données de résultat sont utilisées comme nombre réel à appeler. Si null, aucun appel ne sera passé.

0
répondu Denis Souza 2010-07-31 02:48:14