【问题标题】:How to programmatically answer/end a call in Android 4.1?如何在 Android 4.1 中以编程方式接听/结束通话?
【发布时间】:2013-03-18 16:11:11
【问题描述】:

我正在编写一个 Android 应用程序,我需要在其中接听来电,做一些工作,然后结束通话。 在谷歌搜索之后,我可以找到两种不同的方法来实现这一点,这两种方法都不适用于最新版本的 Android,特别是在 4.1 之后的 Jelly Bean。

I.) 在“android.intent.action.PHONE_STATE”的广播接收器中使用 Java 反射访问“com.android.internal.telephony.ITelephony”。下面的示例代码可以在数百篇相关帖子中找到:

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

这段代码的问题在于

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

需要此方法才能工作,并且此权限已从 android v 2.3 定义为“仅适用于系统应用程序”。简而言之,普通用户应用程序无法再在清单文件中定义此权限。

II.) 另一种方法是模拟推送耳机挂钩,使 Android 接听电话。这是通过广播“Intent.ACTION_MEDIA_BUTTON”来完成的,如下面的代码所示。

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

此方法在 Android 4.1 之前有效,之后 android 已限制用户应用广播“Intent.ACTION_MEDIA_BUTTON”。

所以我的结论是,目前我们无法在 Android 4.1 或更高版本中实现这一点。

还有其他人找到解决此问题的任何其他解决方案或解决方法吗?

【问题讨论】:

  • 答案是谷歌不希望你这样做。这就是为什么他们要阻止找到的所有方法。即使您找到第三种方法,我希望它在下一个版本的操作系统上也无法使用。
  • 显然 Google 已将这些功能限制为一项安全措施。我知道应该禁止从用户应用程序拨打新电话,但为什么要限制应用程序接听来电。因此,用户一定是缺少 Android 上的呼叫限制或本地应答机,不是吗?
  • @Gabe Sechan 您在哪里找到了 Google 阻止这些活动的信息?我有兴趣阅读官方的文字
  • 人们使用的所有方法都在下一个版本中被关闭。

标签: android telephony


【解决方案1】:

这适用于 Android 2.2 到 4.0,现在在将 try catch 添加到最后一行后,它适用于 4.1.2 和 4.2 坦率地说不知道它是如何工作的,但它适用于我。

Log.d(tag, "InSecond Method Ans Call");
// 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));
sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");

Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
headSetUnPluggedintent.putExtra("state", 0);
headSetUnPluggedintent.putExtra("name", "Headset");
try {
    sendOrderedBroadcast(headSetUnPluggedintent, null);
} catch (Exception e) { 
    e.printStackTrace();
}

这适用于我在 Android 4.1.2 以及我在 4.2 上测试过 这仍然会给出一个已处理的异常。

编辑结束通话

希望这可以帮助所有寻找接听和挂断整体解决方案的人。

/**
 * Reject button click listener will reject the incoming call.
 */
private class RejectCallOnClickListener implements OnClickListener {
    @Override
    public void onClick(View v) {
        Log.d(tag, "OnRejectButton: " + "Reject OnClick");
        ignoreCall();
        exitCleanly();
    }
}

/**
 * ignore incoming calls
 */
private void ignoreCall() {
    if (USE_ITELEPHONY)
        ignoreCallAidl();
    else
        ignoreCallPackageRestart();
}
/**
 * AIDL/ITelephony technique for ignoring calls
 */
private void ignoreCallAidl() {
    try {
        // telephonyService.silenceRinger();

        telephonyService.endCall();
    } catch (RemoteException e) {
        e.printStackTrace();
        Log.d(tag, "ignoreCall: " + "Error: " + e.getMessage());

    } catch (Exception e) {
        e.printStackTrace();
        Log.d(tag, "ignoreCall" + "Error: " + e.getMessage());

    }
}
/**
 * package restart technique for ignoring calls
 */
private void ignoreCallPackageRestart() {
    ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    am.restartPackage("com.android.providers.telephony");
    am.restartPackage("com.android.phone");
}
/**
 * cleanup and exit routine
 */
