Reference:
https://developer.android.com/about/versions/android-5.0.html#ScreenPinninghttp://blog.csdn.net/aaa111/article/details/43866981
Abrtraction:
打開Screen pinning後,通知欄和狀態欄會隱藏起來,Home key和Recent app key會失效,而且不允許啟動其它activityHow to open/close screen pinning:
手動:從Settings -> Security -> Screen Pinning來釘選指定的app
同時長按 Back key和 Recent app key來關閉screen pinning
程式:
從app中呼叫startLockTask() 來釘選app。
若app不具有系統權限,則會跳出提示視窗,詢問使用者是否要執行Screen pinning
若app具有系統權限,可以直接呼叫setLockTaskPackages (ComponentName admin, String[] packages) ,省略詢問使用者的步驟
從app中呼叫stopLockTask()來關閉screen pinning
Source code:
Settings.packages/app/Settings/src/com/android/settings/ScreenPinningSettings.java
private void setLockToAppEnabled(boolean isEnabled) {
Settings.System.putInt(getContentResolver(), Settings.System.LOCK_TO_APP_ENABLED,
isEnabled ? 1 : 0);
}
framework/base
.frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
void startLockTaskMode(TaskRecord task) {
.frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
void setLockTaskModeLocked(TaskRecord task, boolean isLocked)
public void handleMessage(Message msg) {
......
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); // Show toast message
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;
.frameworks/base/services/core/java/com/android/server/am/LockTaskNotify.java
public void show(boolean starting) {
int showString = R.string.lock_to_app_exit;
if (starting) {
showString = R.string.lock_to_app_start;
}
Toast.makeText(mContext, mContext.getString(showString), Toast.LENGTH_LONG).show();
}
Related issue:
1. Toast messages are not displayed in screen pinning scenarios when accessed through other Users/Guest mode[Solution1]
.frameworks/base/core/java/android/widget/Toast.java
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+ // Support multi-user
+ params.privateFlags =
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; }
[Solution2]
https://android.googlesource.com/platform/frameworks/base/+/a585268aff94b620b2c22e9ba3ae1163bb5dc8a8%5E%21/#F1
.frameworks/base/core/java/android/widget/Toast.java
public int getYOffset() {
return mTN.mY;
}
+
+ /**
+ * Gets the LayoutParams for the Toast window.
+ * @hide
+ */
+ public WindowManager.LayoutParams getWindowParams() {
+ return mTN.mParams;
+ }
.frameworks/base/services/core/java/com/android/server/am/LockTaskNotify.java
import android.content.Context;
import android.os.Handler;
import android.os.Message;
+import android.view.WindowManager; import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
@@ -56,8 +57,7 @@
if (mLastToast != null) {
mLastToast.cancel();
}
- mLastToast = Toast.makeText(mContext, text, Toast.LENGTH_LONG);
- mLastToast.show();
+ mLastToast = makeAllUserToastAndShow(text); }
public void show(boolean starting) {
@@ -65,7 +65,15 @@
if (starting) {
showString = R.string.lock_to_app_start;
}
- Toast.makeText(mContext, mContext.getString(showString), Toast.LENGTH_LONG).show();+ makeAllUserToastAndShow(mContext.getString(showString));
+ }
+
+ private Toast makeAllUserToastAndShow(String text) {
+ Toast toast = Toast.makeText(mContext, text, Toast.LENGTH_LONG);
+ toast.getWindowParams().privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ toast.show();
+ return toast; }
沒有留言:
張貼留言