第一次写微博 从现在开始写 为了重蹈覆辙过去的我 也是为了以后的纪念
现在已经出现的软件 微信 支付宝
他们所实现的锁屏很简单 就一个activity判断 呵呵 支付宝的更坑点就一个页面的判断 是很简单
但是如果一个应用程序有N个activity n个页面怎么实现呢 现在我们一起看看吧
* Author : Byron
如需转载请注明出处
1. 锁的逻辑
(1)service中循环检测启动的程序
(2)广播接收
(3)是否是自己的程序 有则弹出
(4)输入正确 如果程序运行到后台开始检测运行时弹出
LautchMode="SingleInstance"目的是覆盖应用
不足 仅用于5.0以下 包括现在的360和腾讯的安全卫士
本人文章创建时间为2016年1月13日11:10:54
现在讨论下5.0的锁不足
就拿360和腾讯的安全卫士的软件锁
存在的bug:应用打开 不能锁住 常常弹出锁屏页面的时候又被软件覆盖 因为SingleInstance在5.0以上覆盖不了应用了
2:所有版本4.0-xx手势锁会无效 复现条件 为
(1)打开360或者腾讯关键选择锁住的软件 去打开然间
(2)锁屏弹出 按Home键充Recent中移除 再去打开锁住的软件 发现软件锁无效 原因:软件被杀死 service也会被停止 2分钟左右如果内存足够 会重启service
以上的不足 足以说明 现在的软件锁几乎被改版的伤痕累累 抑郁而终。。
但是我最近就在实现 本软件4.0-xx版的支持
我狠心吧我写几天的service删除 打算页面实现
oncreate -onstart-onResume-onpuse-onstop-ondestory
onstart-检测是否开启软件锁有则弹出
当所有都onstop的时候通知下次开启软件锁
Sorry 这个不是可以的 这个只是理想中做梦的的想法 如果功能都那么好实现何必要人来实现呢
现在分析下逻辑吧
软件启动过程为Splash界面-主界面-主界面中可能有n个activity
分析:splash界面启动的时候不需要开启手势锁 原因:这时候开启 可能会被主页面覆盖掉手势锁 所以手势锁启动条件1 if(activity instanceOf SplashActivity) return;
2,splashActivity到-MainActicity-过程
splashActivity周期oncrate-onstart-onpuse-onstop-ondestory-MainActicity oncreate-start,,其实不是这样的
实际为 splashActivity-onpuse
MainActicity-oncreate
MainActicity-onstart
splashActivity-stop
splashActivity-desotory
这是进入一个activity 如果是不可见判断 是否下次Oncreate打开手势锁呢?
有点异想天开了 因为打开一个activity最后会走onstop
那么从二级页面退到一级页面又会经历什么周期呢 ,如果是手势锁开启它的周期会不会影响整个周期呢 如果是手势锁开启 输入正确 他也会走Onstop 又该怎么办呢 设置手势锁呢
哈哈 想必你我都烦躁了
我还是直接上代码吧 你们拿来用 有闲心的就看看 里面还是很复杂的
主要构建逻辑
分析任务栈--来判断是否开启 如果需要开启 开启之前的条件还有 是否打开手势锁 是否已经输入了 输入正确就没必要在弹出
首先创建 APPLication
Application 注释我就不写了 看不到的可以直接联系我Q10562080
private static Handler mainHandler;
private static Context mContext;
@Override public void onCreate() { super.onCreate(); initGesture(); mainHandler = new Handler(); this.mContext=getApplicationContext();public static Context getAppContext() { return mContext; } public static Handler getHandler(){ return mainHandler; } private void initGesture(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { this.registerActivityLifecycleCallbacks( new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState){ Log.e("onActivityCreated",activity.getClass().getSimpleName()); MyStack.addActivity(activity); GestureManager.getPassCodeManager().onActivityCreated(activity); } @Override public void onActivityStarted(Activity activity) { GestureManager.getPassCodeManager().onActivityStarted(activity); Log.e("onActivityStarted",activity.getClass().getSimpleName()); } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { GestureManager.getPassCodeManager().onActivityStopped(activity); } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { Log.e("onActivityDestroyed",activity.getClass().getSimpleName()); MyStack.removeActivity(activity); GestureManager.getPassCodeManager().onActivityDestroyed(activity); } }); }
}2 任务栈创建
import android.app.Activity; import android.util.Log; import java.util.LinkedList; /** * Description: * Copyright : Copyright (c) 2015 * Company : 望京soho * Author : Byron * Date : 2016/1/12 15:50 */ public class MyStack { private static final LinkedList<Activity> activityList = ObjectUtil.newLinkedList(); public static boolean HasActivityForward(Activity activity){ for (int i=0;i<activityList.size();i++){ Log.e("content",activity.getClass().getSimpleName()); if(activityList.get(i)==activity){ Log.e("activityList.size()",activityList.size()+""); try { activityList.get(i+1); }catch (Exception e){ return false; } } } return true; } public static void addActivity(Activity activity) { activityList.add(activity); } public static void removeActivity(Activity activity) { activityList.remove(activity); } }
3 实现逻辑 在Manager中import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Handler; import android.os.PowerManager; import android.util.Log; import android.view.WindowManager; HubActivity;
Splashctivity;主页的页面
GestureVerifyActivity //闪屏的页面
中锁屏的页面
import java.util.HashSet; import java.util.Set; /** * Description: * Copyright : Copyright (c) 2015 * Company : 望京soho * Author : Byron * Date : 2016/1/11 16:08 */ public class GestureManager { private static final Set<Class> sExemptOfPasscodeActivites; private boolean GestureClock=true; private Handler hanlder; private MyRunnable runnable=new MyRunnable(); static { sExemptOfPasscodeActivites = new HashSet<Class>(); sExemptOfPasscodeActivites.add(GestureVerifyActivity.class); } public static GestureManager mGestureManagerInstance = null; public static GestureManager getPassCodeManager() { if (mGestureManagerInstance == null) { mGestureManagerInstance = new GestureManager(); } return mGestureManagerInstance; } protected GestureManager() { hanlder=MamApp.getHandler(); }; public void onActivityCreated(Activity activity) { if (passCodeIsEnabled()) { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); } else { activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE); } } public void onActivityStarted(Activity activity) { Log.e("onActivityStarted",activity.getClass().getSimpleName()); if(passCodeIsEnabled()){ hanlder.removeCallbacks(runnable); }else{ return; } if(sExemptOfPasscodeActivites.contains(activity.getClass())||activity instanceof SplashScreenActivity){ return; } if(GestureClock){ //||!(activity instanceof SplashScreenActivity)&& ActivityStack.getInstance().get GestureClock=false; Intent i = new Intent(MamApp.getAppContext(), GestureVerifyActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activity.startActivity(i); GestureVerifyActivity.isClock=true; return; } } public void onActivityStopped(Activity activity) { if(sExemptOfPasscodeActivites.contains(activity.getClass())){ return; } PowerManager powerMgr = (PowerManager) activity.getSystemService(Context.POWER_SERVICE); if (passCodeIsEnabled() && powerMgr != null && !powerMgr.isScreenOn()) { activity.moveTaskToBack(true); } if(passCodeIsEnabled()){ if(MyStack.HasActivityForward(activity)){ ActivityStack.getInstance().getActivityListLength(); hanlder.removeCallbacks(runnable); }else{ if(! GestureVerifyActivity.isClock){ Log.e("开始准备锁屏","开始准备锁屏"); hanlder.postDelayed(runnable,60*2*1000); } } } } public void onActivityDestroyed(Activity activity) { if(passCodeIsEnabled()&&!(activity instanceof SplashScreenActivity)){ hanlder.removeCallbacks(runnable); Log.e("取消准备锁屏","取消准备锁屏"); GestureClock=false; } if(activity instanceof HubActivity){ GestureClock=true; } } private class MyRunnable implements Runnable{ @Override public void run() { GestureClock=true; } } private boolean passCodeIsEnabled() { // SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(MamApp.getAppContext()); SharedPreferences appPrefs = MamApp.getAppContext().getSharedPreferences("Setting", Context.MODE_PRIVATE); return (appPrefs.getBoolean("gestrueState", false)); } }