实现效果如下,上锁应用在桌面或最近任务打开弹出解锁界面,需要解锁成功才能打开应用。解锁界面可点击返回或Home键关闭,非上锁应用可直接打开。
基本思路:拦截系统应用启动,判断应用是否在锁住状态,弹出解锁Window。解锁完成后再正常启动应用。分为从桌面启动和最近任务启动两种情况。
1.资源的添加
在frameworks/base/core/res下增加了我的资源目录jia_res,添加了解锁界面用到的资源文件,文件目录如图。
需要在frameworks/base/core/res/Android.bp中添加引用:
android_app {
...
resource_dirs: ["res","jia_res"],
...
}
另外新增的资源需要在symbols.xml或pubulic.xml声明,例如:
<resources>
<java-symbol type="layout" name="window_unmber_unlock_app" />
<java-symbol type="id" name="appNumberLogoImg" />
<java-symbol type="id" name="appNumberNameText" />
<java-symbol type="id" name="subTitleNumber" />
<java-symbol type="id" name="pswNumberPointView" />
<java-symbol type="id" name="errorNumberTipsText" />
<java-symbol type="id" name="numberKeyView" />
<java-symbol type="string" name="lock_app_number_subtitle" />
<java-symbol type="string" name="lock_app_number_error_tip" />
<java-symbol type="drawable" name="ic_lock_delete" />
<java-symbol type="drawable" name="selector_keyboard_number" />
...
</resources>
2.拦截从桌面启动
之前分析过Activity启动流程 ,无论冷启动还是热启动都会先走ActivityStarter的startActivityMayWait方法,因此在此方法进行拦截:
private int startActivityMayWait( ...){
...
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
if (AppLockManager.isAppLocked(aInfo.packageName)) {
IApplicationThread caller1 = caller;
int callingUid1 = callingUid;
Intent intent1 = intent;
String resolvedType1 = resolvedType;
AppLockManager.ShowLockWindow(mService.mContext,aInfo.packageName, new Runnable() {
@Override
public void run() {
startActivityMayWait(caller1, callingUid1,
callingPackage, requestRealCallingPid, requestRealCallingUid,
intent1, resolvedType1, voiceSession,
voiceInteractor, resultTo, resultWho, requestCode,
startFlags, profilerInfo, outResult,
globalConfig, options, ignoreTargetSecurity,
userId, inTask, reason,