首页 > 解决方案 > 在 Android 10 或更高版本中从后台服务启动 Activity

问题描述

我正在开发一个像App Lock一样工作的应用程序。但我的申请有一些不同。我的应用程序有一个MainActivity将作为主页和默认应用程序运行。

<activity
        android:name=".MainActivity"
        android:launchMode="singleInstance"
        android:clearTaskOnLaunch="true"
        android:theme="@style/LaunchTheme"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
        android:hardwareAccelerated="true"
        android:windowSoftInputMode="adjustResize">
        <!-- This keeps the window background of the activity showing
             until Flutter renders its first frame. It can be removed if
             there is no splash screen (such as the default splash screen
             defined in @style/LaunchTheme). -->
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.HOME"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

除此之外,我有一个后台服务将监听另一个应用程序正在前台(堆栈顶部)使用。

<uses-permission
    android:name="android.permission.PACKAGE_USAGE_STATS"
    tools:ignore="ProtectedPermissions" />

/**
 * Check running apps
 * @return Package is running
 */
private String checkRunningApps() {
    String packageName = "";
    UsageStatsManager usm = (UsageStatsManager) this.getSystemService("usagestats");
    long endTime = System.currentTimeMillis();
    long beginTime = endTime - 10000;
    UsageEvents.Event event = new UsageEvents.Event();
    UsageEvents usageEvents = usm.queryEvents(beginTime, endTime);
    while (usageEvents.hasNextEvent()) {
        usageEvents.getNextEvent(event);
        if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
            packageName = event.getPackageName() == null ? "" : event.getPackageName();
        }
    }
    Log.d("flutter", "Target package: " + packageName);
    return this.allowPackages.contains(packageName) ? "" : packageName;
}

MainActivity绑定并监听来自后台服务的回调。当服务有回调时,MainActivity启动一个活动来验证用户

@Override
public void onCredential(String currentPackage) {
    Log.d("flutter", "onCredential " + currentPackage);
    if (BiometricUtil.doesDeviceHasSecuritySetup(this) && !currentPackage.isEmpty()){
        Objects.requireNonNull(this.mAppLockService).setIsAuthenticate(
                AppLockService.generateCredential(
                        "Authenticate",
                        AppLockService.AUTHENTICATE_VALUE_FAIL
                )
        );
        Intent intent = new Intent(MainActivity.this, DeviceCredentialActivity.class);
        intent.putExtra(AppLockService.PACKAGE_KEY, currentPackage);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
    }
}

@Override
public void onStartTargetPackage(String targetPackage) {
    Log.d("flutter", "onStartTargetPackage " + targetPackage);
    Intent launchIntent = this.getPackageManager().getLaunchIntentForPackage(targetPackage);
    if (launchIntent != null) {
        startActivity(launchIntent);
    }
}

所以,在 Android 9 或更低版本上一切都很好,但在 Android 10 或更高版本上,我遇到了一些问题。问题是:

  1. android:clearTaskOnLaunch="true" 和 android:launchMode="singleInstance" 不起作用。
  2. 当 MainActivity 在后台启动一个新的 Activity 时,有时它会出现在栈顶,有时它只是出现在 MainActivity 上方,而另一个应用程序(如设置)出现在栈顶。

所以我不知道为什么会这样。如果你知道原因,请给我一个答案。

这是我关于我的问题的演示。

  1. 在 Android 9 上正确

  2. 在 Android 10 上不正确

感谢您的贡献。

标签: androidflutterperformanceandroid-service

解决方案


推荐阅读