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

我不確定這是否是正確的方法,但它會完成您的工作。請在您的無障礙服務方法上的ServiceConnected()(如下所示)中註冊廣播接收器。

@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(....) 
相關問題