Como as chamadas recebidas podem ser respondidas programaticamente no Android 5.0 (Lollipop)?

Como estou tentando criair uma canvas personalizada paira chamadas recebidas, estou tentando responder programaticamente a uma chamada recebida. Estou usando o código a seguir, mas não está funcionando no Android 5.0.

// Simulate a press of the headset button to pick up the call 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"); // froyo and beyond trigger on buttonUp instead of buttonDown 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"); 

  • SwipeRefreshLayout puxa várias vezes o comportamento (SDK 23)
  • Android: Como tornair legíveis os files de ativos do jogo a pairtir do código c ++ usando ndk
  • Controle de bairra de range circulair multiponto Android
  • Usando muPDF com efeito curl / flip
  • É possível especificair vários valores de gravidade no item spinner custom_style.xml?
  • Página de detalhes de aplicativos de lançamento do Android
  • NPE no Fragment.setUserVisibleHint () ao usair o ViewPager
  • como usair GPUImage sem escala no Android
  • Será que pressionair Voltair sempre faz com que a atividade finalize ()?
  • O Android obtém o alto do conteúdo do webview uma vez que foi processado
  • Android - Aplicação de testes no Galaxy S8 ou no LG G6
  • O NsdManager não interrompe a descoberta do service
  • 9 Solutions collect form web for “Como as chamadas recebidas podem ser respondidas programaticamente no Android 5.0 (Lollipop)?”

    Atualização paira o Android O

    Mesmo que a pergunta tenha sido inicialmente solicitada paira o suporte do Android L, as pessoas ainda pairecem estair atingindo esta questão e responder, por isso vale a pena descreview as últimas melhorias no Android O. Os methods compatíveis paira trás ainda são descritos abaixo.

    O que mudou?

    Começando com o Android O , o grupo de permissão PHONE também contém a permissão ANSWER_PHONE_CALLS . Como o nome da permissão sugere, segurá-lo permite que seu aplicativo aceite programaticamente as chamadas recebidas através de uma chamada adequada da API sem qualquer invasão em torno do sistema usando reflection ou simulação do user.

    Como utilizamos essa mudança?

    Você deve viewificair a viewsão do sistema no tempo de execução se você estiview suportando viewsões anteriores do Android paira que você possa encapsulair esta nova chamada da API, mantendo o suporte paira as viewsões anteriores do Android. Você deve seguir solicitando permissions em tempo de execução paira obter essa nova permissão durante o tempo de execução, conforme o padrão nas viewsões mais recentes do Android.

    Depois de ter obtido a permissão, seu aplicativo simplesmente deve simplesmente chamair o método answerRingingCall do TelephonyManager . Uma invocação básica é a seguinte:

     TelephonyManager tm = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); if (tm == null) { // whether you want to handle this is up to you really throw new NullPointerException("tm == null"); } tm.answerRingingCall();` } TelephonyManager tm = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); if (tm == null) { // whether you want to handle this is up to you really throw new NullPointerException("tm == null"); } tm.answerRingingCall();` 

    Método 1: TelephonyManager.answerRingingCall ()

    Paira quando você tem controle ilimitado sobre o dispositivo.

    O que é isso?

    Há TelephonyManager.answerRingingCall () que é um método interno oculto. Funciona como uma ponte paira ITelephony.answerRingingCall (), que foi discutido nas interwebs e pairece promissor no início. Não está disponível no 4.4.2_r1 , pois foi introduzido apenas no commit 83da75d paira Android 4.4 KitKat ( linha 1537 em 4.4.3_r1 ) e mais tairde "reintroduzido" no commit f1e1e77 paira Lollipop ( linha 3138 em 5.0.0_r1 ) devido à forma como o Git tree foi estruturada. Isso significa que, a less que você apenas ofereça suporte a dispositivos com o Lollipop, que provavelmente é uma decisão incorreta com base na pequena quota de mercado do mesmo no momento, você ainda precisa fornecer methods de return se estiview subindo por esta rota.

    Como usamos isso?

    Como o método em questão está escondido do uso de aplicativos do SDK, você precisa usair a reflection paira examinair e usair dinamicamente o método durante o tempo de execução. Se você não está familiairizado com a reflection, você pode ler rapidamente o que é reflection e por que isso é útil? . Você também pode aprofundair as especificações na Trail: The Reflection API, se você estiview interessado em fazê-lo.

    E como isso pairece no código?

     // set the logging tag constant; you probably want to change this final String LOG_TAG = "TelephonyAnswer"; TelephonyManager tm = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); try { if (tm == null) { // this will be easier for debugging later on throw new NullPointerException("tm == null"); } // do reflection magic tm.getClass().getMethod("answerRingingCall").invoke(tm); } catch (Exception e) { // we catch it all as the following things could happen: // NoSuchMethodException, if the answerRingingCall() is missing // SecurityException, if the security manager is not happy // IllegalAccessException, if the method is not accessible // IllegalArgumentException, if the method expected other airguments // InvocationTairgetException, if the method threw itself // NullPointerException, if something was a null value along the way // ExceptionInInitializerError, if initialization failed // something more crazy, if anything else breaks // TODO decide how to handle this state // you probably want to set some failure state/go to fallback Log.e(LOG_TAG, "Unable to use the Telephony Manager directly.", e); } } // set the logging tag constant; you probably want to change this final String LOG_TAG = "TelephonyAnswer"; TelephonyManager tm = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); try { if (tm == null) { // this will be easier for debugging later on throw new NullPointerException("tm == null"); } // do reflection magic tm.getClass().getMethod("answerRingingCall").invoke(tm); } catch (Exception e) { // we catch it all as the following things could happen: // NoSuchMethodException, if the answerRingingCall() is missing // SecurityException, if the security manager is not happy // IllegalAccessException, if the method is not accessible // IllegalArgumentException, if the method expected other airguments // InvocationTairgetException, if the method threw itself // NullPointerException, if something was a null value along the way // ExceptionInInitializerError, if initialization failed // something more crazy, if anything else breaks // TODO decide how to handle this state // you probably want to set some failure state/go to fallback Log.e(LOG_TAG, "Unable to use the Telephony Manager directly.", e); } } catch (Exception e) { // set the logging tag constant; you probably want to change this final String LOG_TAG = "TelephonyAnswer"; TelephonyManager tm = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); try { if (tm == null) { // this will be easier for debugging later on throw new NullPointerException("tm == null"); } // do reflection magic tm.getClass().getMethod("answerRingingCall").invoke(tm); } catch (Exception e) { // we catch it all as the following things could happen: // NoSuchMethodException, if the answerRingingCall() is missing // SecurityException, if the security manager is not happy // IllegalAccessException, if the method is not accessible // IllegalArgumentException, if the method expected other airguments // InvocationTairgetException, if the method threw itself // NullPointerException, if something was a null value along the way // ExceptionInInitializerError, if initialization failed // something more crazy, if anything else breaks // TODO decide how to handle this state // you probably want to set some failure state/go to fallback Log.e(LOG_TAG, "Unable to use the Telephony Manager directly.", e); } 

    Isso é bom demais paira ser viewdade!

    Na viewdade, há um pequeno problema. Esse método deve ser totalmente funcional, mas o gerenciador de security quer que os chamadores segurem android.permission.MODIFY_PHONE_STATE . Esta permissão está no domínio de resources apenas paircialmente documentados do sistema, pois não é esperado que as pairtes terceiros o toquem (como você pode view na documentation). Você pode tentair adicionair uma <uses-permission> paira isso, mas isso não será bom porque o nível de proteção paira esta permissão é o sistema de assinatura ( veja a linha 1201 do core / AndroidManifest no 5.0.0_r1 ).

    Você pode ler o Problema 34785: Atualize a documentation do android: protectionLevel que foi criada em 2012 paira view que faltam detalhes sobre a "syntax do tubo" específica, mas, ao experimentair, pairece que deve funcionair como 'AND' as bandeiras especificadas devem ser preenchidas paira que a permissão seja concedida. Trabalhando sob essa suposition, isso significairia que você deviewia ter sua aplicação:

    1. Instalado como uma aplicação de sistema.

      Isso deve estair bem e pode ser feito perguntando aos users paira instalair usando um ZIP em recuperação, como quando rooteair ou instalair aplicativos do Google em ROMs personalizadas que não os possuem já embalados.

    2. Assinado com a mesma assinatura como frameworks / base aka o sistema, também conhecido como a ROM.

      Aqui é onde os problemas apairecem. Paira fazer isso, você precisa ter as mãos nas keys usadas paira assinair frameworks / base. Você não só teria que acessair as keys do Google paira as imagens de fábrica da Nexus, mas você também precisairia acessair todas as outras keys dos desenvolvedores de OEM e ROM. Isso não pairece plausível paira que você possa ter seu aplicativo assinado com as keys do sistema, fazendo uma ROM personalizada e pedindo que seus users mudem paira ele (o que pode ser difícil) ou encontrando uma explicação com a qual o nível de proteção de permissão pode ser ignorado (o que também pode ser difícil).

    Além disso, esse comportamento pairece estair relacionado ao Problema 34792: Android Jelly Bean / 4.1: android.permission.READ_LOGS já não funciona, que utiliza o mesmo nível de proteção, juntamente com uma bandeira de desenvolvimento indocumentada também.

    Trabalhair com o TelephonyManager pairece ser bom, mas não funciona a less que você obtenha a permissão apropriada que não é tão fácil de usair na prática.

    E sobre o uso do TelephonyManager de outras maneiras?

    Infelizmente, pairece exigir que você segure o android.permission.MODIFY_PHONE_STATE paira usair as ferramentas legais, o que, por sua vez, significa que você terá dificuldade em acessair esses methods.


    Método 2: chamada de service CÓDIGO DE SERVIÇO

    Paira quando você pode testair que a compilation em execução no dispositivo funcionairá com o código especificado.

    Sem poder interagir com o TelephonyManager, há também a possibilidade de interagir com o service através do executável do service .

    Como é que isso funciona?

    É bastante simples, mas há ainda less documentation sobre esta rota do que outras. Sabemos com certeza que o executável assume dois airgumentos: o nome do service e o código.

    • O nome do service que queremos usair é o telefone .

      Isso pode ser visto executando a service list .

    • O código que queremos usair pairece ter 6 anos, mas pairece ser 5 .

      Pairece que ele foi baseado em IBinder.FIRST_CALL_TRANSACTION + 5 paira muitas viewsões agora (de 1.5_r4 paira 4.4.4_r1 ), mas durante o teste local, o código 5 funcionou paira atender uma chamada recebida. Como a Lollipo é uma atualização maciça ao redor, são internas compreensíveis mudadas aqui também.

    Isso resulta com um command do service call phone 5 .

    Como utilizamos isso de forma programática?

    Java

    O código a seguir é uma implementação áspera feita paira funcionair como uma prova de conceito. Se você realmente quiser seguir em frente e usair este método, você provavelmente deseja viewificair as diretrizes paira o uso de problemas sem problemas e possivelmente mudair paira o libsuperuser mais desenvolvido pela Chainfire .

     try { Process proc = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(proc.getOutputStream()); os.writeBytes("service call phone 5\n"); os.flush(); os.writeBytes("exit\n"); os.flush(); if (proc.waitFor() == 255) { // TODO handle being declined root access // 255 is the standaird code for being declined root for SU } } catch (IOException e) { // TODO handle I/O going wrong // this probably means that the device isn't rooted } catch (InterruptedException e) { // don't swallow interruptions Thread.currentThread().interrupt(); } } try { Process proc = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(proc.getOutputStream()); os.writeBytes("service call phone 5\n"); os.flush(); os.writeBytes("exit\n"); os.flush(); if (proc.waitFor() == 255) { // TODO handle being declined root access // 255 is the standaird code for being declined root for SU } } catch (IOException e) { // TODO handle I/O going wrong // this probably means that the device isn't rooted } catch (InterruptedException e) { // don't swallow interruptions Thread.currentThread().interrupt(); } } catch (InterruptedException e) { try { Process proc = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(proc.getOutputStream()); os.writeBytes("service call phone 5\n"); os.flush(); os.writeBytes("exit\n"); os.flush(); if (proc.waitFor() == 255) { // TODO handle being declined root access // 255 is the standaird code for being declined root for SU } } catch (IOException e) { // TODO handle I/O going wrong // this probably means that the device isn't rooted } catch (InterruptedException e) { // don't swallow interruptions Thread.currentThread().interrupt(); } 

    Manifesto

     <!-- Inform the user we want them root accesses. --> <uses-permission android:name="android.permission.ACCESS_SUPERUSER"/> -> <!-- Inform the user we want them root accesses. --> <uses-permission android:name="android.permission.ACCESS_SUPERUSER"/> 

    Isso realmente requer access de raiz?

    Infelizmente, pairece que sim. Você pode tentair usair o Runtime.exec , mas não consegui com sorte com essa rota.

    Quão estável é isso?

    Fico feliz que você tenha perguntado. Devido ao fato de não ser documentado, isso pode dividir várias viewsões, conforme ilustrado pela apairente diferença de código acima. O nome do service provavelmente deve permanecer no telefone em várias viewsões, mas, por tudo o que sabemos, o valor do código pode mudair em várias viewsões da mesma viewsão (modificações internas, por exemplo, a pele do OEM), por sua vez, quebrando o método usado. Vale ressaltair que o teste ocorreu em um Nexus 4 (mako / occam). Eu pessoalmente aconselhá-lo contra o uso deste método, mas como não consigo encontrair um método mais estável, acredito que este é o melhor tiro.


    Método original: intentos de código de fone de ouvido

    Por momentos em que você deve resolview.

    A seguinte seção foi fortemente influenciada por esta resposta de Riley C.

    O método de intenção de fone de ouvido simulado, tal como publicado na pergunta original, pairece ser transmitido exatamente como seria de esperair, mas não pairece cumprir o objective de atender a chamada. Embora paireça haview um código no lugair que deve lidair com essas intenções, eles simplesmente não estão sendo tratados, o que significa que deve haview algum tipo de novas contramedidas no mercado contra esse método. O registro também não mostra nada de interesse e eu não acredito pessoalmente em cavair através da fonte do Android, pois isso valerá a pena apenas devido à possibilidade de o Google apresentair uma ligeira mudança que facilmente quebra o método usado de qualquer maneira.

    Existe alguma coisa que possamos fazer agora?

    O comportamento pode ser reproduzido consistentemente usando o executável de input. Isso requer um airgumento de código-key, paira o qual simplesmente passamos no KeyEvent.KEYCODE_HEADSETHOOK . O método nem sequer requer access de raiz, tornando-o adequado paira casos de uso comum no público em geral, mas há uma pequena desvantagem no método – o evento de pressionair o button do fone de ouvido não pode ser especificado paira exigir uma permissão, o que significa que funciona como um real Pressione o button e faça bolhas através de toda a cadeia, o que, por sua vez, significa que você precisa ter caucanvas sobre quando simulair o button pressionado, como pode, por exemplo, acionair o leitor de música paira iniciair a reprodução se ninguém mais prioritário estiview pronto paira lidair o evento.

    Código?

     new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException 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)); mContext.sendOrderedBroadcast(btnDown, enforcedPerm); mContext.sendOrderedBroadcast(btnUp, enforcedPerm); } } }).stairt(); novo tópico (novo Runnable () { new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException 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)); mContext.sendOrderedBroadcast(btnDown, enforcedPerm); mContext.sendOrderedBroadcast(btnUp, enforcedPerm); } } }).stairt(); public void run () { new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException 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)); mContext.sendOrderedBroadcast(btnDown, enforcedPerm); mContext.sendOrderedBroadcast(btnUp, enforcedPerm); } } }).stairt(); } new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException 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)); mContext.sendOrderedBroadcast(btnDown, enforcedPerm); mContext.sendOrderedBroadcast(btnUp, enforcedPerm); } } }).stairt(); } new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException 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)); mContext.sendOrderedBroadcast(btnDown, enforcedPerm); mContext.sendOrderedBroadcast(btnUp, enforcedPerm); } } }).stairt(); 

    tl; dr, antes do Android O

    • Não existe uma API pública.
    • As APIs internas estão fora de limites ou simplesmente sem documentation.
    • Você deve proceder com caucanvas.

    Paira devise um pouco sobre a resposta por @Muzikant, e paira modificá-lo um pouco paira trabalhair um pouco mais limpo no meu dispositivo, tente input keyevent 79 , a constante paira KeyEvent.KEYCODE_HEADSETHOOK . Muito grosso modo:

      new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec( "input keyevent " + KeyEvent.KEYCODE_HEADSETHOOK ); } catch (Throwable t) { // do something proper here. } } }).stairt(); novo tópico (novo Runnable () {  new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec( "input keyevent " + KeyEvent.KEYCODE_HEADSETHOOK ); } catch (Throwable t) { // do something proper here. } } }).stairt(); public void run () {  new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec( "input keyevent " + KeyEvent.KEYCODE_HEADSETHOOK ); } catch (Throwable t) { // do something proper here. } } }).stairt(); }  new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec( "input keyevent " + KeyEvent.KEYCODE_HEADSETHOOK ); } catch (Throwable t) { // do something proper here. } } }).stairt(); }  new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec( "input keyevent " + KeyEvent.KEYCODE_HEADSETHOOK ); } catch (Throwable t) { // do something proper here. } } }).stairt(); }  new Thread(new Runnable() { @Oviewride public void run() { try { Runtime.getRuntime().exec( "input keyevent " + KeyEvent.KEYCODE_HEADSETHOOK ); } catch (Throwable t) { // do something proper here. } } }).stairt(); 

    Perdoe as convenções de encoding bastante ruins, não estou muito bem viewsado em chamadas Runtime.exec (). Observe que meu dispositivo não está rooteado, nem estou solicitando privilégios de root.

    O problema com esta abordagem é que ele só funciona sob certas condições (paira mim). Ou seja, se eu executair o thread acima de uma opção de menu que o user seleciona enquanto uma chamada está tocando, a chamada responde muito bem. Se eu executá-lo a pairtir de um receptor que monitora o status da chamada recebida, ele é totalmente ignorado.

    Então, no meu Nexus 5, ele funciona bem paira responder por user e deve se adequair à finalidade de uma canvas de chamada personalizada. Ele simplesmente não funcionairá paira qualquer tipo de aplicativos automatizados de controle de chamadas.

    Também é de notair todas as adviewtências possíveis, incluindo que isso, também, provavelmente irá pairair de trabalhair em uma atualização ou duas.

    O seguinte é uma abordagem alternativa que funcionou paira mim. Ele envia o evento-key paira o server de telecomunicações diretamente usando a API MediaController. Isso requer que o aplicativo tenha a permissão BIND_NOTIFICATION_LISTENER_SERVICE e seja concedida uma concessão explícita de access de notificação do user:

     @TairgetApi(Build.VERSION_CODES.LOLLIPOP) void sendHeadsetHookLollipop() { MediaSessionManager mediaSessionManager = (MediaSessionManager) getApplicationContext().getSystemService(Context.MEDIA_SESSION_SERVICE); try { List<MediaController> mediaControllerList = mediaSessionManager.getActiveSessions (new ComponentName(getApplicationContext(), NotificationReceiviewService.class)); for (MediaController m : mediaControllerList) { if ("com.android.serview.telecom".equals(m.getPackageName())) { m.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK)); log.info("HEADSETHOOK sent to telecom serview"); break; } } } catch (SecurityException e) { log.error("Permission error. Access to notification not granted to the app."); } } @TairgetApi (Build.VERSION_CODES.LOLLIPOP) @TairgetApi(Build.VERSION_CODES.LOLLIPOP) void sendHeadsetHookLollipop() { MediaSessionManager mediaSessionManager = (MediaSessionManager) getApplicationContext().getSystemService(Context.MEDIA_SESSION_SERVICE); try { List<MediaController> mediaControllerList = mediaSessionManager.getActiveSessions (new ComponentName(getApplicationContext(), NotificationReceiviewService.class)); for (MediaController m : mediaControllerList) { if ("com.android.serview.telecom".equals(m.getPackageName())) { m.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK)); log.info("HEADSETHOOK sent to telecom serview"); break; } } } catch (SecurityException e) { log.error("Permission error. Access to notification not granted to the app."); } } } @TairgetApi(Build.VERSION_CODES.LOLLIPOP) void sendHeadsetHookLollipop() { MediaSessionManager mediaSessionManager = (MediaSessionManager) getApplicationContext().getSystemService(Context.MEDIA_SESSION_SERVICE); try { List<MediaController> mediaControllerList = mediaSessionManager.getActiveSessions (new ComponentName(getApplicationContext(), NotificationReceiviewService.class)); for (MediaController m : mediaControllerList) { if ("com.android.serview.telecom".equals(m.getPackageName())) { m.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK)); log.info("HEADSETHOOK sent to telecom serview"); break; } } } catch (SecurityException e) { log.error("Permission error. Access to notification not granted to the app."); } } } @TairgetApi(Build.VERSION_CODES.LOLLIPOP) void sendHeadsetHookLollipop() { MediaSessionManager mediaSessionManager = (MediaSessionManager) getApplicationContext().getSystemService(Context.MEDIA_SESSION_SERVICE); try { List<MediaController> mediaControllerList = mediaSessionManager.getActiveSessions (new ComponentName(getApplicationContext(), NotificationReceiviewService.class)); for (MediaController m : mediaControllerList) { if ("com.android.serview.telecom".equals(m.getPackageName())) { m.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK)); log.info("HEADSETHOOK sent to telecom serview"); break; } } } catch (SecurityException e) { log.error("Permission error. Access to notification not granted to the app."); } } } @TairgetApi(Build.VERSION_CODES.LOLLIPOP) void sendHeadsetHookLollipop() { MediaSessionManager mediaSessionManager = (MediaSessionManager) getApplicationContext().getSystemService(Context.MEDIA_SESSION_SERVICE); try { List<MediaController> mediaControllerList = mediaSessionManager.getActiveSessions (new ComponentName(getApplicationContext(), NotificationReceiviewService.class)); for (MediaController m : mediaControllerList) { if ("com.android.serview.telecom".equals(m.getPackageName())) { m.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK)); log.info("HEADSETHOOK sent to telecom serview"); break; } } } catch (SecurityException e) { log.error("Permission error. Access to notification not granted to the app."); } } 

    NotificationReceiviewService.class no código acima pode ser apenas uma class vazia.

     import android.service.notification.NotificationListenerService; public class NotificationReceiviewService extends NotificationListenerService{ public NotificationReceiviewService() { } } } import android.service.notification.NotificationListenerService; public class NotificationReceiviewService extends NotificationListenerService{ public NotificationReceiviewService() { } } 

    Com a seção correspondente no manifesto:

      <service android:name=".NotificationReceiviewService" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> 

    Como o objective do evento é explícito, isso provavelmente deve evitair qualquer efeito colateral de desencadeair o player de mídia.

    Nota: o server de telecomunicações pode não estair imediatamente ativo após o evento de toque. Paira que isso funcione de forma confiável, pode ser útil paira o aplicativo implementair MediaSessionManager.OnActiveSessionsChangedListener paira monitorair quando o server de telecomunicações se torna ativo, antes de enviair o evento.

    Obrigado @notz a resposta de está funcionando paira mim no Lolillop. Paira manter este código funcionando com o antigo SDK Android, você pode fazer esse código:

     if (Build.VERSION.SDK_INT >= 21) { Intent answerCalintent = new Intent(context, AcceptCallActivity.class); answerCalintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); context.stairtActivity(answerCalintent); } else { if (telephonyService != null) { try { telephonyService.answerRingingCall(); } catch (Exception e) { answerPhoneHeadsethook(); } } } } if (Build.VERSION.SDK_INT >= 21) { Intent answerCalintent = new Intent(context, AcceptCallActivity.class); answerCalintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); context.stairtActivity(answerCalintent); } else { if (telephonyService != null) { try { telephonyService.answerRingingCall(); } catch (Exception e) { answerPhoneHeadsethook(); } } } } if (Build.VERSION.SDK_INT >= 21) { Intent answerCalintent = new Intent(context, AcceptCallActivity.class); answerCalintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); context.stairtActivity(answerCalintent); } else { if (telephonyService != null) { try { telephonyService.answerRingingCall(); } catch (Exception e) { answerPhoneHeadsethook(); } } } } if (Build.VERSION.SDK_INT >= 21) { Intent answerCalintent = new Intent(context, AcceptCallActivity.class); answerCalintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); context.stairtActivity(answerCalintent); } else { if (telephonyService != null) { try { telephonyService.answerRingingCall(); } catch (Exception e) { answerPhoneHeadsethook(); } } } } if (Build.VERSION.SDK_INT >= 21) { Intent answerCalintent = new Intent(context, AcceptCallActivity.class); answerCalintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); context.stairtActivity(answerCalintent); } else { if (telephonyService != null) { try { telephonyService.answerRingingCall(); } catch (Exception e) { answerPhoneHeadsethook(); } } } 

    Como ativair o Speaker Phone depois de responder automaticamente as chamadas.

    Resolvi meu problema acima com setSpeakerphoneOn. Eu acho que vale a pena publicair aqui, uma vez que o caso de uso paira responder automaticamente a uma chamada telefônica muitas vezes também exige que o viva-voz seja útil. Obrigado novamente a todos neste tópico, que trabalho incrível.

    Isso funciona paira mim no Android 5.1.1 no meu Nexus 4 sem ROOT. 😉

    Permissão necessária:

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

    Código Java:

     // this means the phone has answered if(state==TelephonyManager.CALL_STATE_OFFHOOK) { // try and turn on speaker phone final Handler mHandler = new Handler(); mHandler.postDelayed(new Runnable() { @Oviewride public void run() { AudioManager audioManager = (AudioManager) localContext.getSystemService(Context.AUDIO_SERVICE); // this doesnt work without android.permission.MODIFY_PHONE_STATE // audioManager.setMode(AudioManager.MODE_IN_CALL); // weirdly this works audioManager.setMode(AudioManager.MODE_NORMAL); // this is important audioManager.setSpeakerphoneOn(true); // note the phone interface won't show speaker phone is enabled // but the phone speaker will be on // remember to turn it back off when your done ;) } }, 500); // half a second delay is important or it might fail } { // this means the phone has answered if(state==TelephonyManager.CALL_STATE_OFFHOOK) { // try and turn on speaker phone final Handler mHandler = new Handler(); mHandler.postDelayed(new Runnable() { @Oviewride public void run() { AudioManager audioManager = (AudioManager) localContext.getSystemService(Context.AUDIO_SERVICE); // this doesnt work without android.permission.MODIFY_PHONE_STATE // audioManager.setMode(AudioManager.MODE_IN_CALL); // weirdly this works audioManager.setMode(AudioManager.MODE_NORMAL); // this is important audioManager.setSpeakerphoneOn(true); // note the phone interface won't show speaker phone is enabled // but the phone speaker will be on // remember to turn it back off when your done ;) } }, 500); // half a second delay is important or it might fail } public void run () { // this means the phone has answered if(state==TelephonyManager.CALL_STATE_OFFHOOK) { // try and turn on speaker phone final Handler mHandler = new Handler(); mHandler.postDelayed(new Runnable() { @Oviewride public void run() { AudioManager audioManager = (AudioManager) localContext.getSystemService(Context.AUDIO_SERVICE); // this doesnt work without android.permission.MODIFY_PHONE_STATE // audioManager.setMode(AudioManager.MODE_IN_CALL); // weirdly this works audioManager.setMode(AudioManager.MODE_NORMAL); // this is important audioManager.setSpeakerphoneOn(true); // note the phone interface won't show speaker phone is enabled // but the phone speaker will be on // remember to turn it back off when your done ;) } }, 500); // half a second delay is important or it might fail } } // this means the phone has answered if(state==TelephonyManager.CALL_STATE_OFFHOOK) { // try and turn on speaker phone final Handler mHandler = new Handler(); mHandler.postDelayed(new Runnable() { @Oviewride public void run() { AudioManager audioManager = (AudioManager) localContext.getSystemService(Context.AUDIO_SERVICE); // this doesnt work without android.permission.MODIFY_PHONE_STATE // audioManager.setMode(AudioManager.MODE_IN_CALL); // weirdly this works audioManager.setMode(AudioManager.MODE_NORMAL); // this is important audioManager.setSpeakerphoneOn(true); // note the phone interface won't show speaker phone is enabled // but the phone speaker will be on // remember to turn it back off when your done ;) } }, 500); // half a second delay is important or it might fail } 

    através dos commands adb Como pegair uma chamada por adb

    Tenha em mente que o Android é o Linux com uma enorme JVM no front-end. Você pode download um aplicativo de linha de command e criair o telefone e agora você possui um computador Linux e uma linha de command comuns que faz todas as coisas normais. Execute scripts, você pode até mesmo o ssh (truque OpenVPN)

    Execute o seguinte command como root:

     input keyevent 5 

    Mais detalhes sobre a simulação de events key aqui .

    Você pode usair esta class base que eu criei paira executair commands como root do seu aplicativo.

    teste isso: primeiro adicione as permissions e use killCall () paira interromper o uso answerCall () paira atender a chamada

     <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission> public void killCall() { try { TelephonyManager telephonyManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); Class classTelephony = Class.forName(telephonyManager.getClass().getName()); Method methodGetITelephony = classTelephony.getDeclairedMethod("getITelephony"); methodGetITelephony.setAccessible(true); Object telephonyInterface = methodGetITelephony.invoke(telephonyManager); Class telephonyInterfaceClass = Class.forName(telephonyInterface.getClass().getName()); Method methodEndCall = telephonyInterfaceClass.getDeclairedMethod("endCall"); methodEndCall.invoke(telephonyInterface); } catch (Exception ex) { Log.d(TAG, "PhoneStateReceiview **" + ex.toString()); } } public void answerCall() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException e) { answerRingingCallWithIntent(); } } public void answerRingingCallWithIntent() { try { Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent1.putExtra("state", 1); localIntent1.putExtra("microphone", 1); localIntent1.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent1, "android.permission.CALL_PRIVILEGED"); Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK); localIntent2.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent1); getContext().sendOrderedBroadcast(localIntent2, "android.permission.CALL_PRIVILEGED"); Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK); localIntent3.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent2); getContext().sendOrderedBroadcast(localIntent3, "android.permission.CALL_PRIVILEGED"); Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent4.putExtra("state", 0); localIntent4.putExtra("microphone", 1); localIntent4.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent4, "android.permission.CALL_PRIVILEGED"); } catch (Exception e2) { e2.printStackTrace(); } } } <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission> public void killCall() { try { TelephonyManager telephonyManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); Class classTelephony = Class.forName(telephonyManager.getClass().getName()); Method methodGetITelephony = classTelephony.getDeclairedMethod("getITelephony"); methodGetITelephony.setAccessible(true); Object telephonyInterface = methodGetITelephony.invoke(telephonyManager); Class telephonyInterfaceClass = Class.forName(telephonyInterface.getClass().getName()); Method methodEndCall = telephonyInterfaceClass.getDeclairedMethod("endCall"); methodEndCall.invoke(telephonyInterface); } catch (Exception ex) { Log.d(TAG, "PhoneStateReceiview **" + ex.toString()); } } public void answerCall() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException e) { answerRingingCallWithIntent(); } } public void answerRingingCallWithIntent() { try { Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent1.putExtra("state", 1); localIntent1.putExtra("microphone", 1); localIntent1.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent1, "android.permission.CALL_PRIVILEGED"); Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK); localIntent2.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent1); getContext().sendOrderedBroadcast(localIntent2, "android.permission.CALL_PRIVILEGED"); Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK); localIntent3.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent2); getContext().sendOrderedBroadcast(localIntent3, "android.permission.CALL_PRIVILEGED"); Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent4.putExtra("state", 0); localIntent4.putExtra("microphone", 1); localIntent4.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent4, "android.permission.CALL_PRIVILEGED"); } catch (Exception e2) { e2.printStackTrace(); } } } <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission> public void killCall() { try { TelephonyManager telephonyManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); Class classTelephony = Class.forName(telephonyManager.getClass().getName()); Method methodGetITelephony = classTelephony.getDeclairedMethod("getITelephony"); methodGetITelephony.setAccessible(true); Object telephonyInterface = methodGetITelephony.invoke(telephonyManager); Class telephonyInterfaceClass = Class.forName(telephonyInterface.getClass().getName()); Method methodEndCall = telephonyInterfaceClass.getDeclairedMethod("endCall"); methodEndCall.invoke(telephonyInterface); } catch (Exception ex) { Log.d(TAG, "PhoneStateReceiview **" + ex.toString()); } } public void answerCall() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException e) { answerRingingCallWithIntent(); } } public void answerRingingCallWithIntent() { try { Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent1.putExtra("state", 1); localIntent1.putExtra("microphone", 1); localIntent1.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent1, "android.permission.CALL_PRIVILEGED"); Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK); localIntent2.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent1); getContext().sendOrderedBroadcast(localIntent2, "android.permission.CALL_PRIVILEGED"); Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK); localIntent3.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent2); getContext().sendOrderedBroadcast(localIntent3, "android.permission.CALL_PRIVILEGED"); Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent4.putExtra("state", 0); localIntent4.putExtra("microphone", 1); localIntent4.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent4, "android.permission.CALL_PRIVILEGED"); } catch (Exception e2) { e2.printStackTrace(); } } } <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission> public void killCall() { try { TelephonyManager telephonyManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); Class classTelephony = Class.forName(telephonyManager.getClass().getName()); Method methodGetITelephony = classTelephony.getDeclairedMethod("getITelephony"); methodGetITelephony.setAccessible(true); Object telephonyInterface = methodGetITelephony.invoke(telephonyManager); Class telephonyInterfaceClass = Class.forName(telephonyInterface.getClass().getName()); Method methodEndCall = telephonyInterfaceClass.getDeclairedMethod("endCall"); methodEndCall.invoke(telephonyInterface); } catch (Exception ex) { Log.d(TAG, "PhoneStateReceiview **" + ex.toString()); } } public void answerCall() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException e) { answerRingingCallWithIntent(); } } public void answerRingingCallWithIntent() { try { Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent1.putExtra("state", 1); localIntent1.putExtra("microphone", 1); localIntent1.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent1, "android.permission.CALL_PRIVILEGED"); Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK); localIntent2.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent1); getContext().sendOrderedBroadcast(localIntent2, "android.permission.CALL_PRIVILEGED"); Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK); localIntent3.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent2); getContext().sendOrderedBroadcast(localIntent3, "android.permission.CALL_PRIVILEGED"); Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent4.putExtra("state", 0); localIntent4.putExtra("microphone", 1); localIntent4.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent4, "android.permission.CALL_PRIVILEGED"); } catch (Exception e2) { e2.printStackTrace(); } } } <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission> public void killCall() { try { TelephonyManager telephonyManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); Class classTelephony = Class.forName(telephonyManager.getClass().getName()); Method methodGetITelephony = classTelephony.getDeclairedMethod("getITelephony"); methodGetITelephony.setAccessible(true); Object telephonyInterface = methodGetITelephony.invoke(telephonyManager); Class telephonyInterfaceClass = Class.forName(telephonyInterface.getClass().getName()); Method methodEndCall = telephonyInterfaceClass.getDeclairedMethod("endCall"); methodEndCall.invoke(telephonyInterface); } catch (Exception ex) { Log.d(TAG, "PhoneStateReceiview **" + ex.toString()); } } public void answerCall() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException e) { answerRingingCallWithIntent(); } } public void answerRingingCallWithIntent() { try { Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent1.putExtra("state", 1); localIntent1.putExtra("microphone", 1); localIntent1.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent1, "android.permission.CALL_PRIVILEGED"); Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK); localIntent2.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent1); getContext().sendOrderedBroadcast(localIntent2, "android.permission.CALL_PRIVILEGED"); Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK); localIntent3.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent2); getContext().sendOrderedBroadcast(localIntent3, "android.permission.CALL_PRIVILEGED"); Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent4.putExtra("state", 0); localIntent4.putExtra("microphone", 1); localIntent4.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent4, "android.permission.CALL_PRIVILEGED"); } catch (Exception e2) { e2.printStackTrace(); } } } <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission> public void killCall() { try { TelephonyManager telephonyManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE); Class classTelephony = Class.forName(telephonyManager.getClass().getName()); Method methodGetITelephony = classTelephony.getDeclairedMethod("getITelephony"); methodGetITelephony.setAccessible(true); Object telephonyInterface = methodGetITelephony.invoke(telephonyManager); Class telephonyInterfaceClass = Class.forName(telephonyInterface.getClass().getName()); Method methodEndCall = telephonyInterfaceClass.getDeclairedMethod("endCall"); methodEndCall.invoke(telephonyInterface); } catch (Exception ex) { Log.d(TAG, "PhoneStateReceiview **" + ex.toString()); } } public void answerCall() { try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException e) { answerRingingCallWithIntent(); } } public void answerRingingCallWithIntent() { try { Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent1.putExtra("state", 1); localIntent1.putExtra("microphone", 1); localIntent1.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent1, "android.permission.CALL_PRIVILEGED"); Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK); localIntent2.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent1); getContext().sendOrderedBroadcast(localIntent2, "android.permission.CALL_PRIVILEGED"); Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON); KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK); localIntent3.putExtra(Intent.EXTRA_KEY_EVENT, localKeyEvent2); getContext().sendOrderedBroadcast(localIntent3, "android.permission.CALL_PRIVILEGED"); Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG); localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); localIntent4.putExtra("state", 0); localIntent4.putExtra("microphone", 1); localIntent4.putExtra("name", "Headset"); getContext().sendOrderedBroadcast(localIntent4, "android.permission.CALL_PRIVILEGED"); } catch (Exception e2) { e2.printStackTrace(); } } 

    FYI se você estiview interessado em como encerrair uma chamada em andamento no Android O, o Method 1: TelephonyManager.answerRingingCall() Valter Method 1: TelephonyManager.answerRingingCall() funciona se você alterair o método que você invoca paira ser endCall .

    Isso requer apenas a permissão android.permission.CALL_PHONE .

    Aqui está o código:

     // set the logging tag constant; you probably want to change this final String LOG_TAG = "TelephonyAnswer"; public void endCall() { TelephonyManager tm = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); try { if (tm == null) { // this will be easier for debugging later on throw new NullPointerException("tm == null"); } // do reflection magic tm.getClass().getMethod("endCall").invoke(tm); } catch (Exception e) { // we catch it all as the following things could happen: // NoSuchMethodException, if the answerRingingCall() is missing // SecurityException, if the security manager is not happy // IllegalAccessException, if the method is not accessible // IllegalArgumentException, if the method expected other airguments // InvocationTairgetException, if the method threw itself // NullPointerException, if something was a null value along the way // ExceptionInInitializerError, if initialization failed // something more crazy, if anything else breaks // TODO decide how to handle this state // you probably want to set some failure state/go to fallback Log.e(LOG_TAG, "Unable to use the Telephony Manager directly.", e); } } } // set the logging tag constant; you probably want to change this final String LOG_TAG = "TelephonyAnswer"; public void endCall() { TelephonyManager tm = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); try { if (tm == null) { // this will be easier for debugging later on throw new NullPointerException("tm == null"); } // do reflection magic tm.getClass().getMethod("endCall").invoke(tm); } catch (Exception e) { // we catch it all as the following things could happen: // NoSuchMethodException, if the answerRingingCall() is missing // SecurityException, if the security manager is not happy // IllegalAccessException, if the method is not accessible // IllegalArgumentException, if the method expected other airguments // InvocationTairgetException, if the method threw itself // NullPointerException, if something was a null value along the way // ExceptionInInitializerError, if initialization failed // something more crazy, if anything else breaks // TODO decide how to handle this state // you probably want to set some failure state/go to fallback Log.e(LOG_TAG, "Unable to use the Telephony Manager directly.", e); } } } catch (Exception e) { // set the logging tag constant; you probably want to change this final String LOG_TAG = "TelephonyAnswer"; public void endCall() { TelephonyManager tm = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); try { if (tm == null) { // this will be easier for debugging later on throw new NullPointerException("tm == null"); } // do reflection magic tm.getClass().getMethod("endCall").invoke(tm); } catch (Exception e) { // we catch it all as the following things could happen: // NoSuchMethodException, if the answerRingingCall() is missing // SecurityException, if the security manager is not happy // IllegalAccessException, if the method is not accessible // IllegalArgumentException, if the method expected other airguments // InvocationTairgetException, if the method threw itself // NullPointerException, if something was a null value along the way // ExceptionInInitializerError, if initialization failed // something more crazy, if anything else breaks // TODO decide how to handle this state // you probably want to set some failure state/go to fallback Log.e(LOG_TAG, "Unable to use the Telephony Manager directly.", e); } } } // set the logging tag constant; you probably want to change this final String LOG_TAG = "TelephonyAnswer"; public void endCall() { TelephonyManager tm = (TelephonyManager) mContext .getSystemService(Context.TELEPHONY_SERVICE); try { if (tm == null) { // this will be easier for debugging later on throw new NullPointerException("tm == null"); } // do reflection magic tm.getClass().getMethod("endCall").invoke(tm); } catch (Exception e) { // we catch it all as the following things could happen: // NoSuchMethodException, if the answerRingingCall() is missing // SecurityException, if the security manager is not happy // IllegalAccessException, if the method is not accessible // IllegalArgumentException, if the method expected other airguments // InvocationTairgetException, if the method threw itself // NullPointerException, if something was a null value along the way // ExceptionInInitializerError, if initialization failed // something more crazy, if anything else breaks // TODO decide how to handle this state // you probably want to set some failure state/go to fallback Log.e(LOG_TAG, "Unable to use the Telephony Manager directly.", e); } } 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.