5

プログラムの目的: サービスで BACK ボタンをトリガーする

私は多くの方法を試しましたが、誰もこの目的を達成することはできませんでしたが、最終的に 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 に送信するにはどうすればよいですか?

4

3 に答える 3

2

1 サービスの静的フィールドを作成する

public static MyAccessibilityService instance;

2 次に、onServiceConnected() で初期化します

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

3 onUnbind() でクリアするのを忘れないでください

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

onServiceConnected() は、ユーザーがデバイスの設定でアプリに許可を与えると、システムによって呼び出されます

onUnbind() は、ユーザーがその権限を取り消すときです

4 好きな場所でインスタンスを使用する

if(MyAccessibilityService.instance != null)
    MyAccessibilityService.instance.performGlobalAction(....)
于 2016-10-31T15:00:29.577 に答える
2

試みている方法でアクセシビリティ サービスを実行することはできません。アクセシビリティ サービスは、アクセシビリティ サービスとしてのみ実行できます。アクセシビリティ サービスの機能を理解していれば、その理由は明らかです。できること:

  • キーボード イベントの追跡
  • テキスト フィールドの内容を調査する
  • アクションイベントを任意に送信する

これらは、悪意のある目的で簡単に使用できます。アプリケーション、または標準サービスでさえ、そのようなことを実行できるプロセスを起動できるようにすることは、ひどいセキュリティです。そのため、関連するすべての権限を使用して、システムのみがアクセシビリティ サービスを起動できます。これを行う唯一の場所は、アクセシビリティ設定メニューからです。このようにして、ユーザーは、アクセシビリティ サービスがいつ実行されているかを少なくとも知ることができ、実行しているこれらのサービスの種類についてより慎重になることができます。

これはまた、全体的な答えにつながります: できません。少なくとも、実際のアクセシビリティ サービスを実行してから、そこにインテントを直接送信しなければなりません。ただし、ユーザーは自分でサービスを個別に起動する必要があります。

于 2016-03-02T14:44:44.507 に答える
1

これが正しい方法かどうかはわかりませんが、作業は完了します。以下のように、ユーザー補助サービス メソッド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);
于 2016-09-29T12:23:35.290 に答える