手势密码

Activity基类


public class BaseActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        MyActivityManager.getInstance().push(this);

    }

    @Override

    protected void onStop() {

        super.onStop();

        //判断是否进入后台,如果是则重新存储退到后台的时间

        if (!GestureUtils.isAppOnForeground(this)) {

            GestureUtils.clearEnterTime(this);

            GestureUtils.setAppOnBackgroundTime(this, System.currentTimeMillis());

        }

    }

    @Override

    protected void onResume() {

        super.onResume();

        Log.i("bqt", "++++++"+ GestureActivity.class.getName() );

        if (GestureUtils.isAppOnForeground(this) //APP返回前台

                && !GestureUtils.isActivityOnForeground(this, GestureActivity.class.getName()) //GestureActivity不在前台(防止出现多个输入密码界面)

                && GestureUtils.isLongerThanSomeSecond(this, 10) //退到后台时间超过10秒钟

                && GestureUtils.isHasGesturePassword(this)) {//存在手势密码

            GestureActivity.launche(BaseActivity.this, false, false);

        }

    }

}

MainActivity


public class MainActivity extends BaseActivity {

    private Switch switch_gesture;

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        switch_gesture = new Switch(this);

        setContentView(switch_gesture);

        if (!GestureUtils.getGesturePassword(this).isEmpty()) GestureActivity.launche(MainActivity.this, false, true);

    }

    @Override

    protected void onResume() {

        super.onResume();

        switch_gesture.setOnCheckedChangeListener(null);

        //如果手势密码不为空,则设置为打开状态

        boolean isHasPassword = !GestureUtils.getGesturePassword(this).isEmpty();

        switch_gesture.setChecked(isHasPassword);

        switch_gesture.setText("选中状态:" + isHasPassword + ",密码:" + GestureUtils.getGesturePassword(this));

        switch_gesture.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override

            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {

                Log.i("bqt", "状态值" + isChecked);

                if (isChecked) GestureActivity.launche(MainActivity.this, true, false);//去设置手势密码

                else GestureActivity.launche(MainActivity.this, true, true);//去清除手势密码

            }

        });

    }

}

手势密码Activity


public class GestureActivity extends BaseActivity implements View.OnClickListener, GestureDrawline.GestureCallBack {

    /**

     * 是否是从设置密码那里来的(包括设置密码和关闭密码)

     */

    private boolean isSettingPasswd = false;

    /**

     * 是否是清除密码

     */

    private boolean isClearPasswd = false;

    private FrameLayout body_layout;

    private GestureContentView content;

    private TextView tv_description; //设置时的提示和输入手势密码时的手机号码

    private TextView tv_forget; //忘记密码

    private String password; //暂存密码

