上鎖功能相當簡單,基本上只需要 EditText 和 SharedPreferences(也可以使用其它的儲存類別如 fileoutputstream,SQLite) 就能完成,,不過為了操作的方便,我還加上了 button 和 textview ,基本介面如下
開鎖畫面
輸入密碼畫面
而實作原理也相當簡單,為了不把主流程複雜化,我把解鎖(UnLock_Flow.java)和加鎖(Lock_Flow.java)分開成2個類別,首先在主流程開始前先判斷是否有密碼鎖,有就先進解鎖,沒有就直接開始主流程,而在主流程中會有個選項是加入密碼鎖的選擇,點選進入 Lock_Flow.java,相當簡單吧
首先在主流程中判斷的方法如下
void lock() {
// get data for accountdetail
SharedPreferences sp = getSharedPreferences("bcn", 0);
// get accountdetail count
String passstr = sp.getString("adlock", "");
// no lock
if(passstr.equals("")){
}
//lock exist
else {
//call Lock_Flow
Intent inte = new Intent();
inte.setClass(All_List.this, UnLock_Flow.class);
startActivityForResult(inte, 3);
overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
}
}
其中 SharedPreferences 的用法請參考這篇,本篇不再多加詳述
第 9 行判斷內容是否為空,是的話代表沒有密碼鎖直接進入主流程,否的話就呼叫解鎖類別(16 ~ 20 行)
解鎖類別(UnLock_Flow.java)如下
package com.example.helloworld;
import FoXxLib.FP;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
@SuppressLint("NewApi")
public class UnLock_Flow extends Activity {
EditText et;
Button byes;
Button bno;
TextView tv;
int tryNum = 2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initXml();
}
void initXml() {
setContentView(R.layout.unlockflow);
tv = (TextView) findViewById(R.id.textView1);
tv.setText("請輸入密碼解鎖");
et = (EditText) findViewById(R.id.username_edit);
et.setHint("輸入密碼");
byes = (Button) findViewById(R.id.buttonYes);
byes.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
checkPassWord();
}
});
bno = (Button) findViewById(R.id.buttonNo);
bno.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
// use AlertDialog
AlertDialog ad = new AlertDialog.Builder(UnLock_Flow.this,
AlertDialog.THEME_TRADITIONAL).create();
ad.setTitle("警告!!");// 設定警告標題
ad.setMessage("確定離開程序??");
ad.setButton2("確定", new DialogInterface.OnClickListener() {// 設定按鈕2
@Override
public void onClick(DialogInterface dialog,
int which) {
// 點選按鈕2後執行的動作
finishEdit(1);
}
});
ad.setButton("取消", new DialogInterface.OnClickListener() {// 設定按鈕2
@Override
public void onClick(DialogInterface dialog,
int which) {
// 點選按鈕2後執行的動作
}
});
ad.setCanceledOnTouchOutside(true);// 當警告提示出現後,點選提示以外範圍,是否會取消提示,預設是true
ad.setCancelable(true);// 當警告提示出現後,點選其他實體按鈕(backkey等等),是否會取消提示,預設是true
ad.show();
}
});
}
void checkPassWord() {
if (et.getText() == null) {
// use Toast
tryNum--;
Toast.makeText(UnLock_Flow.this, "未輸入密碼!!!" + "還剩" + tryNum + "次",
Toast.LENGTH_SHORT).show();
et.setText("");
} else {
String tempstr = et.getText().toString();
// get data for accountdetail
SharedPreferences sp = getSharedPreferences("bcn", 0);
// get accountdetail count
String passstr = sp.getString("adlock", "");
if (tempstr.equals(passstr)) {
Toast.makeText(UnLock_Flow.this, "密碼正確!!!", Toast.LENGTH_SHORT)
.show();
finishEdit(0);
} else {
Toast.makeText(UnLock_Flow.this,
"密碼錯誤!!!" + "還剩" + tryNum + "次", Toast.LENGTH_SHORT)
.show();
tryNum--;
}
}
if (tryNum < 0) {
finishEdit(1);
}
}
public boolean onKeyDown(int keycode, KeyEvent event) {
FP.p("keycode:" + keycode);
FP.p("event:" + event.getAction());
finishEdit(1);
switch (keycode) {
// menu key
case 82:
break;
}
return super.onKeyDown(keycode, event);
}
/**
*
* @param result
* 0 ok
*/
void finishEdit(int result) {
if (result == 0) {
UnLock_Flow.this.setResult(0);
UnLock_Flow.this.finish();
overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
} else if (result == 1) {
UnLock_Flow.this.setResult(1);
UnLock_Flow.this.finish();
}
}
}
其中比較重要的為 101 行的 checkPassWord() 方法,會取得 在 et 中輸入的字串內容並與 passstr 字串做比較(120行),相同則解鎖成功(finishEdit(0)),失敗則嘗試次數減少,當嘗試次數減為 0 ,那麼會直接回到主程序再結束 (finishEdit(1))
以上是解鎖的部分,接下來是上鎖的部分,在主程序中會有個按鈕,用來觸發加鎖動作,如下
//call Lock_Flow Intent inte = new Intent(); inte.setClass(All_List.this, Lock_Flow.class); startActivityForResult(inte, 4); overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
接著是 Lock_Flow.java的內容,必須注意在沒有上鎖的情況下,可以直接設定密碼,完成上鎖,但相反的若已經有上鎖過,則必須先輸入原先的密碼以解鎖,再上鎖,如下
package com.example.helloworld;
import FoXxLib.FP;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
@SuppressLint("NewApi")
public class Lock_Flow extends Activity{
EditText et;
Button byes;
Button bno;
TextView tv;
int tryNum =2;
//0:lock exist 1:no lock
int flow =0;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
initXml();
}
void initXml(){
setContentView(R.layout.lockflow);
tv = (TextView)findViewById(R.id.textView1);
// get data for accountdetail
SharedPreferences sp = getSharedPreferences("bcn", 0);
// get accountdetail count
String passstr = sp.getString("adlock", "");
//no lock
if(passstr.equals("")){
flow =1;
tv.setText("請輸入密碼:");
}
//lock exist
else{
flow =0;
tv.setText("請輸入原始密碼:");
}
et = (EditText)findViewById(R.id.username_edit);
et.setHint("輸入密碼");
byes = (Button)findViewById(R.id.buttonYes);
byes.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
checkPassWord();
}
});
bno = (Button)findViewById(R.id.buttonNo);
bno.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//use AlertDialog
AlertDialog ad = new AlertDialog.Builder(Lock_Flow.this,AlertDialog.THEME_TRADITIONAL).create();
ad.setTitle("警告!!");//設定警告標題
ad.setMessage("未上鎖,確定返回程序??");
ad.setButton2("確定", new DialogInterface.OnClickListener() {// 設定按鈕2
@Override
public void onClick(DialogInterface dialog, int which) {
// 點選按鈕2後執行的動作
finishEdit(1);
}
});
ad.setButton("取消", new DialogInterface.OnClickListener() {// 設定按鈕2
@Override
public void onClick(DialogInterface dialog, int which) {
// 點選按鈕2後執行的動作
}
});
ad.setCanceledOnTouchOutside(true);//當警告提示出現後,點選提示以外範圍,是否會取消提示,預設是true
ad.setCancelable(true);//當警告提示出現後,點選其他實體按鈕(backkey等等),是否會取消提示,預設是true
ad.show();
}
});
}
void checkPassWord(){
if(flow==0){
if(et.getText().toString().equals("")){
// use Toast
Toast.makeText(Lock_Flow.this, "未輸入密碼!!!"+"還剩"+tryNum+"次",Toast.LENGTH_SHORT).show();
tryNum--;
et.setText("");
}
else{
String tempstr = et.getText().toString();
// get data for accountdetail
SharedPreferences sp = getSharedPreferences("bcn", 0);
// get accountdetail count
String passstr = sp.getString("adlock","");
if(tempstr.equals(passstr)){
Toast.makeText(Lock_Flow.this, "密碼正確!!!",Toast.LENGTH_SHORT).show();
flow =1;
tv.setText("輸入新密碼:");
}
else{
Toast.makeText(Lock_Flow.this, "密碼錯誤!!!"+"還剩"+tryNum+"次",Toast.LENGTH_SHORT).show();
tryNum--;
}
}
if(tryNum<0){
//use AlertDialog
AlertDialog ad = new AlertDialog.Builder(Lock_Flow.this,AlertDialog.THEME_TRADITIONAL).create();
ad.setTitle("更改密碼失敗!!");//設定警告標題
ad.setMessage("原始密碼不正確");
ad.setButton("返回", new DialogInterface.OnClickListener() {// 設定按鈕2
@Override
public void onClick(DialogInterface dialog, int which) {
finishEdit(0);
}
});
ad.setCanceledOnTouchOutside(false);//當警告提示出現後,點選提示以外範圍,是否會取消提示,預設是true
ad.setCancelable(false);//當警告提示出現後,點選其他實體按鈕(backkey等等),是否會取消提示,預設是true
ad.show();
}
}
else if(flow==1){
if(et.getText().toString().equals("")){
// use Toast
Toast.makeText(Lock_Flow.this, "未輸入密碼!!!",Toast.LENGTH_SHORT).show();
et.setText("");
}
else{
String tempstr = et.getText().toString();
// get data for accountdetail
SharedPreferences sp = getSharedPreferences("bcn", 0);
SharedPreferences.Editor spe = sp.edit();
spe.putString("adlock", tempstr);// for more putXXX
spe.commit();
//use AlertDialog
AlertDialog ad = new AlertDialog.Builder(Lock_Flow.this,AlertDialog.THEME_TRADITIONAL).create();
ad.setTitle("上鎖完成!!");//設定警告標題
ad.setMessage("密碼為"+tempstr);
ad.setButton("返回", new DialogInterface.OnClickListener() {// 設定按鈕2
@Override
public void onClick(DialogInterface dialog, int which) {
finishEdit(1);
}
});
ad.setCanceledOnTouchOutside(false);//當警告提示出現後,點選提示以外範圍,是否會取消提示,預設是true
ad.setCancelable(false);//當警告提示出現後,點選其他實體按鈕(backkey等等),是否會取消提示,預設是true
ad.show();
}
}
}
public boolean onKeyDown(int keycode, KeyEvent event){
FP.p("keycode:"+keycode);
FP.p("event:"+event.getAction());
finishEdit(1);
switch(keycode){
// menu key
case 82:
break;
}
return super.onKeyDown(keycode, event);
}
/**
*
* @param result 0 ok
*/
void finishEdit(int result){
if(result==0){
Lock_Flow.this.setResult(0);
Lock_Flow.this.finish();
overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
}
else if(result==1){
Lock_Flow.this.setResult(1);
Lock_Flow.this.finish();
overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
}
}
}
第 30 行 flow=0代表已經有鎖, 必須先解鎖,而flow=1,代表沒有鎖,可以直接輸入密碼上鎖
結果為












