当前位置: 代码迷 >> Android >> 【边做项目边学Android】手机安全卫士07-手机防盗之进去限制
  详细解决方案

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

热度:41   发布时间:2016-04-28 03:08:00.0
【边做项目边学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/

惊呆了,有木有!

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

  相关解决方案