    public static void launche(Context context, boolean isSettingPasswd, boolean isClearPasswd) {

        Intent intent = new Intent(context, GestureActivity.class);

        intent.putExtra("isSettingPasswd", isSettingPasswd);

        intent.putExtra("isClearPasswd", isClearPasswd);

        context.startActivity(intent);

    }

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_gesture_lock);

        Intent intent = getIntent();

        if (intent != null) {

            isSettingPasswd = intent.getBooleanExtra("isSettingPasswd", false);

            isClearPasswd = intent.getBooleanExtra("isClearPasswd", false);

        }

        body_layout = (FrameLayout) findViewById(R.id.body_layout);

        tv_description = (TextView) findViewById(R.id.tv_description);

        tv_forget = (TextView) findViewById(R.id.tv_forget);

        tv_forget.setOnClickListener(this);

        //表示设置手势密码

        if (isSettingPasswd) {

            tv_description.setTextColor(Color.GRAY);

            if (isClearPasswd) {

                tv_description.setText("请输入解锁图案");

                tv_forget.setVisibility(View.VISIBLE);

                content = new GestureContentView(this, GestureUtils.getGesturePassword(this), this);//输入手势密码的构造器

            } else {

                tv_description.setText("请绘制解锁图案");

                tv_forget.setVisibility(View.GONE);

                content = new GestureContentView(this, null, this);//设置手势密码时的构造器

            }

        } else {//表示需要输入手势密码

            tv_description.setTextColor(Color.RED);

            tv_description.setText("请滑动输入解锁图案");

            tv_forget.setVisibility(View.VISIBLE);

            content = new GestureContentView(this, GestureUtils.getGesturePassword(this), this);//输入手势密码的构造器

        }

        //设置手势解锁显示到哪个布局里面

        content.setParentView(body_layout);

    }

    @Override

    protected void onDestroy() {

        super.onDestroy();

        GestureUtils.clearEnterTime(this);//清空进入后台时间

    }

    @Override

    public void onBackPressed() {

        if (isSettingPasswd) finish();

        else showExitAlertDialog();

    }

    @Override

    public void onClick(View v) {

        switch (v.getId()) {

        case R.id.tv_forget:

            showClearAlertDialog();

            break;

        default:

            break;

        }

    }

    //************************************************************************************************************************************

    @Override

    public void checkedSuccess() {

        Log.i("bqt", "checkedSuccess");

        if (isSettingPasswd) {

            if (isClearPasswd) {

                Toast.makeText(GestureActivity.this, "手势密码已解除", Toast.LENGTH_SHORT).show();

                GestureUtils.setGesturePassword(this, "");

            } else {

                Toast.makeText(GestureActivity.this, "手势密码设置成功", Toast.LENGTH_SHORT).show();

                GestureUtils.setGesturePassword(this, password);

            }

        }

        finish();

    }

    @Override

    public void checkedFail() {

        Log.i("bqt", "checkedFail");

        if (isSettingPasswd) {

            tv_description.setTextColor(Color.RED);

            tv_description.setText("与上次绘制不一致,请重新绘制");

        } else {

            tv_description.setTextColor(Color.RED);

            tv_description.setText("输入密码错误");

        }

    }

    @Override

    public void settingPasswdSuccess(StringBuilder stringBuilder, boolean settingPasswdStatus) {

        Log.i("bqt", "settingPasswdSuccess-" + settingPasswdStatus);

        if (settingPasswdStatus) {//密码输入超过四个数

            if (isSettingPasswd) {

                tv_description.setTextColor(Color.GRAY);

                tv_description.setText("请再次绘制解锁图案");

                password = stringBuilder.toString();

            }

        } else {//密码输入不足四个数

            tv_description.setTextColor(Color.RED);

            tv_description.setText("请连接至少4个点");

        }

    }

    @Override

    public void choseNewPoint(StringBuilder stringBuilder) {

        tv_description.setTextColor(Color.GRAY);

        tv_description.setText("已选中" + stringBuilder.toString().length() + "个点");

    }

    //******************************************************************************************

    //退出登录,清空当前用户的信息

    private void showClearAlertDialog() {

        AlertDialog.Builder builder = new AlertDialog.Builder(this).setTitle("提示").setMessage("退出账号可以解除密码保护");

        builder.setNegativeButton("取消", null);

        builder.setPositiveButton("退出", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialogInterface, int i) {

                GestureUtils.setGesturePassword(GestureActivity.this, "");

                finish();

            }

        });

        builder.show();

    }

    //提示是否退出APP

    private void showExitAlertDialog() {

        AlertDialog.Builder builder = new AlertDialog.Builder(this).setTitle("提示").setMessage("确定要退出福利金融吗?");

        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {

            @Override

            public void onClick(DialogInterface dialog, int which) {

                MyActivityManager.getInstance().finishAllActivity();

            }

        });

        builder.setNegativeButton("取消", null);

        builder.show();

    }

}

任务栈工具类


public class MyActivityManager {

    private static MyActivityManager instance;

    private Stack<Activity> activityStack; //用于管理activityStack的栈

    private MyActivityManager() {

    }

    //单例模式

    public static MyActivityManager getInstance() {

        if (instance == null) instance = new MyActivityManager();

        return instance;

    }

    //入栈

    public void push(Activity activity) {

        if (activityStack == null) activityStack = new Stack<Activity>();

        //******************************************************************************************

        for (int i = 0; i < activityStack.size(); i++) {

            if (activity == activityStack.get(i)) return;

        }

        //******************************************************************************************

        activityStack.add(activity);

    }

    //出栈

    public void pop(Activity activity) {

        if (activityStack != null && activityStack.size() > 0 && activity != null) {

            activity.finish();

            activityStack.remove(activity);

            activity = null;

        }

    }

    //获取栈顶的activity,先进后出原则

    public Activity getLastActivity() {

        if (activityStack == null || activityStack.size() == 0) return null;

        return activityStack.lastElement();

    }

    //退出所有activity

    public void finishAllActivity() {

        if (activityStack != null) {

            while (activityStack.size() > 0) {

                Activity activity = getLastActivity();

                if (activity == null) break;

                pop(activity);

            }

        }

    }

    //获取Stack

    public Stack<Activity> getActivityStack() {

        return activityStack;

    }

    //获取Stack中元素的名称(含包名)

    public List<String> getActivityNameList() {

        if (activityStack != null) {

            List<String> list = new ArrayList<String>();

            for (int i = 0; i < activityStack.size(); i++) {

                Activity activity = activityStack.get(i);

                if (activity != null) list.add(activity.getClass().getName());

            }

            return list;

        } else return null;

    }

}

