una samsung salientes realizar puede programacion mientras llamadas llamada grabar está desactivar como celular bloqueo bloquear aplicaciones activado android telephony telephonymanager

samsung - Cómo colgar la llamada saliente en Android?



manual de programacion android pdf (8)

  1. Crea un BroadcastReceiver con una prioridad de 0.
  2. En BC intercepta el intento ACTION_NEW_OUTGOING_CALL en su método onReceive
  3. llamar a setResultData(null) en el mismo método

Esto evitará que la llamada se inicie (siempre que tu receptor sea el último en procesar la intención, creo)

Estoy desarrollando una aplicación donde una de las cosas que necesitamos es controlar la llamada saliente, al menos para poder detenerla desde nuestra aplicación.

Intenté usar Intent.ACTION_CALL de una actividad existente:

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

Pero detener la llamada parece no ser permitido a través de la API.

¿Puedes sugerir alguna solución?

Por ejemplo: ¿habilitar el modo avión durante la llamada? Solo un ejemplo; este truco no funcionó para mí.


Aquí está el código más actualizado, que también funcionará para Android P, porque tiene una API oficial para él (aquí):

en manifiesto, agrega esto:

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

En código, usa esto:

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://.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; }

o en 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://.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 } }



De acuerdo con la documentación sobre ACTION_NEW_OUTGOING_CALL

La intención tendrá el siguiente valor adicional:

EXTRA_PHONE_NUMBER: el número de teléfono originalmente destinado a marcarse.

Una vez que finaliza la transmisión, resultData se usa como el número real para llamar. Si es nulo, no se realizará ninguna llamada.


Para 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); } } } }

Además en Manifest poner en la sección del paquete:

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

Eso es todo.


Prueba esto:

(Utilicé Reflection para acceder a funciones avanzadas de telefonía y modificar algunas)

// 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); }


Puede intentar habilitar y luego desactivar el modo avión:

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);


Se mencionó la captura de la llamada saliente en un BroadcastReceiver y es definitivamente la mejor manera de hacerlo si desea finalizar la llamada antes de marcar.

Sin embargo, una vez que marca o in-call, esa técnica ya no funciona. La única manera de colgar que he encontrado hasta ahora es hacerlo a través de Java Reflection . Como no forma parte de la API pública, debe tener cuidado de usarla y no confiar en ella . Cualquier cambio en la composición interna de Android romperá efectivamente su aplicación.

El blog de Prasanta Paul demuestra cómo se puede lograr, que he resumido a continuación.

Obtener el objeto ITelephony :

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); }

Finalizando la llamada:

telephonyService.endCall();