1

Моя цель программы: вызвать кнопку BACK в службеКак отправить пользовательское событие в AccessibilityService?

Я пробовал много способов, никто не может достичь этой цели, наконец, я обнаружил AccessibilityService, это могут быть самые возможные способы реализации этой функции.

Я создал этот AccessibilityService и тестируют это работает

package com.accessibilityservice; 

public class MyAccessibilityService extends AccessibilityService { 
    public MyAccessibilityService() { 
    } 

    @Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 

     performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK); 

    } 

    @Override 
    public void onInterrupt() { 

    } 
} 

<?xml version="1.0" encoding="utf-8"?> 
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" 
    android:accessibilityEventTypes="typeAllMask" 
    android:accessibilityFeedbackType="feedbackSpoken" 
    android:accessibilityFlags="flagDefault" 
    android:canRetrieveWindowContent="true" 
    android:description="desc" 
    android:notificationTimeout="100" 
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity" /> 

А потом я попытался пошевелиться performGlobalAction на службу, но он не выполняет действия.

public class MyService extends Service { 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     MyAccessibilityService mas=new MyAccessibilityService(); 
     mas.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK); 
    } 
} 

Я также попытался отправить пользовательское событие по-разному, но никто не может отправить MyAccessibilityService

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    //method1 
    AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_CLICKED); 
    event.setContentDescription("this is description"); 
    View view = new View(this); 
    ViewParent parent = view.getParent(); 
    if (parent != null) { 
     parent.requestSendAccessibilityEvent(view, event); 
    } 

    //method2 
    AccessibilityManager manager = (AccessibilityManager) getApplicationContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 
    AccessibilityEvent event = AccessibilityEvent.obtain(); 
    event.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT); 
    event.setPackageName("p"); 
    event.setClassName("c"); 
    manager.sendAccessibilityEvent(event); 
} 

Как я могу отправить пользовательское событие или сообщение MyAccessibilityService, так что я могу признать событие и сообщение для выполнения действия?

ответ

1

Вы не можете запустить службу доступности, как вы пытаетесь. Услуги доступности доступны только для служб доступности. Причина здесь очевидна, если вы понимаете возможности служб доступности. Вещи они могут сделать: события клавиатуры

  • Трек
  • Исследовать содержимое текстовых полей
  • произвольно отправлять события действия

Они могут быть легко использованы в злонамеренных целях. Разрешить приложение или даже стандартную службу запуска процесса, который может делать такие вещи, будет ужасной безопасностью. Таким образом, только система может запускать службу доступности со всеми соответствующими разрешениями. Единственное, что он делает, это меню настроек доступности. Таким образом, пользователи знают, по крайней мере, когда работает служба доступности, и могут быть более осторожными в отношении типов этих служб, которые они запускают.

Это также приводит к общему ответу: вы не можете. По крайней мере, не запустив службу фактической доступности, а затем сразу отправляя намерения. Но пользователю придется отдельно запускать сервис самостоятельно.

0

Я не уверен, что это правильный путь, но он выполнит вашу работу. Получите радиовещательный приемник, зарегистрированный в вашем методе службы специальных возможностей onServiceConnected(), как показано ниже.

@Override 
protected void onServiceConnected() { 
    super.onServiceConnected(); 
    registerReceiver(listener, new IntentFilter("my_custom_event_listener)); 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    unregisterReceiver(listener); 
} 

И ваш вещательный приемник в пределах вашей службы доступности

private class MyCustomListener extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Bundle extras = intent.getExtras(); 
     if(extras != null){ 
      String action = extras.getString("action"); 
      if(action.equals("back") 
       performGlobalAction(GLOBAL_ACTION_BACK); 
     } 
} 

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

Intent back = new Intent("my_custom_event_listener"); 
Bundle data = new Bundle(); 
data.putString("action", "back"); 
back.putExtras(data); 
sendBroadcast(back); 
1

1 Создать статическое поле вашего обслуживания

public static MyAccessibilityService instance;

2 затем инициализировать его в onServiceConnected()

@Override 
    protected void onServiceConnected() { 
    super.onServiceConnected(); 
    instance = this; 
} 

3 не Foget, чтобы очистить его в onUnbind()

@Override 
    public boolean onUnbind(Intent intent) { 
    instance = null; 
    return super.onUnbind(intent); 
} 

onServiceConnected() вызывается системой, когда пользователь дает разрешение для вашего приложения в настройках устройства

onUnbind(), когда пользователи аннулирует это разрешение

4 Используйте свой экземпляр везде, где хотите

if(MyAccessibilityService.instance != null) 
    MyAccessibilityService.instance.performGlobalAction(....)