要绘制的线


/**

 * 手势密码路径绘制

 */

public class GestureDrawline extends View {

    private Context mContext;

    /**声明起点坐标     */

    private int mov_x;

    private int mov_y;

    private Paint paint;

    private Canvas canvas;

    private Bitmap bitmap;

    /**装有各个view坐标的集合     */

    private List<GesturePoint> list;

    /**记录画过的线     */

    private List<Pair<GesturePoint, GesturePoint>> lineList;

    /**判断是否设置手势密码     */

    private boolean isSettingPasswd = false;

    /**手指当前在哪个GesturePoint内     */

    private GesturePoint currentGesturePoint;

    /**用户绘图的回调     */

    private GestureCallBack callBack;

    /**用户当前绘制的图形密码     */

    private StringBuilder passWordSb;

    /**用户传入的passWord */

    private String passWord;

    /**自动选中的情况点*/

    private Map<String, GesturePoint> autoCheckPointMap;

    public GestureDrawline(Context context, List<GesturePoint> list, String passWord, GestureCallBack callBack) {

        super(context);

        mContext = context;

        this.list = list;

        this.passWord = passWord;

        this.callBack = callBack;

        //******************************************************************************************

        this.lineList = new ArrayList<Pair<GesturePoint, GesturePoint>>();

        if (passWord == null || passWord.equals("")) isSettingPasswd = true;

        else isSettingPasswd = false;

        //初始化密码缓存

        this.passWordSb = new StringBuilder();

        //******************************************************************************************

        //屏幕宽高

        DisplayMetrics metric = new DisplayMetrics();

        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

        wm.getDefaultDisplay().getMetrics(metric);

        bitmap = Bitmap.createBitmap(metric.widthPixels, metric.heightPixels, Bitmap.Config.ARGB_8888);

        canvas = new Canvas();

        canvas.setBitmap(bitmap);

        paint = new Paint(Paint.DITHER_FLAG);

        paint.setStyle(Paint.Style.STROKE);

        paint.setStrokeWidth(GestureUtils.dp2px(context, 2f));

        paint.setColor(Color.rgb(219, 56, 56));// 设置默认连线颜色

        paint.setAntiAlias(true);

        initAutoCheckPointMap();//自动选中某些点

    }

    private void initAutoCheckPointMap() {

        autoCheckPointMap = new HashMap<String, GesturePoint>();

        autoCheckPointMap.put("1,3", getGesturePointByNum(2));

        autoCheckPointMap.put("1,7", getGesturePointByNum(4));

        autoCheckPointMap.put("1,9", getGesturePointByNum(5));

        autoCheckPointMap.put("2,8", getGesturePointByNum(5));

        autoCheckPointMap.put("3,7", getGesturePointByNum(5));

        autoCheckPointMap.put("3,9", getGesturePointByNum(6));

        autoCheckPointMap.put("4,6", getGesturePointByNum(5));

        autoCheckPointMap.put("7,9", getGesturePointByNum(8));

    }

    private GesturePoint getGesturePointByNum(int num) {

        for (GesturePoint point : list) {

            if (point.getNum() == num) return point;

        }

        return null;

    }