private void exitCleanly() {
    unHookReceiver();
    this.finish();

}

【讨论】:

  • 我已经使用了 VirtualModelz APP 中的代码您可以检查正在运行的应用程序 VirtualModelz,如果您希望我可以分享市场链接,它适用于 2.2 和 4.1.2。它肯定有效。
  • @ PravinDodia 谁能帮助我我需要一个工作版本,可以使用任何技术结束来自特定号码的呼叫。我需要 2.3.3+ 设备上的工作版本你能帮我吗?
  • @Pro_Zeck 您是否试图从您自己的活动(屏幕)中结束通话。 ?如果是,那么让我看看 4.1.2 操作系统可以做什么,因为它们不允许从不在系统中的任何活动中执行此操作。
  • @pravinDodia 是的,我正在创建一个名为黑名单的列表,我想阻止其号码,并且我想要你的这个功能,你似乎已经解决了它。你能在 Skype 上通话吗 (aftab_sikander)
  • am.restartPackage() 已弃用 - 它是 killBackgroundProcess(String) 的包装器,系统将负责适当地重新启动服务。所以 ignoreCallPackageRestart() 里面的代码应该是 am.killBackgroundProcesses("com.android.providers.telephony"); am.killBackgroundProcesses("com.android.phone");
【解决方案2】:

我的应用程序已经使用以下代码接听电话大约 6 个月了:

Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP,
            KeyEvent.KEYCODE_HEADSETHOOK));
context.sendOrderedBroadcast(i, null);

我已经在 2.2 到 4.2.2 的 Android 版本上对此进行了测试。我在 4.2.2 设备上的测试中没有看到 SecurityException 广播“Intent.ACTION_MEDIA_BUTTON”,也没有看到来自 Play 商店的崩溃报告表明正在发生此类异常。

我会说这并不总是有效。它不适用于 HTC 设备,因为 HTC 设备有一个 HeadsetObeserver 来监听有线耳机的实际插入。如果没有此事件(目前它是第三方应用程序要广播的 SecurityException),则 HeadsetHook KeyEvent 将被忽略。

之前的答案具有误导性。下面的代码块什么都不做:

Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
headSetUnPluggedintent.putExtra("state", 0);
headSetUnPluggedintent.putExtra("name", "Headset");
try {
    sendOrderedBroadcast(headSetUnPluggedintent, null);
} catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

except 生成一个 SecurityException 并捕获它。

在代码工作的其他答案中,这是因为 KeyEvent.KEYCODE_HEADSETHOOK 正在广播。

