onKeyEvent & Accessibility Service



我的用户将使用启用TalkBack或其他可访问服务。我想在我们的应用程序中捕捉onKeyEvent事件,但该事件已发送到启用的辅助功能服务。我创建了以下基本的无障碍服务。

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

当我查看日志时,没有得到任何响应。是否可以在对讲或其他此类辅助功能服务之前使用音量降低和音量增加事件?

谢谢。

编辑:

添加了以下仍然没有运气的标志:

info.flags = AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS;

如果您需要更多信息,请尝试在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"
/>

效果很好!

老问题,但也许这个答案会对某人有所帮助。

是的,另一个辅助功能服务可能会使用KeyEvent。

请查看FLAG_REQUEST_FILTER_KEY_EVENTS文档,其中包括:设置此标志并不保证此服务将筛选关键事件,因为在任何给定时间只有一个服务可以这样做。这避免了在启用不同的密钥筛选服务时由于行为更改而引起的用户困惑。如果已经启用了另一个密钥筛选服务,则此服务将不会接收密钥事件

因此,另一个辅助功能服务可以使用KeyEvents。

尝试删除info.packageNames或将其设置为null。根据此处的文档,您将只收到由这些应用程序包生成的事件。

如果您特别希望从服务中批量按键,这将起作用。它将覆盖音量键操作,因此避免全局使用它。

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();
        }
    }
}

我认为在扩展AccessibilityService时必须实现"onAccessibility Event()"方法;类似于:

@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;
    }

相关内容

  • 没有找到相关文章

最新更新