    // 画位图

    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        canvas.drawBitmap(bitmap, 0, 0, null);

    }

    // 触摸事件

    @Override

    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {

        //手指按下的时候

        case MotionEvent.ACTION_DOWN:

            mov_x = (int) event.getX();

            mov_y = (int) event.getY();

            // 判断当前点击的位置是处于哪个点之内    

            currentGesturePoint = getGesturePointAt(mov_x, mov_y);

            if (currentGesturePoint != null) {

                currentGesturePoint.setHighLighted(true);

                passWordSb.append(currentGesturePoint.getNum());

                callBack.choseNewPoint(passWordSb);//******************************************************************************************

            }

            // canvas.drawGesturePoint(mov_x, mov_y, paint);// 画点

            break;

        //手指移动的时候

        case MotionEvent.ACTION_MOVE:

            clearScreenAndDrawList();

            // 得到当前移动位置是处于哪个点内

            GesturePoint gesturePointAt = getGesturePointAt((int) event.getX(), (int) event.getY());

            //代表当前用户手指处于点与点之前

            if (currentGesturePoint == null && gesturePointAt == null) {

                return true;

            } else {//代表用户的手指移动到了点上

                if (currentGesturePoint == null) {//先判断当前的GesturePoint是不是为null

                    //如果为空,那么把手指移动到的点赋值给currentGesturePoint

                    currentGesturePoint = gesturePointAt;

                    //把currentGesturePoint这个点设置选中为true;

                    currentGesturePoint.setHighLighted(true);

                    passWordSb.append(currentGesturePoint.getNum());

                }

            }

            // 点击移动区域不在圆的区域,或者如果当前点击的点与当前移动到的点的位置相同,那么以当前的点中心为起点,以手指移动位置为终点画线

            if (gesturePointAt == null || currentGesturePoint.equals(gesturePointAt) || gesturePointAt.isHighLighted()) {

                canvas.drawLine(currentGesturePoint.getCenterX(), currentGesturePoint.getCenterY(),//

                        event.getX(), event.getY(), paint);

            } else { // 如果当前点击的点与当前移动到的点的位置不同,那么以前前点的中心为起点,以手移动到的点的位置画线

                canvas.drawLine(currentGesturePoint.getCenterX(), currentGesturePoint.getCenterY(), //

                        gesturePointAt.getCenterX(), gesturePointAt.getCenterY(), paint);

                gesturePointAt.setHighLighted(true);

                // 判断是否中间点需要选中

                GesturePoint betweenPoint = getBetweenCheckPoint(currentGesturePoint, gesturePointAt);

                if (betweenPoint != null && !betweenPoint.isHighLighted()) {

                    // 存在中间点并且没有被选中

                    Pair<GesturePoint, GesturePoint> pair1 = new Pair<GesturePoint, GesturePoint>(currentGesturePoint, betweenPoint);

                    lineList.add(pair1);

                    passWordSb.append(betweenPoint.getNum());

                    Pair<GesturePoint, GesturePoint> pair2 = new Pair<GesturePoint, GesturePoint>(betweenPoint, gesturePointAt);

                    lineList.add(pair2);

                    passWordSb.append(gesturePointAt.getNum());

                    // 设置中间点选中

                    betweenPoint.setHighLighted(true);

                    // 赋值当前的point;

                    currentGesturePoint = gesturePointAt;

                } else {

                    Pair<GesturePoint, GesturePoint> pair = new Pair<GesturePoint, GesturePoint>(currentGesturePoint, gesturePointAt);

                    lineList.add(pair);

                    // 赋值当前的GesturePoint;

                    currentGesturePoint = gesturePointAt;

                    passWordSb.append(currentGesturePoint.getNum());

                }

                callBack.choseNewPoint(passWordSb);//******************************************************************************************

            }

            break;

        // 当手指抬起的时候, 清掉屏幕上所有的线,只画上集合里面保存的线

        case MotionEvent.ACTION_UP:

            //代表输入的密码与用户密码相同

            if (passWordSb.toString().length() < 4) {

                callBack.settingPasswdSuccess(passWordSb, false);//******************************************************************************************

            } else if (!isSettingPasswd && passWord.equals(passWordSb.toString())) {

                callBack.checkedSuccess();//******************************************************************************************

            } else if (isSettingPasswd) {

                isSettingPasswd = false;

                passWord = passWordSb.toString();

                //缓存密码回调,用于保存密码

                callBack.settingPasswdSuccess(passWordSb, true);//******************************************************************************************

            } else { //用户绘制的密码与传入的密码不同

                callBack.checkedFail();//******************************************************************************************

            }

            //重置passWordSb

            passWordSb = new StringBuilder();

            //清空保存点的集合

            lineList.clear();

            //重新绘制界面

            clearScreenAndDrawList();

            for (GesturePoint p : list) {

                p.setHighLighted(false);

            }

            break;

        default:

            break;

        }

        invalidate();

        return true;

    }

    /**

     * 通过点的位置去集合里面查找这个点是包含在哪个GesturePoint里面的

     * @return 如果没有找到,则返回null,代表用户当前移动的地方属于点与点之间

     */

    private GesturePoint getGesturePointAt(int x, int y) {

        for (GesturePoint GesturePoint : list) {

            // 先判断x

            int leftX = GesturePoint.getLeftX();

            int rightX = GesturePoint.getRightX();

            if (!(x >= leftX && x < rightX)) {

                // 如果为假,则跳到下一个对比

                continue;

            }

            int topY = GesturePoint.getTopY();

            int bottomY = GesturePoint.getBottomY();

            if (!(y >= topY && y < bottomY)) {

                // 如果为假,则跳到下一个对比

                continue;

            }

            // 如果执行到这,那么说明当前点击的点的位置在遍历到点的位置这个地方

            return GesturePoint;

        }

        return null;

    }

    private GesturePoint getBetweenCheckPoint(GesturePoint pointStart, GesturePoint pointEnd) {

        int startNum = pointStart.getNum();

        int endNum = pointEnd.getNum();

        String key = null;

        if (startNum < endNum) {

            key = startNum + "," + endNum;

        } else {

            key = endNum + "," + startNum;

        }

        return autoCheckPointMap.get(key);

    }

    /**清掉屏幕上所有的线,然后画出集合里面的线 */

    private void clearScreenAndDrawList() {

        canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

        for (Pair<GesturePoint, GesturePoint> pair : lineList) {

            canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY(), pair.second.getCenterX(), pair.second.getCenterY(), paint);// 画线

        }

    }

    //******************************************************************************************

    /**是否设置手势密码 */

    public void setSettingPasswd(boolean isSettingPasswd) {

        this.isSettingPasswd = isSettingPasswd;

    }

    public boolean getSettingPasswdStatus() {

        return isSettingPasswd;

    }

    /**手势回调*/

    public interface GestureCallBack {

        /**代表用户绘制的密码与传入的密码相同 */

        public abstract void checkedSuccess();

        /**代表用户绘制的密码与传入的密码不相同 */

        public abstract void checkedFail();

        /**用户设置/输入了手势密码*/

        public abstract void settingPasswdSuccess(StringBuilder stringBuilder, boolean settingPasswdStatus);

        /**用户设置/输入了手势密码过程中新选中了一个点*/

        public abstract void choseNewPoint(StringBuilder stringBuilder);

    }

}

