2014-09-04 46 views
5

我的用戶將使用已啓用話語提示或其他一些無障礙服務。我想在我們的應用程序中捕獲onKeyEvent事件,但事件被分派到啓用的輔助功能服務。我創建了以下基本的輔助功能服務。onKeyEvent&Accessibility服務

public class Accessibility_Service extends AccessibilityService { 

    private String TAG = Accessibility_Service.class.getSimpleName(); 

    @Override 
    public boolean onKeyEvent(KeyEvent event) { 
     int action = event.getAction(); 
     int keyCode = event.getKeyCode(); 
     if (action == KeyEvent.ACTION_UP) { 
      if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 
       Log.d("Hello", "KeyUp"); 
      } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
       Log.d("Hello", "KeyDown"); 
      } 
      return true; 
     } else { 
      return super.onKeyEvent(event); 
     } 
    } 

    /** 
    * Passes information to AccessibilityServiceInfo. 
    */ 
    @Override 
    public void onServiceConnected() { 
     Log.v(TAG, "on Service Connected"); 
     AccessibilityServiceInfo info = new AccessibilityServiceInfo(); 
     info.packageNames = new String[] { "com.camacc" }; 
     info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; 
     info.notificationTimeout = 100; 
     info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN; 
     setServiceInfo(info); 

    }// end onServiceConnected 

    /** 
    * Called on an interrupt. 
    */ 
    @Override 
    public void onInterrupt() { 
     Log.v(TAG, "***** onInterrupt"); 

    }// end onInterrupt 

    @Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 
     // TODO Auto-generated method stub 

    } 
}// end Accessibility_Service class 

當我檢查logcat時,我沒有得到任何迴應。在TalkBack或其他此類輔助功能服務之前是否可以使用音量降低和上傳事件?

謝謝。

編輯:

添加以下標誌仍然沒有運氣:

info.flags = AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS; 

回答

-2

我想你一定當擴展AccessibilityService實行 「onAccessibilityEvent()」 方法;東西一樣:

@Override 
public void onAccessibilityEvent(AccessibilityEvent event) { 
    final int eventType = event.getEventType(); 
    switch(eventType) { 
     case AccessibilityEvent.TYPE_VIEW_CLICKED: 
      do somthing 
      break; 
     case AccessibilityEvent.TYPE_VIEW_FOCUSED: 
      do somthing 
      break; 
    } 
4

老問題,但也許這個答案會幫助別人。

是的,另一個輔助功能服務可能會消耗KeyEvent。

請查看FLAG_REQUEST_FILTER_KEY_EVENTS文檔,有: 設置此標誌並不能保證此服務將過濾關鍵事件,因爲在任何給定時間只有一個服務可以這樣做。這可以避免用戶在啓用不同的密鑰過濾服務的情況下由於行爲改變而感到困惑。如果已啓用另一個密鑰過濾服務,則此密鑰過濾服務不會接收關鍵事件。

因此,另一個輔助功能服務可以使用KeyEvent。

5

嘗試配置的輔助服務,像這樣的XML資源,如果你需要更多的信息,看看這個:https://developer.android.com/guide/topics/ui/accessibility/services.html

<?xml version="1.0" encoding="utf-8"?> 
<accessibility-service 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:accessibilityEventTypes="typeContextClicked|typeViewClicked" 
android:packageNames="com.example.andres.eventcapture" 
android:accessibilityFlags="flagRequestFilterKeyEvents" 
android:accessibilityFeedbackType="feedbackAllMask" 
android:notificationTimeout="50" 
android:canRetrieveWindowContent="true" 
android:settingsActivity="" 
android:canRequestFilterKeyEvents="true" 
/> 

它的工作好!

+0

謝謝,我能夠獲得音量和音量降低的事件。不檢測軟鍵盤按鍵/ – ashishdhiman2007 2018-01-18 11:04:36

1

嘗試刪除info.packageNames或將其設置爲null。根據文檔here,您只會收到這些應用程序包生成的事件。

0

如果你特別想要一個服務的音量按鍵,這將工作。它將覆蓋音量鍵操作,因此請避免全局使用它。

public class VolumeKeyController { 

    private MediaSessionCompat mMediaSession; 
    private final Context mContext; 

    public VolumeKeyController(Context context) { 
     mContext = context; 
    } 

    private void createMediaSession() { 
     mMediaSession = new MediaSessionCompat(mContext, KeyUtil.log); 

     mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | 
       MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); 
     mMediaSession.setPlaybackState(new Builder() 
       .setState(PlaybackStateCompat.STATE_PLAYING, 0, 0) 
       .build()); 
     mMediaSession.setPlaybackToRemote(getVolumeProvider()); 
     mMediaSession.setActive(true); 
    } 

    private VolumeProviderCompat getVolumeProvider() { 
     final AudioManager audio = mContext.getSystemService(Context.AUDIO_SERVICE); 

     int STREAM_TYPE = AudioManager.STREAM_MUSIC; 
     int currentVolume = audio.getStreamVolume(STREAM_TYPE); 
     int maxVolume = audio.getStreamMaxVolume(STREAM_TYPE); 
     final int VOLUME_UP = 1; 
     final int VOLUME_DOWN = -1; 

     return new VolumeProviderCompat(VolumeProviderCompat.VOLUME_CONTROL_RELATIVE, maxVolume, currentVolume) { 
      @Override 
      public void onAdjustVolume(int direction) { 
       // Up = 1, Down = -1, Release = 0 
       // Replace with your action, if you don't want to adjust system volume 
       if (direction == VOLUME_UP) { 
        audio.adjustStreamVolume(STREAM_TYPE, 
          AudioManager.ADJUST_RAISE, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 
       } 
       else if (direction == VOLUME_DOWN) { 
        audio.adjustStreamVolume(STREAM_TYPE, 
          AudioManager.ADJUST_LOWER, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 
       } 
       setCurrentVolume(audio.getStreamVolume(STREAM_TYPE)); 
      } 
     }; 
    } 

    // Call when control needed, add a call to constructor if needed immediately 
    public void setActive(boolean active) { 
     if (mMediaSession != null) { 
      mMediaSession.setActive(active); 
      return; 
     } 
     createMediaSession(); 
    } 

    // Call from Service's onDestroy method 
    public void destroy() { 
     if (mMediaSession != null) { 
      mMediaSession.release(); 
     } 
    } 
}