9

我有一个应用程序将自己注册为默认启动器,并在启动时自动固定自己。

安装应用程序时,这一切都很好。它固定自己,只有后退按钮可见。

问题是当设备第一次启动时,它没有正确固定。我多次看到一系列“屏幕固定”和“屏幕未固定”的祝酒词。“主页”和“最近的任务”按钮仍然可见。

--

运行“adb shell dumpsys activity activities”——最后几行表明它没有被固定:

mLockTaskModeState=NONE mLockTaskPackages (userId:packages)=
0:[com.example.myapp]
mLockTaskModeTasks[]

--

运行 Marshmallow/6.0/23 的测试设备 Asus ZenPad

我依靠 MainActivity 清单属性“lockTaskMode”来固定(而不是 activity.startLockTask()):

<activity
    android:name=".MainActivity"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:label="@string/launcher_main"
    android:launchMode="singleTask"
    android:lockTaskMode="if_whitelisted"
    android:screenOrientation="landscape">
    <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>

任何帮助或指示将不胜感激

4

3 回答 3

3

我有同样的问题,我真的只能找到一个解决方案。我不知道为什么,但是是的,android 中的某些东西在启动时会阻止任务锁定,这让我大吃一惊,因为任务锁定旨在创建这些“信息亭”类型的应用程序。我能找到的唯一解决方案是检测未锁定的情况,然后重新启动应用程序。它有点“hacky”,但你还能做什么?

为了检测它没有锁定的情况,我创建了一个状态变量并分配状态(锁定、锁定、解锁、解锁)。然后在 onTaskModeExiting 的设备管理员接收器中,如果状态不是“解锁”,那么我知道它自己解锁了。因此,如果这种情况发生在失败的地方,我然后使用此方法重新启动应用程序(在警报管理器中安排应用程序,然后终止应用程序):

如何以编程方式“重启” android 应用程序?

这是一些示例代码:

设备管理员接收器

@Override
public void onLockTaskModeEntering(Context context, Intent intent, String pkg) {
    super.onLockTaskModeEntering(context, intent, pkg);
    Lockdown.LockState = Lockdown.LOCK_STATE_LOCKED;
}

@Override
public void onLockTaskModeExiting(Context context, Intent intent) {
    super.onLockTaskModeExiting(context, intent);

    if (Lockdown.LockState != Lockdown.LOCK_STATE_UNLOCKING) {
        MainActivity.restartActivity(context);
    }
    Lockdown.LockState = Lockdown.LOCK_STATE_UNLOCKED;
}

主要活动

public static void restartActivity(Context context) {
    if (context != null) {
        PackageManager pm = context.getPackageManager();
        if (pm != null) {
            Intent intent = pm.getLaunchIntentForPackage(context.getPackageName());
            if (intent != null) {
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                int pendingIntentId = 223344;
                PendingIntent pendingIntent = PendingIntent.getActivity(context, pendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
                AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
                mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, pendingIntent);
                System.exit(0);
            }
        }
    }
}

private void lock() {
    Lockdown.LockState = Lockdown.LOCK_STATE_LOCKING;
    startLockTask();
}

private void unlock() {
    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    if (am.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED) {
        Lockdown.LockState = Lockdown.LOCK_STATE_UNLOCKING;
        stopLockTask();
    }
}

事实上,这是我实现的简化版本。但它应该有希望让你指出一个解决方案。

于 2017-05-05T21:50:22.793 回答
0

抱歉迟到了,但是......
任何有这个问题的人都可以在第一个(LAUNCHER / HOME)活动(例如MainActivity)中完成这项棘手的工作:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (mSharedPreferences.getBoolean(KEY_PREF_RECREATED, false)) {
        mSharedPreferences.edit().putBoolean(KEY_PREF_RECREATED, false).apply();

        // start LOCK TASK here
    } else {
        mSharedPreferences.edit().putBoolean(KEY_PREF_RECREATED, true).apply();

        finish(); // close the app
        startActivity(new Intent(this, MainActivity.class)); // reopen the app
        return;
    }

    setContentView(R.layout.activity_main);

    // other codes
}
于 2018-06-02T19:55:03.367 回答
0

我现在找到的唯一解决方案:制作另一个启动器应用程序,没有锁定任务,每次启动器出现时都会触发主应用程序。这可以防止用户在 BOOT_COMPLETED 接收器上调用 LockTasked 应用程序之前再等待几秒钟。因此,只有当 lockTask 应用程序在清单中具有某些活动的启动器属性时,我们才能遇到这个问题。

于 2017-11-09T18:25:59.230 回答