18

С одного года, я работал над продуктом IOT, и приложение, прилагаемое, работало нормально. Теперь я не могу принять вызов программно в более высоких версиях Android. Особенность очень важна для продукта. Любая помощь высоко ценится.Программный прием в Nougat

Перед обновлением исправления безопасности Ноябрь 2016 года, Runtime.getRunTime.exec("Command") работал нормально, чтобы принять вызов программно.

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

Как сделать это возможным в версии Nougat android.

Ищет любой вид взлома.

Я открыл нить для улучшений.

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-адрес для запроса.

+0

http://stackoverflow.com/q/40673922/5996106 .Same вопрос с не решение. –

+0

Автор вопроса связан с устройством не с версией. – AndroidHacker

+0

У вас есть это http://stackoverflow.com/a/27084305/5996106 –

ответ

0

Это своего рода хак, вы можете использовать accessibility service для получения звонка. Чтобы включить службу доступности, вы должны включить свою службу в настройке - Доступность - ваш сервис.

Во-первых, добавьте типWindowContentChanged для accessibilityEventTypes.

<accessibility-service 
    android:accessibilityEventTypes="typeViewClicked|typeViewFocused|typeViewScrolled|typeWindowContentChanged|typeWindowStateChanged" 
    android:packageNames="com.example.android.myFirstApp, com.example.android.mySecondApp" 
    android:accessibilityFeedbackType="feedbackSpoken" 
    android:notificationTimeout="100" 
    android:settingsActivity="com.example.android.apis.accessibility.TestBackActivity" 
    android:canRetrieveWindowContent="true" 
/> 

И что-то делать с событием или «отображаемым текстом» или «описанием содержимого».

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

Да, я знаю, что это не изящный способ решить вашу проблему. Это своего рода хак.

6

Поскольку я также работаю над продуктом IOT, это была одна из самых больших проблем, с которой я столкнулся, но после некоторых исследований я считаю, что нашел какое-то решение этой проблемы, или вы можете сказать, что это простой хак. Я протестировал этот хак в нескольких устройствах с несколькими версиями и обнаружил, что большинство устройств реагируют. Только устройства Samsung не отвечают, некоторые устройства Huawei и некоторые устройства Oppo также не отвечают (я все еще смотрю что-то для этих устройств).

Я заметил, что Android предоставляет одну из функций «Доступ к уведомлениям». Вы можете использовать NotificationListenerService, чтобы читать уведомления и выполнять некоторые действия над ними. предоставляет некоторые методы переопределения:

onNotificationPosted() 
    onNotificationRemoved() 
    getActiveNotifications() 

... и т.д.

Вот код: создать службу, которая проходит NotificationListenerService

class NLService extends NotificationListenerService { 

    @Override 
    public void onNotificationPosted(StatusBarNotification sbn) { 
     .... 
    } 

    @Override 
    public void onNotificationRemoved(StatusBarNotification sbn) { 
     .... 
    } 

В AndroidMenifest, добавьте эту услугу как:

<service 
     android:name=".NLService" 
     android:label="@string/app_name" 
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> 
     <intent-filter> 
      <action 
android:name="android.service.notification.NotificationListenerService" /> 
     </intent-filter> 
    </service> 

Этот wil l разрешайте вашему приложению читать полученные уведомления.

Теперь, вот основной код:

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

Thats это!

Все установлено. Запустите приложение и устройства, кроме Samsung, в зависимости от того, что отображает уведомление о входящем вызове с кнопками «Ответ» и «Отклонить/отменить действие», позволит вам ответить на вызов.

Чтобы открыть настройки уведомлений доступа и позволяя приложению читать уведомления, используйте:

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

Просто создайте POC для этого и дайте мне знать о том, как это работает.

Пожалуйста, отметьте мой ответ, если это поможет.

Кроме того, если вы можете предоставить некоторое решение для тех же устройств Samsung, пожалуйста, обновите их.

Благодаря

+0

работает безупречно на моем Samsung Note 2 Android v7.1.1! Благодаря ! – ProllyGeek

+0

отлично работает, но что, если я хочу ответить на него кнопкой? not autoAnswer – Eazyz

+0

Для этого можно использовать простой сценарий. Пожалуйста, просмотрите мой новый ответ. –

1

Для ответа на вызов с помощью кнопки, установите флаг всякий раз, когда обнаружен входящий вызов:

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

Теперь создайте список в классе NSLogService,

static ArrayList<StatusBarNotification> statusBarNotifications; 

и в вашем onNotificationPosted() добавить StatusBarNotification в список,

@Override 
public void onNotificationPosted(StatusBarNotification sbn) { 

    if (HomeScreen.shouldAnswerCallViaNotification) { 
     if (statusBarNotifications == null) { 
      updateNotificationList(); 
     } 
     statusBarNotifications.add(sbn); 

    } else { 
     updateNotificationList(); 
    } 

} 
public static ArrayList<StatusBarNotification> getAllNotifications() { 
    return statusBarNotifications; 
} 

public static void updateNotificationList() { 

    if (statusBarNotifications != null) 
     statusBarNotifications = null; 
    statusBarNotifications = new ArrayList<StatusBarNotification>(); 
} 

в вашем рабочем столе, на кнопки мыши, вызовите performNotificationOperation(NLService.getAllNotifications());

здесь является определение этого метода:

private void performNotificationOperation(ArrayList<StatusBarNotification> 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(); 
    } 

}