【问题标题】:Android: how to re-enable an accessibility service after each reboot?Android:每次重启后如何重新启用无障碍服务?
【发布时间】:2019-06-02 22:14:43
【问题描述】:

我们所说的设备是带有外部 USB 键盘的 Android 8 主机。 好吧,我需要为这个键盘的功能键分配一些任务,例如启动某些应用程序。比如,F4 可以启动媒体播放器,F5 可以启动导航应用等等。 AutomateAutoInput Tasker 插件都可以用于此目的,但所有此类应用程序都使用 accessibility service 与物理交互隐藏设备。

这里的大问题是,这个特定的 Android 设备会在(热)重启时定期终止辅助功能服务。从禁用省电模式到将 Automate 等标记为 设备管理应用程序,一切都尝试了, 没有任何帮助。所以我已经辞职了,现在我正在考虑另一种方法,以便在系统因未知原因重新启动后禁用相应的无障碍服务后重新启用它。

如果设备已植根,我想有一种简单的方法可以通过 shell 命令或其他方式重新启动无障碍服务(只是猜测,我是 Android 的初学者)。但显然我想尽可能避免生根。理想的情况是在每次重新启动时(自动)启动一个 shell 命令/应用程序/前台服务/任何东西——这将具有足够的管理权限来重新启用系统在重新启动期间刚刚禁用的可访问性服务。当然,所有这些东西都不需要生根设备。但我不确定这是否可以在 Android 上完成(在 Windows 上,在系统帐户中运行的服务就足够了,但 Android 是另一回事)。

一个公平的解决方案可能是

  1. root 设备,
  2. 安装用于在每次重启后重启无障碍服务的 shell 命令(应用程序、前台服务等)并
  3. 取消设备根目录(以 SuperSU 为例)以保护用户并且不使保修失效。

有人能告诉我上述解决方案是否可以达到预期的效果吗?如果可以的话,我可以提供一些指导方针吗?

【问题讨论】:

    标签: android keyboard-shortcuts accessibilityservice


    【解决方案1】:

    要实现您的目的,您应该使用 BroadcastReceiverjobIntentService

    首先创建一个启动接收器

    public class BootReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
                MyService.enqueueWork(context, new Intent());
            }
        }
    
    }
    

    将其添加到manifest

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
    <receiver android:name=".BootReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                </intent-filter>
    </receiver>
    
    <service android:name=".MyService"
             android:permission="android.permission.BIND_JOB_SERVICE"/>
    

    现在你必须定义你的 jobIntent

    public class MyService extends JobIntentService {
    
        public static final int JOB_ID = 0x01;
    
        public static void enqueueWork(Context context, Intent work) {
            enqueueWork(context, MyService.class, JOB_ID, work);
        }
    
        @Override
        protected void onHandleWork(@NonNull Intent intent) {
            // your code
        }
    
    }
    

    就是这样。这将直接启动服务(在 pre-O 平台上运行时)或将其作为作业排入队列(在 O 和更高版本上运行时)。不管是什么平台,你传入 enqueueWork 的所有东西最终都会出现在 onHandleWork 中。

    这里有一些有用的链接:link - link

    【讨论】:

    • 谢谢。正如我已经说过的,我是 Android 新手,我有下一个问题:这个清单的所有者应用程序应该是前台服务还是可以是常规应用程序?如果是这样,我应该 root 设备还是可以启动服务的应用程序能够收集足够的权限来执行此操作?
    • 应用程序的清单,不需要root设备
    • 请考虑我的回答是否正确或有帮助,这对 SO 社区很重要
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 2016-12-05
    • 2020-01-24
    • 2011-04-21
    相关资源
    最近更新 更多