¿Cómo responder / finalizar una llamada programáticamente en Android 4.1?

Estoy escribiendo una aplicación de Android en la que necesito responder una llamada entrante, hacer un trabajo y luego finalizar la llamada. Después de todas las búsquedas en Google, pude encontrar dos formas diferentes de lograr esto, las cuales no funcionan con las versiones recientes de Android, específicamente después de la versión 4.1, Jelly Bean.

I.) Acceda a "com.android.internal.telephony.ITelephony" utilizando Java Reflection en el receptor de Broadcast para "android.intent.action.PHONE_STATE". El código de ejemplo a continuación se puede encontrar en cientos de publicaciones relacionadas:

public class PhoneCallReceiver extends BroadcastReceiver {
 Context context = null;
 private static final String TAG = "Phone call";
 private ITelephony telephonyService;

@Override
 public void onReceive(Context context, Intent intent) {
  if (!intent.getAction().equals("android.intent.action.PHONE_STATE")) 
    return;

  Log.v(TAG, "Receving....");
  TelephonyManager telephony = (TelephonyManager) 
  context.getSystemService(Context.TELEPHONY_SERVICE);  
  try {
      Log.v(TAG, "Get getTeleService...");
      Class c = Class.forName(telephony.getClass().getName());
      Method m = c.getDeclaredMethod("getITelephony");
      m.setAccessible(true);
      telephonyService = (ITelephony) m.invoke(telephony);
      telephonyService.silenceRinger();
      Log.v(TAG, "Answering Call now...");
      telephonyService.answerRingingCall();
      Log.v(TAG, "Call answered...");
      //telephonyService.endCall();
  } catch (Exception e) {
   e.printStackTrace();
   Log.e(TAG,
           "FATAL ERROR: could not connect to telephony subsystem");
   Log.e(TAG, "Exception object: " + e);
  }
 }
}

El problema con este código es que

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

se requiere para que este método funcione, y este permiso se ha definido como "solo para aplicaciones del sistema" de Android v 2.3. En resumen, las aplicaciones de usuario normales ya no pueden definir este permiso en el archivo de manifiesto.

II.) Otra forma es simular el empuje del gancho para auriculares que hace que Android responda a la llamada. Esto se hace transmitiendo el "Intent.ACTION_MEDIA_BUTTON" como se muestra en el siguiente código.

public class PhoneCallReceiver extends BroadcastReceiver {
 Context context = null;
 private static final String TAG = "Phone call";

 @Override
 public void onReceive(Context context, Intent intent) {
     if (!intent.getAction().equals("android.intent.action.PHONE_STATE")) 
         return;

     String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
     if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
         String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

         Intent answer = new Intent(Intent.ACTION_MEDIA_BUTTON);
         answer.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
         context.sendOrderedBroadcast(answer, null);
         Log.d(TAG, "Answered incoming call from: " + number);
     }   
     return;
 } 
}

Este método funciona hasta Android 4.1, después de lo cual Android ha restringido las aplicaciones de usuario de la transmisión "Intent.ACTION_MEDIA_BUTTON".

Así que mi conclusión es que actualmente no hay forma de lograr esto en Android 4.1 o posterior.

¿Alguien más ha encontrado alguna otra solución o solución a este problema?

Respuestas a la pregunta(8)

Su respuesta a la pregunta