如何在服务内捕获关键事件?

7

我希望能够在我编写的服务中捕获关键事件。我可以在活动中轻松实现此操作,但是我尝试在服务中进行此操作时失败了。我想要捕获的关键事件(全局)是“返回”按钮,但如果不可能,HTC Desire提供的任何(硬件)按钮都可以。


你为什么想要在“Service”中捕获它? - Macarse
首先,我是新手安卓编程,我认为只有当一个活动获得焦点时才会接收到 KeyEvents。如果不是这样的话,我就不一定需要一个服务。我的目标是编写一个应用程序,在打电话时可以取消由接近传感器激活的屏幕锁定。这是必要的,因为 HTC Desire 有时会“忘记”正确地重新启用屏幕,我希望在按下任何按钮时都能实现这个功能(以便能够挂断电话而不必拆除电池 ;))。 - user388759
5个回答

3

您可以通过使用辅助功能服务捕获硬件按键事件,只需在安装应用程序后转到辅助功能设置并启用服务即可。以下是代码:

    public class AccessiblityService extends AccessibilityService {

        @Override
        protected void onServiceConnected() {
            super.onServiceConnected();
            Log.d(TAG, "service is connected");
        }

        @Override
        public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {

            Log.d(TAG, "onAccessibiltyEvent" + accessibilityEvent.toString());

        }

        @Override
        public void onInterrupt() {

        }
    // here you can intercept the keyevent
        @Override
        protected boolean onKeyEvent(KeyEvent event) {
            return handleKeyEvent(event);
        }

         private boolean handleKeyEvent(KeyEvent event) {
            int action = event.getAction();
            int keyCode = event.getKeyCode();
            if (action == KeyEvent.ACTION_DOWN) {
                switch (keyCode) {
                    case KeyEvent.KEYCODE_VOLUME_DOWN:
                        //do something
                        return true;

                    case KeyEvent.KEYCODE_VOLUME_UP: {
                        //do something
                        return true;
                    }
                }
            }
            return false;
        }

} 

manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.mypackagename">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <service
            android:name=".AccessiblityService"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
            <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/accessibility_service" />
        </service>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>             
    </application>

</manifest>

accessibility_service.xml//在“xml”目录中创建

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:canRequestFilterKeyEvents="true"
    android:accessibilityFlags="flagRequestFilterKeyEvents"/>

1
如何从辅助功能设置中启用服务? - Tom Taylor
刚刚尝试了从adb (https://dev59.com/g2kw5IYBdhLWcg3wNXz2#38939299) 中获取电源按钮按下事件的服务,但仍然无法成功获取。 - Tom Taylor

2

服务没有用户界面,因此它不会接收任何来自用户的输入。

如果您有一个管理服务的活动,那么在您的活动中按下返回键时,您可以使服务执行特殊操作。


1

是的,Android的活动只有在它们获得焦点时才会接收到KeyEvents

“全局”捕获后退按钮按下的唯一方法是创建一个InputMethod,以便您可以拦截硬键事件。 请记住,使用自己的InputMethod将不允许您使用自定义键盘,例如Swiftkey

您尝试联系HTC解决此问题了吗?


这不是我的设备(我有一台三星Galaxy I9000——它有自己的问题;)而是我的一个朋友的设备。他在一些论坛上搜索,发现一些人有同样的问题,但迄今为止没有解决方案(我不知道他是否联系了HTC)。但是,由于Android是开放的,我们应该能够解决遇到的问题(所以我想),所以想法就是这样做。;) - user388759

1
您可以从框架中广播keyEvent,并在您的服务中处理广播。 但是,您需要更改框架中的代码才能实现这一点。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接