要绘制的点


/**

 * 绘制的点

 * @author 白乾涛

 */

public class GesturePoint {

    /**

    * 左边x的值

    */

    private int leftX;

    /**

     * 右边x的值

     */

    private int rightX;

    /**

     * 上边y的值

     */

    private int topY;

    /**

     * 下边y的值

     */

    private int bottomY;

    /**

     * 这个点对应的ImageView控件

     */

    private ImageView image;

    /**

     * 中心x值

     */

    private int centerX;

    /**

     * 中心y值

     */

    private int centerY;

    /**

     * 是否是高亮(划过),仅用于确定背景图片

     */

    private boolean highLighted;

    /**

     * 代表这个Point对象代表的数字,从1开始

     */

    private int num;

    public GesturePoint(int leftX, int rightX, int topY, int bottomY, ImageView image, int num) {

        super();

        this.leftX = leftX;

        this.rightX = rightX;

        this.topY = topY;

        this.bottomY = bottomY;

        this.image = image;

        this.num = num;

        this.centerX = (leftX + rightX) / 2;

        this.centerY = (topY + bottomY) / 2;

    }

    /**

     * 判断是否是相同的点

     */

    @Override

    public boolean equals(Object obj) {

        if (obj == null || !(obj instanceof GesturePoint)) return false;//类型不对

        GesturePoint other = (GesturePoint) obj;

        if (bottomY != other.bottomY || leftX != other.leftX || rightX != other.rightX || topY != other.topY) return false;//位置不对

        if ((image == null && other.image != null) || !image.equals(other.image)) return false;//图片不对(状态不对)

        return true;

    }

    @Override

    public int hashCode() {

        final int prime = 31;

        int result = 1;

        result = prime * result + bottomY;

        result = prime * result + ((image == null) ? 0 : image.hashCode());

        result = prime * result + leftX;

        result = prime * result + rightX;

        result = prime * result + topY;

        return result;

    }

    @Override

    public String toString() {

        return "Point [leftX=" + leftX + ", rightX=" + rightX + ", topY=" + topY + ", bottomY=" + bottomY + "]";

    }

    //******************************************************************************************

    public void setHighLighted(boolean highLighted) {

        this.highLighted = highLighted;

        if (highLighted) this.image.setBackgroundResource(R.drawable.gesture_node_highlighted);

        else this.image.setBackgroundResource(R.drawable.gesture_node_default);

    }

    public boolean isHighLighted() {

        return highLighted;

    }

    //******************************************************************************************

    public int getLeftX() {

        return leftX;

    }

    public void setLeftX(int leftX) {

        this.leftX = leftX;

    }

    public int getRightX() {

        return rightX;

    }

    public void setRightX(int rightX) {

        this.rightX = rightX;

    }

    public int getTopY() {

        return topY;

    }

    public void setTopY(int topY) {

        this.topY = topY;

    }

    public int getBottomY() {

        return bottomY;

    }

    public void setBottomY(int bottomY) {

        this.bottomY = bottomY;

    }

    public ImageView getImage() {

        return image;

    }

    public void setImage(ImageView image) {

        this.image = image;

    }

    public int getCenterX() {

        return centerX;

    }

    public void setCenterX(int centerX) {

        this.centerX = centerX;

    }

    public int getCenterY() {

        return centerY;

    }

    public void setCenterY(int centerY) {

        this.centerY = centerY;

    }

    public int getNum() {

        return num;

    }

    public void setNum(int num) {

        this.num = num;

    }

}

手势密码的容器


/**

 * 手势密码容器类

 */

public class GestureContentView extends ViewGroup {

    private int contentWidth;//9个点所在父控件的大小

    private int eachWith; //图片半径

    private int margin; //间距

    /**

     * 声明一个集合用来封装坐标集合

     */

    private List<GesturePoint> list;

    private Context context;

    private GestureDrawline gestureDrawline;

    private boolean isSettingPasswd;

    /**

     * 包含9个手势点的容器

     * @param context

     * @param passWord 用户传入密码,当为设置手势密码时可传入null或""

     * @param callBack 手势绘制完毕的回调

     */

    public GestureContentView(Context context, String passWord, GestureDrawline.GestureCallBack callBack) {

        super(context);

        this.context = context;

        if (passWord == null || passWord.equals("")) isSettingPasswd = true;

        else isSettingPasswd = false;

        contentWidth = GestureUtils.getScreenWidth(context);

        eachWith = contentWidth / 12;

        margin = (contentWidth - eachWith * 3 * 2) / 4;

        this.list = new ArrayList<GesturePoint>();

        // 添加9个图标

        addChild();

        // 初始化一个可以画线的view

        if (isSettingPasswd) {

            gestureDrawline = new GestureDrawline(context, list, null, callBack);

        } else {

            gestureDrawline = new GestureDrawline(context, list, passWord, callBack);

        }

    }

    //添加子元素

    private void addChild() {

        for (int i = 0; i < 9; i++) {

            ImageView image = new ImageView(context);

            image.setBackgroundResource(R.drawable.gesture_node_default);

            this.addView(image);

            // 定义点的上下左右位置

            int row = i / 3;// 第几行

            int col = i % 3;// 第几列

            int leftX = col * (2 * eachWith + margin) + margin;

            int topY = row * (2 * eachWith + margin) + margin;

            int rightX = (col + 1) * (2 * eachWith + margin);

            int bottomY = (row + 1) * (2 * eachWith + margin);

            GesturePoint p = new GesturePoint(leftX, rightX, topY, bottomY, image, i + 1);

            this.list.add(p);

        }

    }

    @Override

    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        for (int i = 0; i < getChildCount(); i++) {

            int row = i / 3;//第几行

            int col = i % 3;//第几列

            View v = getChildAt(i);

            //布局每个子元素的大小和位置

            v.layout(col * (2 * eachWith + margin) + margin, row * (2 * eachWith + margin) + margin, (col + 1) * (2 * eachWith + margin), (row + 1)

                    * (2 * eachWith + margin));

        }

    }

    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        for (int i = 0; i < getChildCount(); i++) {

            View v = getChildAt(i);

            v.measure(widthMeasureSpec, heightMeasureSpec);

        }

    }

    //******************************************************************************************

    //设置父界面

    public void setParentView(ViewGroup parent) {

        LayoutParams layoutParams = new LayoutParams(contentWidth, contentWidth);

        this.setLayoutParams(layoutParams);

        gestureDrawline.setLayoutParams(layoutParams);

        parent.addView(gestureDrawline);

        parent.addView(this);

    }

    //设置是否用于设置手势密码

    public void setGesturePassword(boolean status) {

        gestureDrawline.setSettingPasswd(status);

    }

    //获取是否设置手势密码的状态

    public boolean getGesturePassword() {

        return gestureDrawline.getSettingPasswdStatus();

    }

}

手势密码工具类


public class GestureUtils {

    public static final String Gesture_FILE_NAME = "gesture";

    public static final String Gesture_KEY_NAME = "GesturePassword" + "|" + "";//可以为每个账户设置一个独立的手势密码

    private static final String ENTER_BACKGROUND_FILE_NAME = "App_Enter_Background_Time";

    private static final String ENTER_BACKGROUND_KEY_NAME = "AppOnBackGround";

    /**

     * dp 转成为 px

     */

