第一次写微博 从现在开始写 为了重蹈覆辙过去的我 也是为了以后的纪念
现在已经出现的软件 微信 支付宝
他们所实现的锁屏很简单 就一个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));
}
}