2017-09-13 3 views
1

AccessibilityService을 통해 시스템 백 프레스 이벤트를 보내려고합니다. 내 자신의 앱에없는 경우에만 작동합니다.AccessibilityService - performGlobalAction이 자체 앱에서 작동하지 않습니다.

나는 내 앱에 상관없이 을 performGlobalAction에서 얻지 만, 내 자체 앱이 아닌 다른 모든 앱에서 이벤트가 실제로 실행된다는 것을 알 수 있습니다. 이전 활동이 표시되거나 이와 유사하다는 의미에서)

왜 이런 현상이 발생합니까? 내 앱은 WindowManager의 상단에 오버레이가 그려져 있고 모든 것이 작동합니다 (AccessibilityService이 실행 중이고 내 맞춤 이벤트를 처리하고 있으며 내 이벤트의 성공 메시지를 항상 반환하지만 내 앱은 반대로 반응하지 않습니다 버튼 이벤트).

내 서비스는 다음과 같습니다 :

public class MyAccessibilityService extends AccessibilityService { 

    public static void sendBackIntent(Context context) { 
     Intent intent = new Intent(context, MyAccessibilityService.class); 
     intent.putExtra("action", GLOBAL_ACTION_BACK); 
     context.startService(intent); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Bundle extras = intent.getExtras(); 
     Integer action = null; 
     if (extras != null) { 
      action = extras.getInt("action"); 
     } 

     if (action != null) { 
      switch (action) { 
       case GLOBAL_ACTION_BACK: 
        boolean result = performGlobalAction(action); 
        L.d("Action %d executed: %b", action, result); 
        break; 
       default: 
        L.e("Unhandled action %d", action); 
        break; 
      } 
     } 
     return super.onStartCommand(intent, flags, startId); 
    } 

    @Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 

    } 

    @Override 
    public void onInterrupt() { 
    } 
} 

편집

을이 명확하게하기 위해 : 나는 MyAccessibilityService.sendBackIntent(context)를 통해이 서비스를 시작하지 마십시오

  • , 나는 다음과 같은 의도를 보내 : if (isAccessibilityserviceRunning) MyAccessibilityService.sendBackIntent(context)
  • sys를 통해 서비스를 시작합니다. 임시 서비스 메뉴를 활성화하고 이후에 자동으로 시스템을 시작하도록하십시오.
  • AccessibilityService의 모든 것을 accessibilityservice.xml에 설정하고이를 사용하여 내 서비스 설정을 정의하면이 이벤트가 완벽하게 작동합니다. 안정적으로 수신 받기 원하는 및 올바른

2

내 경우에는 내 오버레이 여전히 가끔 문제를 만들 타이밍 문제가있다는 포커스 만드는 초점을 훔쳐하지 않는 것 같다 편집 할 수 있습니다. 그래도 startService 전화가 허용 된 대답에서 논의 된대로 안전하지 않으므로 BroadcastReceiver을 사용하여 서비스를 향상시킬 수 있습니다.

답변

1

매우 이상한 일을하고 있다는 것을 알게되었습니다. AccessibilityService을 보통 (Service)으로 처리하고있는 것으로 보입니다. 이 제안이의 부분이 다음과 같은 방법의 구현 :

public static void sendBackIntent(Context context); 

@Override 
public int onStartCommand(Intent intent, int flags, int startId); 
이러한 두 가지 방법의 서명에 의해 그냥

하고 정적 메서드 내에서

context.startService(intent);  

의 부르심, 내가 말할 수있는 당신은 AccessibilityServices을 이해할 수 없으며 그들이 어떻게 자신의 직업을 수행하기로되어 있는지. 액세스 가능성 서비스를 시작하거나 시도하는 방식으로 액세스 서비스를 시작할 수 없습니다. 접근성 서비스를 사용하여 전역 작업을 수행 할 수는 있지만 접근성 서비스 메뉴 (TalkBack이 표시된 위치를 알고 있음)에서 올바르게 실행하지 않으면 정확하고 전 세계적으로 그렇게하지 못할 것입니다.

코드가 본질적으로 실행중인 컨텍스트 내에서 실행되고 있지 않습니다. 따라서 실행되고 실행됩니다. 그러나 AccessibilityServices과 그 각각의 힘은 운영 체제에 전역으로 부착 할 수있는 능력을 갖추고 있습니다.당신이 서비스를 시작하려고 할 때 안드로이드 API 년대는 제대로 AccessibilityService 바인딩되지 않습니다

context.startService(intent); 

당신은 접근성 서비스 설정 메뉴에서 액세스 서비스를 시작해야합니다.