    public static int dp2px(Context context, float dpValue) {

        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());

    }

    /**  获取屏幕宽  */

    public static int getScreenWidth(Context context) {

        DisplayMetrics metric = new DisplayMetrics();

        ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metric);

        return metric.widthPixels;

    }

    /**

     * 获取手势密码

     */

    public static String getGesturePassword(Context context) {

        SharedPreferences sp = context.getSharedPreferences(Gesture_FILE_NAME, Context.MODE_PRIVATE);

        return sp.getString(Gesture_KEY_NAME, "");

    }

    /**

     * 设置手势密码

     */

    public static void setGesturePassword(Context context, String gesturePassword) {

        SharedPreferences sp = context.getSharedPreferences(Gesture_FILE_NAME, Context.MODE_PRIVATE);

        Editor editor = sp.edit();

        editor.putString(Gesture_KEY_NAME, gesturePassword);

        editor.commit();

    }

    /**

     * 清除手势密码--注意,这会清除所有账户设置的手势密码

     */

    public static void clearGesturePassword(Context context, String gesturePassword) {

        SharedPreferences sp = context.getSharedPreferences(Gesture_FILE_NAME, Context.MODE_PRIVATE);

        Editor editor = sp.edit();

        editor.clear();

        editor.commit();

    }

    /**

     * 判断是否存在手势密码

     */

    public static boolean isHasGesturePassword(Context context) {

        return !getGesturePassword(context).isEmpty();//当且仅当 length() 为 0 时返回 true

    }

    /**

     * 记录进入后台时间

     */

    public static void setAppOnBackgroundTime(Context context, long time) {

        SharedPreferences sp = context.getSharedPreferences(ENTER_BACKGROUND_FILE_NAME, Context.MODE_PRIVATE);

        SharedPreferences.Editor editor = sp.edit();

        editor.putLong(ENTER_BACKGROUND_KEY_NAME, time);

        editor.commit();

    }

    /**

     * 获取上一次进入后台的时间

     */

    public static long getAppOnBackgroundTIme(Context context) {

        SharedPreferences sp = context.getSharedPreferences(ENTER_BACKGROUND_FILE_NAME, Context.MODE_PRIVATE);

        return sp.getLong(ENTER_BACKGROUND_KEY_NAME, 0);

    }

    /**

     * 清除缓存的进入后台的时间

     */

    public static void clearEnterTime(Context context) {

        SharedPreferences sp = context.getSharedPreferences(ENTER_BACKGROUND_FILE_NAME, Context.MODE_PRIVATE);

        SharedPreferences.Editor editor = sp.edit();

        editor.clear();

        editor.commit();

    }

    /**

     * 判断程序是否在前台运行

     */

    public static boolean isAppOnForeground(Context context) {

        ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);

        String packageName = context.getApplicationContext().getPackageName();

        List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();

        if (appProcesses == null) return false;

        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {

            if (appProcess.processName.equals(packageName) && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) return true;

        }

        return false;

    }

    /**

     * 判断某个界面是否在前台,即判断当前Activity是否在最顶层,权限android.permission.GET_TASKS

     */

    public static boolean isActivityOnForeground(Context context, String className) {

        if (context == null || TextUtils.isEmpty(className)) return false;

        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        @SuppressWarnings("deprecation")

        List<RunningTaskInfo> list = am.getRunningTasks(1);

        if (list != null && list.size() > 0) {

            ComponentName cpn = list.get(0).topActivity;

            Log.i("bqt", "222++++++"+ cpn.getClassName() );

            if (className.equals(cpn.getClassName())) {

                return true;

            }

        }

        return false;

    }

    /**

     * 判断程序退到后台是否超过指定秒

     */

    public static boolean isLongerThanSomeSecond(Context context, int second) {

        long curTime = System.currentTimeMillis();

        long appEnterBackgroundTime = getAppOnBackgroundTIme(context);

        if (appEnterBackgroundTime != 0 && ((curTime - appEnterBackgroundTime) / 1000) >= second) return true;

        return false;

    }

}

来自为知笔记(Wiz)

附件列表

时间: 2024-10-20 07:40:53

手势密码的相关文章

[优化]Swift 简简单单实现手机九宫格手势密码 解锁

我去 为毛这篇文章会被移除首页 技术含量还是有点的   如果在此被移除  那就果断离开园子了 之前的文章 Swift 简简单单实现手机九宫格手势密码解锁 1.对之前的绘制线条的方法进行优化 之前是遍历选中点的集合分别的在点之间绘制线条 改进之后使用系统的API一口气将线条绘制出来 2.增加密码错误情况下想某宝一样红色提示和三角形状的路线指示如下图所示 3.遇到的难点主要是三角形的绘制 和 旋转角度的功能 原理就不多说了 真相见代码 转载需要注明出处 http://www.cnblogs.com/

空间手势密码的实现

一.团队介绍 首先还是要介绍一下我们的团队.我们的队名是"来不及了快上车".队长:黄玥.成员:谢园,宋丰年,潘子帅,张帆,高宇轩. 这里是所有队员的链接: 黄玥:http://www.cnblogs.com/hy1234/ 谢园:http://www.cnblogs.com/KKKA/ 宋丰年:http://www.cnblogs.com/Iriya/ 潘子帅:http://www.cnblogs.com/ss961011/ 张帆:http://www.cnblogs.com/ZFyo

Andriod手势密码破解

★ 引子 之前在Freebuf上看到一片文章讲Andriod的手势密码加密原理,觉得比较有意思,所以就写了一个小程序试试. ★ 原理            Android的手势密码加密原理很简单: 先给屏幕上的每一个点编号(一般是 3 X 3): 00,01,02 03,04,05 06,07,08 注意这里的数字都是十六进制. 假设我沿着左边和下边画了一个 L 字,则手势的点排列顺序 sequence 是 00,03,06,07,08. 然后计算密文 C = SHA-1(sequence),然

HTML5 Canvas简简单单实现手机九宫格手势密码解锁

原文:HTML5 Canvas简简单单实现手机九宫格手势密码解锁 早上花了一个半小时写了一个基于HTML Canvas的手势解锁,主要是为了好玩,可能以后会用到. 思路:根据配置计算出九个点的位置,存入一个数组,当然存入数组的顺序的索引是: 第一行:0   1  2   第二行:3  4  5 第三行:6  7  8 然后就根据这个坐标数组去绘制九个点 再则我们需要一个保存选中点的数组,每当touchmove事件就判断当前触摸点和那个点的距离小于圆的半径  如果为真的话 那么就添加进入选中点的数

支付宝钱包手势密码破解实战

背景 随着移动互联网的普及以及手机屏幕越做越大等特点,在移动设备上购物.消费已是人们不可或缺的一个生活习惯了.随着这股浪潮的兴起,安全.便捷的移动支付需求也越来越大.因此,各大互联网公司纷纷推出了其移动支付平台.其中,用的比较多的要数腾讯的微信和阿里的支付宝钱包了.就我而言,平时和同事一起出去AA吃饭,下班回家打车等日常生活都已经离不开这两个支付平台了. 正所谓树大招风,移动支付平台的兴起,也给众多一直徘徊在网络阴暗地带的黑客们又一次重生的机会.因为移动平台刚刚兴起,人们对移动平台的安全认识度还

iOS下的手势密码实现

一.iOS下的手势 1 #import "ViewController.h" 2 3 @interface ViewController () 4 5 @property (weak, nonatomic) IBOutlet UILabel *genstureLabel; 6 7 8 @end 9 10 @implementation ViewController 11 12 - (void)viewDidLoad { 13 [super viewDidLoad]; 14 15 16

Android例子源码仿支付宝手势密码的功能实现

本项目是一个仿支付宝手势密码部分的源码,项目在1280×720分辨率上显示有问题,在 854x480上没有问题,项目编码UTF-8默认编译版本4.4.2,实现思路: 1.要用一个类来表示这9个点中的第一个点.里面保留有当前点的上下左右的各个位置等属性: 2.自定义GroupView,用来装9个点,9个点的显示是通过ImageView.复写onLayout这个方法,让点按需求排列: 3.定义一个可以画线的View,复写onTouchEvent方法,在这个方法里面进行画直线的操作: 4.判断用户手指

Swift 简简单单实现手机九宫格手势密码解锁

大家可以看到我之前的文章[HTML5 Canvas简简单单实现手机九宫格手势密码解锁] 本文是使用苹果语言对其进行了移植 颜色配色是拾取的支付宝的颜色 本文的目的说明:语言是想通的  只要思路在 语言只是手段而已 这是本人自学swift一个礼拜 然后花了三个小时写出来的肯定会有不规范的地方 因为思路比较简单 大家可以参考 javascript 版本 废话不多说先上效果 (对了 大家如果能在转载的地方注明出处的话 那就是极好的 http://www.cnblogs.com/zzzzz/p/swif

支付宝钱包手势密码破解实战(root过的手机可直接绕过手势密码)

/* 本文章由 莫灰灰 编写,转载请注明出处. 作者:莫灰灰    邮箱: [email protected] */ 背景 随着移动互联网的普及以及手机屏幕越做越大等特点,在移动设备上购物.消费已是人们不可或缺的一个生活习惯了.随着这股浪潮的兴起,安全.便捷的移动支付需求也越来越大.因此,各大互联网公司纷纷推出了其移动支付平台.其中,用的比较多的要数腾讯的微信和阿里的支付宝钱包了.就我而言,平时和同事一起出去AA吃饭,下班回家打车等日常生活都已经离不开这两个支付平台了. 正所谓树大招风,移动支付