【讨论】:

    【解决方案3】:

    试试这个 以编程方式接听结束通话。它对我来说工作正常。

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

    【讨论】:

    【解决方案4】:

    作为此线程的结论,这里是适用于 Android 4.2.2 的代码。

    --> 如@PravinDodia 在上面的线程中提到的,通过模拟耳机挂钩的推送并将广播保持在 try-catch 中来应答呼叫。 (观察到在 catch 中抛出并处理了一个异常,无论如何调用都会得到响应。所以我想我们可以忽略这个异常并继续生活,就像什么都没发生一样!)

    --> 使用 ITelephony 断开呼叫。

    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;
         else {
             String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
    
             if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                 answerPhoneHeadsethook(context, intent);
                 return;
             }
             else if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
                 Log.d(TAG, "CALL ANSWERED NOW!!");
                 try {
                        synchronized(this) {
                            Log.d(TAG, "Waiting for 10 sec ");
                            this.wait(10000);
                        }
                    }
                    catch(Exception e) {
                        Log.d(TAG, "Exception while waiting !!");
                        e.printStackTrace();
                    }
                 disconnectPhoneItelephony(context);
                 return;
             }
             else {
                 Log.d(TAG, "ALL DONE ...... !!");
             }
         }  
     }
    
     public void answerPhoneHeadsethook(Context context, Intent intent) {
         String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
         if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
             String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
             Log.d(TAG, "Incoming call from: " + number);
             Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);             
             buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
             try {
                 context.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");
                 Log.d(TAG, "ACTION_MEDIA_BUTTON broadcasted...");
             }
             catch (Exception e) {
                 Log.d(TAG, "Catch block of ACTION_MEDIA_BUTTON broadcast !");
             }
    
             Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
             headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
             headSetUnPluggedintent.putExtra("state", 1); // 0 = unplugged  1 = Headset with microphone 2 = Headset without microphone
             headSetUnPluggedintent.putExtra("name", "Headset");
             // TODO: Should we require a permission?
             try {
                 context.sendOrderedBroadcast(headSetUnPluggedintent, null);
                 Log.d(TAG, "ACTION_HEADSET_PLUG broadcasted ...");
             }
             catch (Exception e) {
                    // TODO Auto-generated catch block
                    //e.printStackTrace();
                    Log.d(TAG, "Catch block of ACTION_HEADSET_PLUG broadcast");
                    Log.d(TAG, "Call Answered From Catch Block !!");
             }
             Log.d(TAG, "Answered incoming call from: " + number);  
        }
        Log.d(TAG, "Call Answered using headsethook");
     }
    
     public static void disconnectPhoneItelephony(Context context) {
         ITelephony telephonyService;
         Log.v(TAG, "Now disconnecting using ITelephony....");
          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, "Disconnecting Call now...");
              //telephonyService.answerRingingCall();
              //telephonyService.endcall();
              Log.v(TAG, "Call disconnected...");
              telephonyService.endCall();
          } catch (Exception e) {
           e.printStackTrace();
           Log.e(TAG,
                   "FATAL ERROR: could not connect to telephony subsystem");
           Log.e(TAG, "Exception object: " + e);
          }
     }
    }
    

    至少断开功能有效,我们知道它是如何工作的。所以那些想要开发呼叫限制应用程序的人可以继续。 对于像我这样想接听电话的人,我想我们现在可以使用它,只希望它不会在下一个版本中停止工作。

    【讨论】:

      【解决方案5】:

      试试这个:

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

      AndroidManifest.xml 文件中添加权限为

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

      【讨论】:

      • 谁能确认这些解决方案是否适用于 4.4 kitkat?
      • 权限 MODIFY_PHONE_STATE 不适用于 Lollipop
      【解决方案6】:

      ITelephony 方法在 4.4 上不起作用,我发现耳机/媒体按钮方法仍然允许在挂断前响起相当长的铃声。

      这篇 chaps 博客文章展示了一种新方法,我在 4.4.2 Galaxy s4 和 HTC one mini 上进行了测试,该方法挂断速度更快,而且您也不会收到未接来电条目。

      http://aprogrammersday.blogspot.co.uk/2014/05/disconnect-block-drop-calls-android-4.html

      该技术使用如下运行时 exec,显然您可能需要为某些设备使用不同的编号。

      public class HangupPhoneCallReceiver extends BroadcastReceiver {
      
          @Override
          public void onReceive(Context context, Intent intent) {
      
              if (TelephonyManager.EXTRA_STATE_RINGING.equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE))) {
      
                  Executor eS = Executors.newSingleThreadExecutor();
                  eS.execute(new Runnable() {
                      @Override
                      public void run() {
                          Runtime runtime = Runtime.getRuntime();
                          try {
                              Log.d(TAG, "service call phone 5 \n");
                              runtime.exec("service call phone 5 \n");
                          } catch (Exception exc) {
                              Log.e(TAG, exc.getMessage());
                          }
                      }
                  });
      
                  return;
              }
          }
      }
      

      【讨论】:

      • 感谢 Chris 的推荐,请随时通过我的电子邮件博客(位于 gmail dot com 的 naeem.akram.malik)联系并讨论想法。
      • 它在 Nexus4/kitkat 上工作;这节省了我的时间。谢谢 chris 和 naeem。
      • 此解决方案与 android 4.X 完美配合,但不适用于 android 50 和 5.1。你有解决这个问题的办法吗?
      【解决方案7】:

      使用 IT Telephony 断开呼叫不适用于 Samsung S Duos 等某些设备。但是你仍然可以让铃声静音:)

      【讨论】:

      • S5 Duos/Lollipop:它确实有效(呼出或呼入都结束)。仅经过 SIM2 测试。
      【解决方案8】:

      在 9.0 之前的旧版本中结束通话 使用这个:

      TelephonyManager tm = (TelephonyManager)context.getSystemService(TELEPHONY_SERVICE);
      
      Method m1 = null;
      try {
          m1 = tm.getClass().getDeclaredMethod("getITelephony");
      } catch (NoSuchMethodException e) {
          e.printStackTrace();
      }
      m1.setAccessible(true);
      Object iTelephony = null;
      try {
          iTelephony = m1.invoke(tm);
      } catch (IllegalAccessException e) {
          e.printStackTrace();
      } catch (InvocationTargetException e) {
          e.printStackTrace();
      }
      
      Method m3 = null;
      try {
          m3 = iTelephony.getClass().getDeclaredMethod("endCall");
      } catch (NoSuchMethodException e) {
          e.printStackTrace();
      }
      
      try {
          m3.invoke(iTelephony);
      } catch (IllegalAccessException e) {
          e.printStackTrace();
      } catch (InvocationTargetException e) {
          e.printStackTrace();
      }
          
      

      & 表示馅饼

      TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
      if (telecomManager != null) {
          return telecomManager.endCall();
      }
      
      Make sure your compile SDK version is 28
      

      【讨论】:

        【解决方案9】:
        private void PhoneControl(int nControl) {
            if(nControl == PHONE_END_CALL) { // End call, all Android version
                try {
                    TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
                    if (telecomManager != null) {
                        telecomManager.endCall();
                    }
                }catch (Exception e) {}
                try {
                    TelephonyManager tm = (TelephonyManager) context.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(context.checkSelfPermission("android.permission.ANSWER_PHONE_CALLS") == PackageManager.PERMISSION_GRANTED) {
                            TelecomManager tm = (TelecomManager) context.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) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
                        if(mediaSessionManager != null) {
                            try {
                                List<MediaController> mediaControllerList = mediaSessionManager.getActiveSessions
                                        (new ComponentName(context, NotificationReceiverService.class));
        
                                for (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) {
        //                      Toast.makeText(instance, "sdfsdf123123"+e, Toast.LENGTH_LONG).show();
                                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.startActivity(answerCalintent);
                                /* Do Nothing */ }
                        }
        
        
        //                new Thread(new Runnable() {
        //
        //                    @Override
        //                    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));
        //
        //                             context.sendOrderedBroadcast(btnDown, enforcedPerm);
        //                             context.sendOrderedBroadcast(btnUp, enforcedPerm);
        //                         }
        //                     }
        //
        //                  }).start();
                    }
                    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) context.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 {
                                        context.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));
        
                            context.sendOrderedBroadcast(btnDown, enforcedPerm);
                            context.sendOrderedBroadcast(btnUp, enforcedPerm);
                        }
                    }
        //       }
            }
        }
            
        <!--Incoming call state Listen-->
            <uses-permission android:name="android.permission.READ_CONTACTS" />
            <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        
            <!--    Store Data in Device/Shared pref-->
            <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        
            <!--Get Incoming Number-->
            <uses-permission android:name="android.permission.READ_CALL_LOG" />
        
            <!--Answer call-->
            <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
            <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
            <uses-permission
                android:name="android.permission.MODIFY_PHONE_STATE"
                tools:ignore="ProtectedPermissions" />
        
        
            <!--End Calll-->
            <uses-permission android:name="android.permission.CALL_PHONE" />
        
            public class NotificationReceiverService extends NotificationListenerService {
                public NotificationReceiverService() {
                }
            }
        
        <service
            android:name=".notifications.NotificationReceiverService"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
        
            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
        </service>
        
        
        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 < 26 && Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1 )
        { // 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 = null;
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
                    intent2 = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
                }
                startActivity(intent2);
        
        
                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //Do something after 100ms
                        Intent intent=new Intent(MainActivity.this, Main2Activity.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
        
                    }
                }, 1000);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-02-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多