Android L screen pinning

这个暂时相对冷门的功能,如果你能看到这篇文章说明你还是有点了解的。

屏幕固定是android 5.0 上的新功能 其Api介绍如下:

我说一点比较重要的吧,就是开了屏幕固定以后,通知栏和状态栏会隐藏,home键和recent键会失效(单端失效),然后还不准系统启动其他activity。

就是说 你只能在这个应用内部干事情。比如你吧手机借给别人的时候就可以用这个功能 。

至于这个“尚不完善”的功能的消极作用会在文末讲一点。

Apis

Screen pinning

Android 5.0 introduces a new screen pinning API that lets you temporarily restrict users from leaving your task or being interrupted by notifications. This could be used, for example, if you are developing an education app to support high stakes assessment requirements on Android, or a single-purpose or kiosk application. Once your app activates screen pinning, users cannot see notifications, access other apps, or return to the home screen, until your app exits the mode.

There are two ways to activate screen pinning:

  • Manually: Users can enable screen pinning in Settings > Security > Screen Pinning, and select the tasks they want to pin by touching the green pin icon in the recents screen.
  • Programmatically: To activate screen pinning programmatically, call startLockTask() from your app. If the requesting app is not a device owner, the user is prompted for confirmation. A device owner app can call the setLockTaskPackages() method to enable apps to be pinnable without the user confirmation step.

When task locking is active, the following behavior happens:

  • The status bar is blank, and user notifications and status information are hidden.
  • The Home and Recent Apps buttons are hidden.
  • Other apps cannot launch new activities.
  • The current app can start new activities, as long as doing so does not create new tasks.
  • When screen pinning is invoked by a device owner, the user remains locked to your app until the app calls stopLockTask().
  • If screen pinning is activity by another app that is not a device owner or by the user directly, the user can exit by holding both the Back and Recent buttons.

来源: https://developer.android.com/about/versions/android-5.0.html#ScreenPinning

reference

     public void startLockTask ()

Added in API level 21
Request to put this Activity in a mode where the user is locked to the current task. This will prevent the user from launching other apps, going to settings, or reaching the home screen. If isLockTaskPermitted(String) returns true for this component then the app will go directly into Lock Task mode. The user will not be able to exit this mode until stopLockTask() is called. If isLockTaskPermitted(String) returns false then the system will prompt the user with a dialog requesting permission to enter this mode. When entered through this method the user can exit at any time through an action described by the request dialog. Calling stopLockTask will also exit the mode.

来源: https://developer.android.com/reference/android/app/Activity.html

     public void stopLockTask ()

Added in API level 21
Allow the user to switch away from the current task. Called to end the mode started by startLockTask(). This can only be called by activities that have successfully called startLockTask previously. This will allow the user to exit this app and move onto other activities.

来源: https://developer.android.com/reference/android/app/Activity.html#stopLockTask()

support

Use screen pinning

This information applies only to devices running Android 5.0 and higher.
You can set your device to only show a certain app's screen using screen pinning, and some apps may ask you if you want to use screen pinning.

Screen pinning can be handy if you want to play a game without accidentally minimizing the app if you touch the Home button. Turn on screen pinning in your device's settings app. Then follow the instructions below to pin a screen for a specific app.

Turn screen pinning on or off

  1. Open your device's Settings menu .
  2. Under "Personal," touch Security.
  3. Under "Advanced," touch Screen pinning.
  4. Move the switch on or off.

Pin a screen

  1. Make sure that screen pinning is enabled on your device.
  2. Open an app and go to the screen you want to pin.
  3. Touch Overview on your device.
  4. Swipe up to reveal the pin icon on the bottom right corner of your selected screen.
  5. Touch the pin icon .
  6. If you want the lock screen to appear after an app is unpinned, check the box next to "Ask for unlock pattern before unpinning."
  7. Touch Start.

Unpin a screen

  1. When you're on the pinned screen, touch and hold Overview and Back at the same time.
  2. Release both buttons and the screen will be unpinned.
    • If you required that the lock screen show after an app is unpinned, you will need to enter your pattern, PIN, or pa ssword.

来源: https://support.google.com/nexus/answer/6118421?hl=en&ref_topic=3416293

图没挂但是要翻墙才能看得到。

屏幕固定相关的实现在:ActivityStackSupervisor.java

固定

    case LOCK_TASK_START_MSG: {
        // When lock task starts, we disable the status bars.
        try {
            if (mLockTaskNotify == null) {
                mLockTaskNotify = new LockTaskNotify(mService.mContext);
            }
            mLockTaskNotify.show(true);
            mLockTaskIsLocked = msg.arg2 == 0;
            if (getStatusBarService() != null) {
                int flags =
                        StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK;
                if (!mLockTaskIsLocked) {
                    flags ^= StatusBarManager.DISABLE_HOME
                            | StatusBarManager.DISABLE_RECENT;
                }
                getStatusBarService().disable(flags, mToken,
                        mService.mContext.getPackageName());
            }
            mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
            if (getDevicePolicyManager() != null) {
                getDevicePolicyManager().notifyLockTaskModeChanged(true,
                        (String)msg.obj, msg.arg1);
            }
        } catch (RemoteException ex) {
            throw new RuntimeException(ex);
        }
     } break;

解除固定

                case LOCK_TASK_END_MSG: {
                    // When lock task ends, we enable the status bars.
                    try {
                        if (getStatusBarService() != null) {
                            getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
                                    mService.mContext.getPackageName());
                        }
                        mWindowManager.reenableKeyguard(mToken);
                        if (getDevicePolicyManager() != null) {
                            getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
                                    msg.arg1);
                        }
                        if (mLockTaskNotify == null) {
                            mLockTaskNotify = new LockTaskNotify(mService.mContext);
                        }
                        mLockTaskNotify.show(false);
                        try {
                            boolean shouldLockKeyguard = Settings.System.getInt(
                                    mService.mContext.getContentResolver(),
                                    Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0;
                            if (!mLockTaskIsLocked && shouldLockKeyguard) {
                                mWindowManager.lockNow(null);
                                mWindowManager.dismissKeyguard();
                                new LockPatternUtils(mService.mContext)
                                        .requireCredentialEntry(UserHandle.USER_ALL);
                            }
                        } catch (SettingNotFoundException e) {
                            // No setting, don't lock.
                        }
                    } catch (RemoteException ex) {
                        throw new RuntimeException(ex);
                    }
                } break;

如果你想自定义组合键解除屏幕固定只需要调用IActivityManager中的相应方法就行了。
还有要添加android.permission.MANAGE_ACTIVITY_STACKS权限。

    IActivityManager activityManager = ActivityManagerNative.getDefault();
      if(activityManager != null && activityManager.isInLockTaskMode()){
         activityManager.stopLockTaskModeOnCurrent();
      }

定制按键在:phoneWindowsManager.java里 尤其是没有虚拟键的手机,很可能要定制按键去解除屏幕固定。

编译后会输出到:Install: out/target/product/msm8916_64/system/framework/android.policy.jar

----------------------又是分割线----------

来说消极的:
这“然后还不准系统启动其他activity”但来一个很大的问题,就是你不能接电话了,没有任何提示,退出屏幕固定也没有来电记录。
还有个坑爹的,如果你屏幕固定的应用是“拨号”,那么恭喜你你能拨出去电话,但是因为不准启动其他Activity,所以你看不到正在拨号和正在通话的界面,这也就意味着你没法挂断电话。
over。

Comments
Write a Comment