2017-03-08 35 views
1

Googleのthis公式チュートリアルに続き、レイアウトの上にレイアウトを追加しています。ただし、アクセシビリティサービスがアクティブになってから、常にレイアウトが追加されます。アクセシビリティサービスからレイアウトをプログラムで追加または削除するにはどうすればよいですか?

このレイアウトをプログラム的に追加する場合は、特定の操作の後にもう一度削除する必要があります。

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" 
    android:accessibilityEventTypes="typeViewClicked|typeViewFocused" 
    android:packageNames="com.whatsapp" 
    android:accessibilityFeedbackType="feedbackSpoken" 
    android:notificationTimeout="100" 
    android:settingsActivity="com.example.android.apis.accessibility.TestBackActivity" 
    android:canRetrieveWindowContent="true" /> 

は、私はほとんどのチュートリアルから借りてきた私のコードです:ここで

は、アクセシビリティのサービスのための私のXMLであるしかし

public class GlobalActionBarService extends AccessibilityService { 

    private static final String TAG = "AccessibilityService"; 
    private WindowManager mWindowManager; 
    FrameLayout mLayout; 

    @Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 
     final int eventType = event.getEventType(); 
     String eventText = null; 
     switch(eventType) { 
      case AccessibilityEvent.TYPE_VIEW_CLICKED: 
       eventText = "Clicked: "; 
       break; 
      case AccessibilityEvent.TYPE_VIEW_FOCUSED: 
       eventText = "Focused: "; 
       break; 
     } 

     eventText = eventText + event.getContentDescription(); 

     mLayout = new FrameLayout(this); 
     mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); 
     WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 
     lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; 
     lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN; 
     lp.format = PixelFormat.TRANSLUCENT; 
     lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 
     lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 
     lp.gravity = Gravity.TOP; 
     LayoutInflater inflater = LayoutInflater.from(this); 
     inflater.inflate(R.layout.action_bar, mLayout); 

     if (eventText.toLowerCase().contains("test")) { 
      Log.d(TAG, "Oh! Displaying the layout"); 
      mWindowManager.addView(mLayout, lp); 
     } 

     if (eventText.toLowerCase().contains("navigate")) { 
      Log.d(TAG, "Removing the layout"); 
      if (mLayout != null && mLayout.getRootView() != null) { 
       mWindowManager.removeView(mLayout.getRootView()); 
      } 
     } 
    } 

    @Override 
    public void onInterrupt() { 

    } 

} 

、私のコードブレークと、それは明らかに間違っています。レイアウトを削除しようとすると失敗します。 (そして同じレイアウトを何度も追加していますか?)私が検討すべき性能上の問題はありますか?続き

私はフレームレイアウトを削除しようとするとスローされる例外です。

03-08 22:28:10.375 24266-24266/im.avi.todolist E/AndroidRuntime: 
FATAL EXCEPTION: main 
Process: im.avi.todolist, PID: 24266 
java.lang.IllegalArgumentException: View=android.widget.FrameLayout{3695c2 V.E...... ......I. 0,0-0,0} not attached to window manager 
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:473) 
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:382) 
at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:119) 
at im.avi.todolist.GlobalActionBarService.onAccessibilityEvent(GlobalActionBarService.java:77) 
at android.accessibilityservice.AccessibilityService$2.onAccessibilityEvent(AccessibilityService.java:1449) 
at android.accessibilityservice.AccessibilityService$IAccessibilityServiceClientWrapper.executeMessage(AccessibilityService.java:1585) 
at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:37) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

答えて

1

私は私の友人の助けを借りて解決策を考え出しました。私がやっていた間違いは毎回framelayoutを追加することでした。以下は現在動作するコードです:

public class GlobalActionBarService extends AccessibilityService { 

    private static final String TAG = "AccessibilityService"; 
    private WindowManager mWindowManager; 
    FrameLayout mLayout; 

    @Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 
     final int eventType = event.getEventType(); 
     String eventText = null; 
     switch(eventType) { 
      case AccessibilityEvent.TYPE_VIEW_CLICKED: 
       eventText = "Clicked: "; 
       break; 
      case AccessibilityEvent.TYPE_VIEW_FOCUSED: 
       eventText = "Focused: "; 
       break; 
     } 

     eventText = eventText + event.getContentDescription(); 

     if (eventText.toLowerCase().contains("test")) { 
      Log.d(TAG, "Oh! Displaying the layout"); 
      if (mLayout == null) { 
       mLayout = new FrameLayout(this); 
       mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); 
       WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 
       lp.type = WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; 
       lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN; 
       lp.format = PixelFormat.TRANSLUCENT; 
       lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 
       lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 
       lp.gravity = Gravity.TOP; 
       LayoutInflater inflater = LayoutInflater.from(this); 
       inflater.inflate(R.layout.action_bar, mLayout); 
       mWindowManager.addView(mLayout, lp); 
      } 
     } 

     if (eventText.toLowerCase().contains("navigate")) { 
      Log.d(TAG, "Removing the layout"); 
      if (mLayout != null && mLayout.getRootView() != null) { 
       mWindowManager.removeView(mLayout); 
       mLayout = null; 
      } 
     } 
    } 

    @Override 
    public void onInterrupt() { 

    } 

} 
関連する問題