以编程方式接受Nougat中的呼叫

从一年开始,我一直在研究IOT产品,附带的应用程序运行正常。 现在我无法在更高版本的android中以编程方式接受调用。 function对产品非常重要。 任何帮助都非常感谢。

2016年11月安全补丁更新之前, Runtime.getRunTime.exec("Command")工作正常以编程方式接受调用。

 Runtime.getRuntime().exec("input keyevent " +Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); 

如何在Nougat版本的android中实现它。

寻找任何types的黑客。

我已经为增强function打开了一个post。

https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened&groupby=&sort=&id=231938

注意*如果您中的任何一方遇到同样的问题,请向Android Dev Team请求加入并提供规定以获得用户的运行时权限。 按照上面提到的URL来请求。

因为我也在研究物联网产品,这是我遇到的最大问题之一,但经过一些研究,我认为我find了解决这个问题的方法,或者你可以说一个简单的黑客。 我已经在几个版本的多个设备中测试了这个hack,并发现大多数设备都在响应。 只有三星设备没有响应,一些华为设备和一些Oppo设备也没有响应。(我还在寻找这些设备的东西)。

我注意到Android提供了访问通知的一个function。 您可以使用NotificationListenerService来读取通知并对其执行某些操作。 它提供了一些覆盖方法:

  onNotificationPosted() onNotificationRemoved() getActiveNotifications() 

……等

这是一个代码:创建一个扩展NotificationListenerService的服务

  class NLService extends NotificationListenerService { @Override public void onNotificationPosted(StatusBarNotification sbn) { .... } @Override public void onNotificationRemoved(StatusBarNotification sbn) { .... } 

在AndroidMenifest中,将此服务添加为:

       

这将允许您的应用程序读取收到的任何通知。

现在,这是主要代码:

在onNotificationPosted(StatusBarNotification sbn)中添加以下代码:

  @Override public void onNotificationPosted(StatusBarNotification sbn) { try { if (sbn.getNotification().actions != null) { for (Notification.Action action : sbn.getNotification().actions) { Log.e(TAG, "" + action.title); if (action.title.toString().equalsIgnoreCase("Answer")) { Log.e(TAG, "" + true); PendingIntent intent = action.actionIntent; try { intent.send(); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } } } } } catch (Exception e) { e.printStackTrace(); } } 

而已!

全部设置,运行应用程序和三星以外的设备,无论哪个显示来电通知,使用应答和拒绝/拒绝操作按钮,都可以接听电话。

要打开通知访问设置并允许您的应用程序读取通知,请使用:

  Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"); startActivity(intent); 

只需为此创建一个POC,让我知道它是如何工作的。

如果有帮助,请标记我的答案。

此外,如果您可以为三星设备提供相同的解决方案,请更新。

谢谢

它有点破解,你可以使用辅助function来接听电话。 要启用辅助function服务,您必须在设置 – 辅助function – 您的服务上启用您的服务。

首先,将typeWindowContentChanged添加到accessibilityEventTypes。

  

并使用事件或“显示的文本”或“内容描述”执行某些操作。

 @Override public void onAccessibilityEvent(AccessibilityEvent event) { // Do something with Click or Focused event final int eventType = event.getEventType(); String eventText = null; switch(eventType) { case AccessibilityEvent.TYPE_VIEW_CLICKED: eventText = "Focused: "; break; case AccessibilityEvent.TYPE_VIEW_FOCUSED: eventText = "Focused: "; break; } eventText = eventText + event.getContentDescription(); // Traverse all items in screen. // Do something with text. AccessibilityNodeInfo info = getRootInActiveWindow(); int index; int count = info.getChildCount(); AccessibilityNodeInfo child; for (index = 0; index < count; index++) { child = info.getChild(index); if (child.getText() != null) Log.d(TAG, "text: " + child.getText().toString() + " " + child.getContentDescription()); // perform Click //if (child.isClickable()); //child.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } 

是的,我知道这不是解决问题的优雅方式。 这是一种黑客行为。

要使用按钮接听电话,请在检测到来电时设置标志:

  if(state==TelephonyManager.CALL_STATE_RINGING){ shouldAnswerCallViaNotification = true; } else { shouldAnswerCallViaNotification = false; } 

现在,在NSLogService类中创建一个列表,

 static ArrayList statusBarNotifications; 

并在您的onNotificationPosted()中将StatusBarNotification添加到列表中,

  @Override public void onNotificationPosted(StatusBarNotification sbn) { if (HomeScreen.shouldAnswerCallViaNotification) { if (statusBarNotifications == null) { updateNotificationList(); } statusBarNotifications.add(sbn); } else { updateNotificationList(); } } public static ArrayList getAllNotifications() { return statusBarNotifications; } public static void updateNotificationList() { if (statusBarNotifications != null) statusBarNotifications = null; statusBarNotifications = new ArrayList(); } 

在HomeScreen中,单击Button按钮,调用performNotificationOperation(NLService.getAllNotifications());

这是这个方法的定义:

  private void performNotificationOperation(ArrayList activeNotifications) { if (activeNotifications.size()> 0) { main_Loop: for (StatusBarNotification notification : activeNotifications) { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (notification.getNotification().actions != null) { for (Notification.Action action : notification.getNotification().actions) { // Log.e(TAG, "" + action); Log.e(TAG, "" + action.title); if (action.title.toString().equalsIgnoreCase("Answer")) { Log.e(TAG, "" + true); PendingIntent intent = action.actionIntent; try { intent.send(); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } break main_Loop; } } } } } catch (Exception e) { e.printStackTrace(); } } } try { NLService.updateNotificationList(); } catch (Exception e) { e.printStackTrace(); } } 

根据“ Vishal Sharma ”的回答,我们可以动态获取动作按钮标题,以支持其他语言:

  @Override public void onNotificationPosted(StatusBarNotification sbn) { try { if (sbn.getNotification().actions != null) { Notification.Action[] notificationAction=sbn.getNotification().actions; //Log.e(G.TAG, "" +notificationAction + " =>"+notificationAction.length); String rejectTitle=""+notificationAction[0].title; String acceptTitle=""+notificationAction[1].title; for (Notification.Action action : notificationAction){ if (action.title.toString().equalsIgnoreCase(acceptTitle)) { PendingIntent intent = action.actionIntent; try { intent.send(); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } } } } } catch (Exception e) { e.printStackTrace(); } }