返回

Android 10开机自启动的新姿势:Qt应用静默启动揭秘

前端

静默启动,静候其变

在移动设备上,开机自启动是一个常见的需求,尤其对于一些系统级应用或工具类应用而言,需要在用户不知不觉中完成启动过程,从而实现特定功能或提供及时服务。传统的开机自启动方式往往依靠静态广播监听,但这一方法在Android 10及其以上版本中已不再奏效。

为了解决这一问题,Android引入了新的静默启动机制,允许应用在用户不知情的情况下自动启动。这种机制依赖于系统的JobScheduler服务,能够在设备启动后的一定时间内触发应用的启动任务。

Qt拥抱静默启动

Qt for Android作为跨平台开发框架,自然也支持这一新机制。在Qt 5.15版本中,新增了QAndroidJniEnvironment::registerNativeService()方法,允许开发者注册一个本地服务,并在JobScheduler的触发下自动启动应用。

Android 10静默启动实战

要实现Qt应用在Android 10及其以上版本的静默启动,需要完成以下步骤:

  1. 在应用的AndroidManifest.xml文件中声明本地服务:
<service
    android:name="org.qtproject.example.NativeService"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:exported="false" />
  1. 在应用的代码中注册本地服务:
QAndroidJniEnvironment env;
env->registerNativeService("org.qtproject.example.NativeService",
                          [](const char *action) {
                              // 应用启动代码
                          });
  1. 使用JobScheduler安排启动任务:
JobInfo jobInfo = new JobInfo.Builder(123,
                                    new ComponentName(this, NativeService.class))
                        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE)
                        .build();

jobScheduler.schedule(jobInfo);

结语

通过本文的介绍,相信您已经对Qt应用在Android 10及其以上版本的静默启动机制有了深入的了解。希望这一技巧能够帮助您开发出更加实用和用户友好的应用。

附录:代码示例

// NativeService.java
public class NativeService extends JobService {

    @Override
    public boolean onStartJob(JobParameters params) {
        // 启动Qt应用
        Intent intent = new Intent(this, QtMainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);

        return false;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }
}
// QtMainActivity.cpp
#include <QAndroidJniEnvironment>
#include <QAndroidJniObject>

extern "C" JNIEXPORT void JNICALL
Java_org_qtproject_example_NativeService_startQtApp(JNIEnv *env, jobject thiz, jstring action) {
    QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
    activity.callMethod<void>("runOnUiThread", "(Ljava/lang/Runnable;)V", QAndroidJniObject::fromString("startQtApp()").object<jobject>());
}

void startQtApp() {
    // Qt应用启动代码
}

参考链接: