【边做项目边学Android】手机安全卫士07-手机防盗之进入限制

上次写到在进入手机但·防盗界面时需要有密码限制,首先第一次进入时会弹出对话框提示用户设置密码;再次进入时会要求用户输入密码;这次来具体实现上述功能。

首次登录,设置密码

首先,我们的密码是保存在SharePreference中的”password”字段里的,在登录时后台需要校验该字段是否已经设置了密码,若未设置则弹出对话框让用户设置,否则要用户输入密码进入手机防盗界面;

  • 校验是否设置了密码

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sp = getSharedPreferences("config", Context.MODE_PRIVATE);
        // 判读用户是否已经设置了密码
        if (isPwdSetup()) {
            Log.i(TAG, "设置了密码,弹出输入密码的对话框");
        } else {
            Log.i(TAG, "未设置密码,弹出设置密码对话框");
            showFirstEntryDialog();
        }
    }

    /**
     * 检查sharedpreference中是否有密码的设置
     *
     * @return
     */
    private boolean isPwdSetup() {
        String password = sp.getString("password", null);
        if (password == null) {
            return false;
        } else {
            if ("".equals(password)) {
                return false;
            } else {
                return true;
            }
        }
    }

  • showFirstEntryDialog(),弹出用户设置密码对话框

/**
     * 第一次进入程序时弹出的设置密码的对话框
     * 使用自定义对话框样式
     */
    private void showFirstEntryDialog() {
        dialog = new Dialog(this, R.style.MyDialog);
//      dialog.setContentView(R.layout.first_entry_dialog);// 设置要显示的内容
        View view = View.inflate(this, R.layout.first_entry_dialog, null);
        et_pwd = (EditText) view.findViewById(R.id.et_first_entry_pwd);
        et_pwd_confirm = (EditText) view.findViewById(R.id.et_first_entry_pwd_confirm);
        Button bt_confirm = (Button) view.findViewById(R.id.bt_first_dialog_confirm);
        Button bt_cancel = (Button) view.findViewById(R.id.bt_first_dialog_cancel);

        // 设置按钮对应的点击事件
        bt_confirm.setOnClickListener(this);
        bt_cancel.setOnClickListener(this);

        dialog.setContentView(view);
        dialog.setCanceledOnTouchOutside(false);// 设置dialog不可以点击其他地方时消失
        dialog.setCancelable(false);// 设置dialog不可以点返回键时消失
        dialog.show();
    }
  • 用户输入后,后台对用户的输入进行处理

@Override
    public void onClick(View view) {
        switch(view.getId()){
        // 点击取消
        case R.id.bt_first_dialog_cancel:
            dialog.dismiss();
            break;
        case R.id.bt_first_dialog_confirm:
            String pwd = et_pwd.getText().toString().trim();
            String pwd_confirm = et_pwd_confirm.getText().toString().trim();

            // 输入的密码中包好空值
            if("".equals(pwd) || "".equals(pwd_confirm)){
                Toast.makeText(getApplicationContext(), "输入不能为空!", Toast.LENGTH_LONG).show();
                return;
            }else{
                if(pwd.equals(pwd_confirm)){
                    Editor editor = sp.edit();
                    editor.putString("password", pwd);
                    editor.commit();
                }
                // 两次输入不一致
                else{
                    Toast.makeText(getApplicationContext(), "两次输入密码不相同!", Toast.LENGTH_LONG).show();
                    return;
                }
            }
            dialog.dismiss();
            break;
        }
    }

效果如下:

初次进入手机防盗界面:

未输入时点击确定:

两次输入密码不相同:


再次登录,输入密码

  • 弹出对话框样式:normal_entry_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dip"
    android:layout_height="280dip"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录"
        android:textColor="@color/textcolor"
        android:textSize="24sp" />

    <LinearLayout
        android:layout_width="300dip"
        android:layout_height="wrap_content"
        android:background="#ffc8c8c8"
        android:orientation="vertical" >

        <EditText
            android:id="@+id/et_normal_entry_pwd"
            android:layout_width="300dip"
            android:layout_height="wrap_content"
            android:hint="请输入密码"
            android:password="true" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="300dip"
        android:layout_height="50dip"
        android:gravity="center"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/bt_normal_dialog_confirm"
            android:layout_width="140dip"
            android:layout_height="40dip"
            android:background="@drawable/button_background"
            android:text="确定"
            android:textColor="#ffffffff" />

        <Button
            android:id="@+id/bt_normal_dialog_cancel"
            android:layout_width="140dip"
            android:layout_height="40dip"
            android:layout_marginLeft="3dip"
            android:background="@drawable/button_background"
            android:text="取消" />
    </LinearLayout>

</LinearLayout>

  • showNormalEntryDialog方法

/**
     * 正常登录的对话框
     *
     */
    private void showNormalEntryDialog() {
        dialog = new Dialog(this, R.style.MyDialog);
        View view = View.inflate(this, R.layout.normal_entry_dialog, null);
        et_pwd = (EditText) view.findViewById(R.id.et_normal_entry_pwd);
        Button bt_confirm = (Button) view.findViewById(R.id.bt_normal_dialog_confirm);
        Button bt_cancel = (Button) view.findViewById(R.id.bt_normal_dialog_cancel);

        // 设置按钮对应的点击事件
        bt_confirm.setOnClickListener(this);
        bt_cancel.setOnClickListener(this);

        dialog.setContentView(view);
        dialog.setCanceledOnTouchOutside(false);// 设置dialog不可以点击其他地方时消失
//      dialog.setCancelable(false);// 设置dialog不可以点返回键时消失
        dialog.show();
    }
  • 按键处理:

@Override
    public void onClick(View view) {
        switch(view.getId()){
        case R.id.bt_normal_dialog_cancel:
            dialog.dismiss();
            break;
        case R.id.bt_normal_dialog_confirm:
            String input_pwd = et_pwd.getText().toString();
            if("".equals(input_pwd)){
                Toast.makeText(getApplicationContext(), "输入不能为空!", Toast.LENGTH_LONG).show();
                return;
            }else{
                String password = sp.getString("password", "");
                if(!password.equals(input_pwd)){
                    Toast.makeText(getApplicationContext(), "输入密码不正确,请重新输入!", Toast.LENGTH_LONG).show();
                    et_pwd.selectAll();// 用户输入错误后,对文本进行全选,方便用户进行删除重新输入
                    return;
                }
            }
            Log.i(TAG, "加载手机防盗主界面");
            dialog.dismiss();
            break;
        }
    }

效果如下:


密码加密存储

目前我们的密码存储都是以明文存储在SharePreference中的,因此有点Android开发基础的人都可以获取到我们设置的密码。

考虑使用加密算法对密码加密后进行存储。

使用JavaSe提供的MessageDigest类进行加密。MessageDigest支持的加密算法包括:MD5、SHA-1、SHA-256。


package com.liuhao.mobilesafe.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Encoder {

    public static String encode(String pwd) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(pwd.getBytes());
            StringBuffer sb = new StringBuffer();
            for (byte b : bytes) {
                String str = Integer.toHexString(0xff & b);// byte是八位字节存储的,转化为16进制数,直接与11111111相与
                if (str.length() == 1) {
                    sb.append("0" + str);
                } else {
                    sb.append(str);
                }
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException("不存在加密算法");
        }
    }
}

这样在存储密码时调用encode()方法即可对密码进行存储。在读取时也要用加密后的密文与已存储的进行对比。


editor.putString("password", MD5Encoder.encode(pwd));

if(!password.equals(MD5Encoder.encode(input_pwd))){
    Toast.makeText(getApplicationContext(), "输入密码不正确,请重新输入!", Toast.LENGTH_LONG).show();
    et_pwd.selectAll();// 用户输入错误后,对文本进行全选,方便用户进行删除重新输入
    return;
}

其实我们仅仅简单的一次加密也是很不保险的,虽说从算法实现上来说md5加密是不可逆的,但是有些“别有用心”的人,竟然将所有可预见的字符串对应的密文都算出来了,真是。。。

比如这个网站:http://www.cmd5.com/

惊呆了,有木有!

所以,以后在重要的网站设置密码时一定要设的复杂一点!!!

时间: 2024-11-15 12:08:30

【边做项目边学Android】手机安全卫士07-手机防盗之进入限制的相关文章

【边做项目边学Android】手机安全卫士01:splash界面ui

手机安全卫士项目是跟着黑马的视频做的. splash是飞洒.飞溅的意思,主要是用于完成一个产品logo显示,期间可以: 后台完成数据库初始化的操作 联网访问服务器,获取服务器最新信息(升级提示) 不同的日期显示出来不同logo,判断当前系统时间,素材一般从服务器上下载下来. 判断时间,根据不同时间显示不同的加载页面 布局文件:splash.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayou

【边做项目边学Android】手机安全卫士09-手机防盗界面设置向导1

本次主要做手机防盗界面的设置向导功能界面的设计. 需求: 当用户进入手机防盗界面时,判断用户是否已经进行过设置向导: 如果用户已经设置过手机防盗,则不再提示用户进入手机向导 若还没有设置,则提示用户进入设置向导界面. 具体实现: 1.当用户输入"手机防盗"密码正确时,进行判断用户是否进行过设置向导 /** * 判断用户是否进行过设置向导 * @return */ private boolean isSetup(){ return sp.getBoolean("isAlread

【边做项目边学Android】手机安全卫士03:获取更新的服务器配置,显示更新对话框

配置应用程序在手机桌面显示的名称和图标-AndroidManifest.xml: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.liuhao.mobilesafe" android:versionCode="

【边做项目边学Android】手机安全卫士04_01:界面(Activity)之间的切换,Activity和任务栈

上一回说到,用户选择是否升级,若用户选择不升级,那么就要进入程序的主界面.下面要做的是从splash界面跳转到main界面. MainActivity创建 1.首先新建MainActivity: package com.liuhao.mobilesafe.ui; import com.liuhao.mobilesafe.R; import android.app.Activity; import android.os.Bundle; public class MainActivity exten

【边做项目边学Android】手机安全卫士10-设置向导之绑定SIM卡

上回主要做了设置向导界面的界面设计,主要涉及到界面的布局和一些控件的使用.这次要做设置向导界面的功能具体实现. 首先,4个界面分别是(重复度很大,这里就不再贴到正文中了) /mobilesafe/res/layout/setup_wizard1.xml /mobilesafe/res/layout/setup_wizard2.xml /mobilesafe/res/layout/setup_wizard3.xml /mobilesafe/res/layout/setup_wizard4.xml

【边做项目边学Android】手机安全卫士05_1:程序主界面

主界面布局(知识点:GridView) mainscreen.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height=

【边做项目边学Android】手机安全卫士08-一些布局和显示的细节:State List

我们注意到有些应用里的按钮在点击时的显示状态和普通状态是不一样的,比如: 普通状态下: 选中状态下: 那这种效果是如何实现的呢?在Android系统中提供给我们一种方便与实现这种功能的方法即:state list drawable. StateListDrawable是在XML中定义的drawable对象,我们可以通过设置不同item下的图片来显示不同状态,这取决于 drawable对象的状态.例如,一个Button控件可以有不同的状态(点击.聚焦等),通过一系列的drawable对象,可以为每

【边做项目边学Android】手机安全卫士11-设置向导之设置安全号码

这次主要实现设置安全号码的功能,即当发现手机SIM卡信息发生改变时,会自动给安全号码发送一条报警短信.主要包括选择联系人功能.涉及到的知识点包括:带返回值的Intent,ListView数据适配器. 选择联系人功能 界面 用ListView来对读取的联系人进行展示 /mobilesafe/res/layout/select_contact.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayou

【边做项目边学Android】手机安全卫士05_2:程序主界面,为每个条目添加事件

为每个条目添加点击事件监听器 gv_main.setOnItemClickListener(this); 需要当前Activity实现OnItemClickListener接口,同时实现public void onItemClick(AdapterView<?> parent, View view, int position,long id)方法 /** * 当gridview的条目被点击的时候对应的回调 * parent : gridView * view : 当前被点击条目的 Linear