서비스가 이미 시작된 경우에도 이러한 호출은 안전하지 않습니다! 활동을 시작하기 전에 사용자가 서비스를 시작한다는 보장은 없습니다. context.startService을 호출하고이 방법으로 AccessibilityService를 시작하려고하면 내게 필요한 옵션 설정 메뉴가 서비스를 시작하지 못하며 OS에 제대로 바인딩되지 않습니다. 실제로 이런 상황이 발생하면 사용자는 다음을 수행해야합니다. 접근성 설정 메뉴에서 스위치 서비스를 끄고 응용 프로그램을 강제 종료 (심지어 설치 제거)하고 장치를 다시 시작한 다음 서비스를 시작한 다음 작업을 시작합니다. 적절한 행동이 성취되도록 명령하십시오.

이렇게하지 않으면 OS에 제대로 바인딩되지 않으며 동작이 정의되지 않습니다. 지금 당장 당신은 OS에서 해킹을 만들었고 AOSP 통합 테스트에서 다루지 않았기 때문에 버전, 제조사 등에 따라 크게 다를 수있는 정의되지 않은 동작에 대해 실행 중입니다.

실제로 context.startService() 호출을 사용하여 내게 필요한 옵션 서비스를 시작할 수 없습니다. 이는 Accessibility Services가 화면 컨텐츠에 액세스 할 수 있고 사용자가 액세스 할 수있는 제공 업체 및 응용 프로그램에 대한 정밀한 그레인 제어가 필요하기 때문에 Android의 매우 중요한 보안 기능입니다. 따라서 어떤 행동을하고있는 동안 그것은 정의되지 않고 위험한 행동입니다. 다음 서비스 구성 XML로

:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" 
    android:description="@string/accessibility_service_description" 
    android:accessibilityEventTypes="typeWindowContentChanged" 
    android:accessibilityFlags="flagRequestTouchExplorationMode" 
    android:canRetrieveWindowContent="true" 
    android:canRequestTouchExplorationMode="true" 
    android:accessibilityFeedbackType="feedbackGeneric" 
    android:notificationTimeout="100" 
    android:settingsActivity="com.service.SettingsActivity" 
    /> 

그리고 다음과 같은 접근성 서비스 당신이 원하는 것은 다음과 같은 것입니다.

class MyA11yService extends AccessibilityService { 
    @Override public boolean onGesture(int gestureId) { 
     switch (gestureId) { 
      case GESTURE_SWIPE_UP_AND_DOWN: 
       CLog.d("Performing gesture."); 
       performGlobalAction(GLOBAL_ACTION_BACK); 
       return true; 

      default: 
       return false; 
     } 
    } 
} 

performGlobalAction 전화는 Context에서 잘 작동합니다. 이제는 SWIPE_UP_DOWN 제스처에서이 작업을 수행하는 대신 원하는 작업은 "글로벌 뒤로 버튼"작업을 트리거 할 수있는 일부 프로세스 간 통신을 설정하는 것입니다. 그러나이 정보는 또 다른 질문입니다. 비록이 글의 정보를 이해한다면, 어떻게 진행해야하는지 명확해질 것입니다.

+1

토론이나 디버깅 세션에 대한 설명이 아닙니다. 이 대화는 [채팅으로 이동되었습니다] (http://chat.stackoverflow.com/rooms/154466/discussion-on-answer-by-chriscm-accessibilityservice-performglobalaction-not-w). 여기에 중요한 정보가 있으면 질문이나 답변으로 편집해야합니다. –

+0

그래서 위협의 어느 시점에서 나는 그 내용 중 일부를 옮긴 후 주석 삭제에 관한 의견을 게시했습니다. 누군가는 그것을 nuked했지만 지금은 사라졌습니다. 많은 내용을 삭제하기 전에 경고를 보내 주시면 감사하겠습니다. @ prom85 : 다른 질문에 다른 질문을하는 경우이 특정 질문에 대해 정답 (또는 적어도 유사한 문제로 혼동스러워하는 다른 사람들이 볼 필요가있는 정보)이라고 생각합니다. – ChrisCM

+0

삭제 된 댓글 중에 내가 게시 한 내용이 표시되지 않습니다. 어쨌든, 정보는 삭제되지 않았습니다 *; 그것은 채팅에 보관되었습니다. * 다른 시끄러운 댓글을 남겨 두는 것 외에는 경고 할 수있는 실제 방법이 없습니다. 댓글 쓰레드가 너무 길어지면 자동 플래그를 얻습니다. 제안 된 액션 코스는 채팅으로 이동하는 것입니다. 워크 플로를 개선하는 방법이나 정책 관련 문제에 대한 제안 사항이 있으면 [Meta]에 질문을 게시 할 수 있습니다. 당신이 얻으려고하는 라인은 기본적으로 코멘트가 일시적이며 토론을위한 것이 아닙니다. –

관련 문제