運(yùn)行有問題或需要源碼請點(diǎn)贊關(guān)注收藏后評論區(qū)留言~~~
SQLite簡介
SQLite是一種小巧的嵌入式數(shù)據(jù)庫,使用方便,開發(fā)簡單,如同mysql,oracle那樣,SQLite也采用SQL語句管理數(shù)據(jù),由于它屬于輕型數(shù)據(jù)庫,不涉及復(fù)雜的數(shù)據(jù)控制操作,因此App開發(fā)只用到數(shù)據(jù)定義和數(shù)據(jù)操縱兩類SQL。
1:數(shù)據(jù)定義語言
它描述了怎么變更數(shù)據(jù)實(shí)體的框架結(jié)構(gòu),就SQLite而言,主要包括創(chuàng)建表格,刪除表格,修改表結(jié)構(gòu)等等操作
2:數(shù)據(jù)操縱語言
它描述了怎樣處理數(shù)據(jù)實(shí)體的內(nèi)部記錄,表格記錄的操作類型包括添加,刪除,修改,查詢4類
一、數(shù)據(jù)庫管理器SQLiteDatabase
若要在Java代碼中操縱SQLite,還需要專門的工具類,SQLiteDatabase便是Android提供的SQLite數(shù)據(jù)庫管理器,開發(fā)者可以在活動(dòng)頁面代碼調(diào)用openOrCreateDatabase方法獲取數(shù)據(jù)庫實(shí)例 效果如下
?
DatabaseActivity類
package com.example.chapter06;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class DatabaseActivity extends AppCompatActivity implements View.OnClickListener {
private TextView tv_database;
private String mDatabaseName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_database);
tv_database = findViewById(R.id.tv_database);
findViewById(R.id.btn_database_create).setOnClickListener(this);
findViewById(R.id.btn_database_delete).setOnClickListener(this);
// 生成一個(gè)測試數(shù)據(jù)庫的完整路徑
mDatabaseName = getFilesDir() + "/test.db";
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_database_create) {
// 創(chuàng)建或打開數(shù)據(jù)庫。數(shù)據(jù)庫如果不存在就創(chuàng)建它,如果存在就打開它
SQLiteDatabase db = openOrCreateDatabase(mDatabaseName, Context.MODE_PRIVATE, null);
String desc = String.format("數(shù)據(jù)庫%s創(chuàng)建%s", db.getPath(), (db!=null)?"成功":"失敗");
tv_database.setText(desc);
} else if (v.getId() == R.id.btn_database_delete) {
boolean result = deleteDatabase(mDatabaseName); // 刪除數(shù)據(jù)庫
String desc = String.format("數(shù)據(jù)庫%s刪除%s", mDatabaseName, result?"成功":"失敗");
tv_database.setText(desc);
}
}
}
activity_databaseXML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_database_create"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="創(chuàng)建數(shù)據(jù)庫"
android:textColor="@color/black"
android:textSize="17sp" />
<Button
android:id="@+id/btn_database_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="刪除數(shù)據(jù)庫"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
<TextView
android:id="@+id/tv_database"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
二、數(shù)據(jù)庫幫助器SQLiteOpenHelper
由于SQLiteDatabase存在局限性,一不小心就會(huì)重復(fù)打開數(shù)據(jù)庫,處理數(shù)據(jù)庫的升級也不方便,因此Android提供了數(shù)據(jù)庫幫助其SQLiteOpenHelper,幫助開發(fā)者合理使用SQLite
下面通過實(shí)例演示對數(shù)據(jù)庫的增刪改查功能以及獲取用戶信息 效果如下
?
?
SQLiteWriteActivity類?
package com.example.chapter06;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter06.bean.UserInfo;
import com.example.chapter06.database.UserDBHelper;
import com.example.chapter06.util.DateUtil;
import com.example.chapter06.util.ToastUtil;
public class SQLiteWriteActivity extends AppCompatActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
private UserDBHelper mHelper; // 聲明一個(gè)用戶數(shù)據(jù)庫幫助器的對象
private EditText et_name;
private EditText et_age;
private EditText et_height;
private EditText et_weight;
private boolean bMarried = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sqlite_write);
et_name = findViewById(R.id.et_name);
et_age = findViewById(R.id.et_age);
et_height = findViewById(R.id.et_height);
et_weight = findViewById(R.id.et_weight);
CheckBox ck_married = findViewById(R.id.ck_married);
ck_married.setOnCheckedChangeListener(this);
findViewById(R.id.btn_save).setOnClickListener(this);
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
bMarried = isChecked;
}
@Override
protected void onStart() {
super.onStart();
// 獲得數(shù)據(jù)庫幫助器的實(shí)例
mHelper = UserDBHelper.getInstance(this, 1);
mHelper.openWriteLink(); // 打開數(shù)據(jù)庫幫助器的寫連接
}
@Override
protected void onStop() {
super.onStop();
mHelper.closeLink(); // 關(guān)閉數(shù)據(jù)庫連接
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_save) {
String name = et_name.getText().toString();
String age = et_age.getText().toString();
String height = et_height.getText().toString();
String weight = et_weight.getText().toString();
if (TextUtils.isEmpty(name)) {
ToastUtil.show(this, "請先填寫姓名");
return;
} else if (TextUtils.isEmpty(age)) {
ToastUtil.show(this, "請先填寫年齡");
return;
} else if (TextUtils.isEmpty(height)) {
ToastUtil.show(this, "請先填寫身高");
return;
} else if (TextUtils.isEmpty(weight)) {
ToastUtil.show(this, "請先填寫體重");
return;
}
// 以下聲明一個(gè)用戶信息對象,并填寫它的各字段值
UserInfo info = new UserInfo();
info.name = name;
info.age = Integer.parseInt(age);
info.height = Long.parseLong(height);
info.weight = Float.parseFloat(weight);
info.married = bMarried;
info.update_time = DateUtil.getNowDateTime("yyyy-MM-dd HH:mm:ss");
mHelper.insert(info); // 執(zhí)行數(shù)據(jù)庫幫助器的插入操作
ToastUtil.show(this, "數(shù)據(jù)已寫入SQLite數(shù)據(jù)庫");
}
}
}
SQLiteReadActivity類
package com.example.chapter06;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter06.bean.UserInfo;
import com.example.chapter06.database.UserDBHelper;
import com.example.chapter06.util.ToastUtil;
import java.util.List;
@SuppressLint("DefaultLocale")
public class SQLiteReadActivity extends AppCompatActivity implements View.OnClickListener {
private UserDBHelper mHelper; // 聲明一個(gè)用戶數(shù)據(jù)庫幫助器的對象
private TextView tv_sqlite;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sqlite_read);
tv_sqlite = findViewById(R.id.tv_sqlite);
findViewById(R.id.btn_delete).setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
// 獲得數(shù)據(jù)庫幫助器的實(shí)例
mHelper = UserDBHelper.getInstance(this, 1);
mHelper.openReadLink(); // 打開數(shù)據(jù)庫幫助器的讀連接
readSQLite(); // 讀取數(shù)據(jù)庫中保存的所有用戶記錄
}
@Override
protected void onStop() {
super.onStop();
mHelper.closeLink(); // 關(guān)閉數(shù)據(jù)庫連接
}
// 讀取數(shù)據(jù)庫中保存的所有用戶記錄
private void readSQLite() {
if (mHelper == null) {
ToastUtil.show(this, "數(shù)據(jù)庫連接為空");
return;
}
// 執(zhí)行數(shù)據(jù)庫幫助器的查詢操作
List<UserInfo> userList = mHelper.query("1=1");
String desc = String.format("數(shù)據(jù)庫查詢到%d條記錄,詳情如下:", userList.size());
for (int i = 0; i < userList.size(); i++) {
UserInfo info = userList.get(i);
desc = String.format("%s\n第%d條記錄信息如下:", desc, i + 1);
desc = String.format("%s\n 姓名為%s", desc, info.name);
desc = String.format("%s\n 年齡為%d", desc, info.age);
desc = String.format("%s\n 身高為%d", desc, info.height);
desc = String.format("%s\n 體重為%f", desc, info.weight);
desc = String.format("%s\n 婚否為%b", desc, info.married);
desc = String.format("%s\n 更新時(shí)間為%s", desc, info.update_time);
}
if (userList.size() <= 0) {
desc = "數(shù)據(jù)庫查詢到的記錄為空";
}
tv_sqlite.setText(desc);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_delete) {
mHelper.closeLink(); // 關(guān)閉數(shù)據(jù)庫連接
mHelper.openWriteLink(); // 打開數(shù)據(jù)庫幫助器的寫連接
mHelper.deleteAll(); // 刪除所有記錄
mHelper.closeLink(); // 關(guān)閉數(shù)據(jù)庫連接
mHelper.openReadLink(); // 打開數(shù)據(jù)庫幫助器的讀連接
readSQLite(); // 讀取數(shù)據(jù)庫中保存的所有用戶記錄
ToastUtil.show(this, "已刪除所有記錄");
}
}
}
activity_sqlite_writeXML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp" >
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="姓名:"
android:textColor="@color/black"
android:textSize="17sp" />
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="3dp"
android:layout_marginTop="3dp"
android:layout_toRightOf="@+id/tv_name"
android:background="@drawable/editext_selector"
android:gravity="left|center"
android:hint="請輸入姓名"
android:inputType="text"
android:maxLength="12"
android:textColor="@color/black"
android:textSize="17sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp" >
<TextView
android:id="@+id/tv_age"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="年齡:"
android:textColor="@color/black"
android:textSize="17sp" />
<EditText
android:id="@+id/et_age"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="3dp"
android:layout_marginTop="3dp"
android:layout_toRightOf="@+id/tv_age"
android:background="@drawable/editext_selector"
android:gravity="left|center"
android:hint="請輸入年齡"
android:inputType="number"
android:maxLength="2"
android:textColor="@color/black"
android:textSize="17sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp" >
<TextView
android:id="@+id/tv_height"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="身高:"
android:textColor="@color/black"
android:textSize="17sp" />
<EditText
android:id="@+id/et_height"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="3dp"
android:layout_marginTop="3dp"
android:layout_toRightOf="@+id/tv_height"
android:background="@drawable/editext_selector"
android:gravity="left|center"
android:hint="請輸入身高"
android:inputType="number"
android:maxLength="3"
android:textColor="@color/black"
android:textSize="17sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp" >
<TextView
android:id="@+id/tv_weight"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="體重:"
android:textColor="@color/black"
android:textSize="17sp" />
<EditText
android:id="@+id/et_weight"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="3dp"
android:layout_marginTop="3dp"
android:layout_toRightOf="@+id/tv_weight"
android:background="@drawable/editext_selector"
android:gravity="left|center"
android:hint="請輸入體重"
android:inputType="numberDecimal"
android:maxLength="5"
android:textColor="@color/black"
android:textSize="17sp" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp" >
<CheckBox
android:id="@+id/ck_married"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:checked="false"
android:text="已婚"
android:textColor="@color/black"
android:textSize="17sp" />
</RelativeLayout>
<Button
android:id="@+id/btn_save"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="保存到數(shù)據(jù)庫"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
activity_sqlite_readXML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="刪除所有記錄"
android:textColor="@color/black"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_sqlite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
三、優(yōu)化記住密碼功能
真正的記住密碼功能應(yīng)該是先輸入手機(jī)號碼,然后根據(jù)手機(jī)號碼匹配保存的密碼,一個(gè)手機(jī)號碼對應(yīng)一個(gè)密碼,并支持根據(jù)手機(jī)號查找登錄信息,從而同時(shí)記住多個(gè)手機(jī)號的密碼 這是通過SQLite數(shù)據(jù)庫可以實(shí)現(xiàn)這一點(diǎn) 后臺(tái)保存密碼和手機(jī)號 效果如下
?
?LoginSQLiteActivity類
package com.example.chapter06;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.chapter06.bean.UserInfo;
import com.example.chapter06.database.UserDBHelper;
import com.example.chapter06.util.DateUtil;
import com.example.chapter06.util.ViewUtil;
import java.util.Random;
@SuppressLint("DefaultLocale")
public class LoginSQLiteActivity extends AppCompatActivity implements View.OnClickListener, OnFocusChangeListener {
private RadioGroup rg_login; // 聲明一個(gè)單選組對象
private RadioButton rb_password; // 聲明一個(gè)單選按鈕對象
private RadioButton rb_verifycode; // 聲明一個(gè)單選按鈕對象
private EditText et_phone; // 聲明一個(gè)編輯框?qū)ο? private TextView tv_password; // 聲明一個(gè)文本視圖對象
private EditText et_password; // 聲明一個(gè)編輯框?qū)ο? private Button btn_forget; // 聲明一個(gè)按鈕控件對象
private CheckBox ck_remember; // 聲明一個(gè)復(fù)選框?qū)ο?
private int mRequestCode = 0; // 跳轉(zhuǎn)頁面時(shí)的請求代碼
private boolean bRemember = false; // 是否記住密碼
private String mPassword = "111111"; // 默認(rèn)密碼
private String mVerifyCode; // 驗(yàn)證碼
private UserDBHelper mHelper; // 聲明一個(gè)用戶數(shù)據(jù)庫的幫助器對象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_sqlite);
rg_login = findViewById(R.id.rg_login);
rb_password = findViewById(R.id.rb_password);
rb_verifycode = findViewById(R.id.rb_verifycode);
et_phone = findViewById(R.id.et_phone);
tv_password = findViewById(R.id.tv_password);
et_password = findViewById(R.id.et_password);
btn_forget = findViewById(R.id.btn_forget);
ck_remember = findViewById(R.id.ck_remember);
// 給rg_login設(shè)置單選監(jiān)聽器
rg_login.setOnCheckedChangeListener(new RadioListener());
// 給ck_remember設(shè)置勾選監(jiān)聽器
ck_remember.setOnCheckedChangeListener(new CheckListener());
// 給et_phone添加文本變更監(jiān)聽器
et_phone.addTextChangedListener(new HideTextWatcher(et_phone, 11));
// 給et_password添加文本變更監(jiān)聽器
et_password.addTextChangedListener(new HideTextWatcher(et_password, 6));
btn_forget.setOnClickListener(this);
findViewById(R.id.btn_login).setOnClickListener(this);
// 給密碼編輯框注冊一個(gè)焦點(diǎn)變化監(jiān)聽器,一旦焦點(diǎn)發(fā)生變化,就觸發(fā)監(jiān)聽器的onFocusChange方法
et_password.setOnFocusChangeListener(this);
}
// 定義登錄方式的單選監(jiān)聽器
private class RadioListener implements RadioGroup.OnCheckedChangeListener {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == R.id.rb_password) { // 選擇了密碼登錄
tv_password.setText("登錄密碼:");
et_password.setHint("請輸入密碼");
btn_forget.setText("忘記密碼");
ck_remember.setVisibility(View.VISIBLE);
} else if (checkedId == R.id.rb_verifycode) { // 選擇了驗(yàn)證碼登錄
tv_password.setText(" 驗(yàn)證碼:");
et_password.setHint("請輸入驗(yàn)證碼");
btn_forget.setText("獲取驗(yàn)證碼");
ck_remember.setVisibility(View.INVISIBLE);
}
}
}
// 定義是否記住密碼的勾選監(jiān)聽器
private class CheckListener implements CompoundButton.OnCheckedChangeListener {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (buttonView.getId() == R.id.ck_remember) {
bRemember = isChecked;
}
}
}
// 定義一個(gè)編輯框監(jiān)聽器,在輸入文本達(dá)到指定長度時(shí)自動(dòng)隱藏輸入法
private class HideTextWatcher implements TextWatcher {
private EditText mView; // 聲明一個(gè)編輯框?qū)ο? private int mMaxLength; // 聲明一個(gè)最大長度變量
public HideTextWatcher(EditText v, int maxLength) {
super();
mView = v;
mMaxLength = maxLength;
}
// 在編輯框的輸入文本變化前觸發(fā)
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
// 在編輯框的輸入文本變化時(shí)觸發(fā)
public void onTextChanged(CharSequence s, int start, int before, int count) {}
// 在編輯框的輸入文本變化后觸發(fā)
public void afterTextChanged(Editable s) {
String str = s.toString(); // 獲得已輸入的文本字符串
// 輸入文本達(dá)到11位(如手機(jī)號碼),或者達(dá)到6位(如登錄密碼)時(shí)關(guān)閉輸入法
if ((str.length() == 11 && mMaxLength == 11)
|| (str.length() == 6 && mMaxLength == 6)) {
ViewUtil.hideOneInputMethod(LoginSQLiteActivity.this, mView); // 隱藏輸入法軟鍵盤
}
}
}
@Override
public void onClick(View v) {
String phone = et_phone.getText().toString();
if (v.getId() == R.id.btn_forget) { // 點(diǎn)擊了“忘記密碼”按鈕
if (phone.length() < 11) { // 手機(jī)號碼不足11位
Toast.makeText(this, "請輸入正確的手機(jī)號", Toast.LENGTH_SHORT).show();
return;
}
if (rb_password.isChecked()) { // 選擇了密碼方式校驗(yàn),此時(shí)要跳到找回密碼頁面
// 以下攜帶手機(jī)號碼跳轉(zhuǎn)到找回密碼頁面
Intent intent = new Intent(this, LoginForgetActivity.class);
intent.putExtra("phone", phone);
startActivityForResult(intent, mRequestCode); // 攜帶意圖返回上一個(gè)頁面
} else if (rb_verifycode.isChecked()) { // 選擇了驗(yàn)證碼方式校驗(yàn),此時(shí)要生成六位隨機(jī)數(shù)字驗(yàn)證碼
// 生成六位隨機(jī)數(shù)字的驗(yàn)證碼
mVerifyCode = String.format("%06d", new Random().nextInt(999999));
// 以下彈出提醒對話框,提示用戶記住六位驗(yàn)證碼數(shù)字
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("請記住驗(yàn)證碼");
builder.setMessage("手機(jī)號" + phone + ",本次驗(yàn)證碼是" + mVerifyCode + ",請輸入驗(yàn)證碼");
builder.setPositiveButton("好的", null);
AlertDialog alert = builder.create();
alert.show(); // 顯示提醒對話框
}
} else if (v.getId() == R.id.btn_login) { // 點(diǎn)擊了“登錄”按鈕
if (phone.length() < 11) { // 手機(jī)號碼不足11位
Toast.makeText(this, "請輸入正確的手機(jī)號", Toast.LENGTH_SHORT).show();
return;
}
if (rb_password.isChecked()) { // 密碼方式校驗(yàn)
if (!et_password.getText().toString().equals(mPassword)) {
Toast.makeText(this, "請輸入正確的密碼", Toast.LENGTH_SHORT).show();
} else { // 密碼校驗(yàn)通過
loginSuccess(); // 提示用戶登錄成功
}
} else if (rb_verifycode.isChecked()) { // 驗(yàn)證碼方式校驗(yàn)
if (!et_password.getText().toString().equals(mVerifyCode)) {
Toast.makeText(this, "請輸入正確的驗(yàn)證碼", Toast.LENGTH_SHORT).show();
} else { // 驗(yàn)證碼校驗(yàn)通過
loginSuccess(); // 提示用戶登錄成功
}
}
}
}
// 從下一個(gè)頁面攜帶參數(shù)返回當(dāng)前頁面時(shí)觸發(fā)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == mRequestCode && data != null) {
// 用戶密碼已改為新密碼,故更新密碼變量
mPassword = data.getStringExtra("new_password");
}
}
// 從修改密碼頁面返回登錄頁面,要清空密碼的輸入框
@Override
protected void onRestart() {
super.onRestart();
et_password.setText("");
}
@Override
protected void onResume() {
super.onResume();
mHelper = UserDBHelper.getInstance(this, 1); // 獲得用戶數(shù)據(jù)庫幫助器的實(shí)例
mHelper.openWriteLink(); // 恢復(fù)頁面,則打開數(shù)據(jù)庫連接
}
@Override
protected void onPause() {
super.onPause();
mHelper.closeLink(); // 暫停頁面,則關(guān)閉數(shù)據(jù)庫連接
}
// 校驗(yàn)通過,登錄成功
private void loginSuccess() {
String desc = String.format("您的手機(jī)號碼是%s,恭喜你通過登錄驗(yàn)證,點(diǎn)擊“確定”按鈕返回上個(gè)頁面",
et_phone.getText().toString());
// 以下彈出提醒對話框,提示用戶登錄成功
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("登錄成功");
builder.setMessage(desc);
builder.setPositiveButton("確定返回", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish(); // 結(jié)束當(dāng)前的活動(dòng)頁面
}
});
builder.setNegativeButton("我再看看", null);
AlertDialog alert = builder.create();
alert.show();
// 如果勾選了“記住密碼”,則把手機(jī)號碼和密碼保存為數(shù)據(jù)庫的用戶表記錄
if (bRemember) {
UserInfo info = new UserInfo(); // 創(chuàng)建一個(gè)用戶信息對象
info.phone = et_phone.getText().toString();
info.password = et_password.getText().toString();
info.update_time = DateUtil.getNowDateTime("yyyy-MM-dd HH:mm:ss");
mHelper.insert(info); // 往用戶數(shù)據(jù)庫添加登錄成功的用戶信息
}
}
// 焦點(diǎn)變更事件的處理方法,hasFocus表示當(dāng)前控件是否獲得焦點(diǎn)。
// 為什么光標(biāo)進(jìn)入密碼框事件不選onClick?因?yàn)橐c(diǎn)兩下才會(huì)觸發(fā)onClick動(dòng)作(第一下是切換焦點(diǎn)動(dòng)作)
@Override
public void onFocusChange(View v, boolean hasFocus) {
String phone = et_phone.getText().toString();
// 判斷是否是密碼編輯框發(fā)生焦點(diǎn)變化
if (v.getId() == R.id.et_password) {
// 用戶已輸入手機(jī)號碼,且密碼框獲得焦點(diǎn)
if (phone.length() > 0 && hasFocus) {
// 根據(jù)手機(jī)號碼到數(shù)據(jù)庫中查詢用戶記錄
UserInfo info = mHelper.queryByPhone(phone);
if (info != null) {
// 找到用戶記錄,則自動(dòng)在密碼框中填寫該用戶的密碼
et_password.setText(info.password);
}
}
}
}
}
LoginForgetActivity類
package com.example.chapter06;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Random;
@SuppressLint("DefaultLocale")
public class LoginForgetActivity extends AppCompatActivity implements View.OnClickListener {
private EditText et_password_first; // 聲明一個(gè)編輯框?qū)ο? private EditText et_password_second; // 聲明一個(gè)編輯框?qū)ο? private EditText et_verifycode; // 聲明一個(gè)編輯框?qū)ο? private String mVerifyCode; // 驗(yàn)證碼
private String mPhone; // 手機(jī)號碼
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_forget);
// 從布局文件中獲取名叫et_password_first的編輯框
et_password_first = findViewById(R.id.et_password_first);
// 從布局文件中獲取名叫et_password_second的編輯框
et_password_second = findViewById(R.id.et_password_second);
// 從布局文件中獲取名叫et_verifycode的編輯框
et_verifycode = findViewById(R.id.et_verifycode);
findViewById(R.id.btn_verifycode).setOnClickListener(this);
findViewById(R.id.btn_confirm).setOnClickListener(this);
// 從上一個(gè)頁面獲取要修改密碼的手機(jī)號碼
mPhone = getIntent().getStringExtra("phone");
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_verifycode) { // 點(diǎn)擊了“獲取驗(yàn)證碼”按鈕
if (mPhone == null || mPhone.length() < 11) {
Toast.makeText(this, "請輸入正確的手機(jī)號", Toast.LENGTH_SHORT).show();
return;
}
// 生成六位隨機(jī)數(shù)字的驗(yàn)證碼
mVerifyCode = String.format("%06d", new Random().nextInt(999999));
// 以下彈出提醒對話框,提示用戶記住六位驗(yàn)證碼數(shù)字
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("請記住驗(yàn)證碼");
builder.setMessage("手機(jī)號" + mPhone + ",本次驗(yàn)證碼是" + mVerifyCode + ",請輸入驗(yàn)證碼");
builder.setPositiveButton("好的", null);
AlertDialog alert = builder.create();
alert.show(); // 顯示提醒對話框
} else if (v.getId() == R.id.btn_confirm) { // 點(diǎn)擊了“確定”按鈕
String password_first = et_password_first.getText().toString();
String password_second = et_password_second.getText().toString();
if (password_first.length() < 6 || password_second.length() < 6) {
Toast.makeText(this, "請輸入正確的新密碼", Toast.LENGTH_SHORT).show();
return;
}
if (!password_first.equals(password_second)) {
Toast.makeText(this, "兩次輸入的新密碼不一致", Toast.LENGTH_SHORT).show();
return;
}
if (!et_verifycode.getText().toString().equals(mVerifyCode)) {
Toast.makeText(this, "請輸入正確的驗(yàn)證碼", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "密碼修改成功", Toast.LENGTH_SHORT).show();
// 以下把修改好的新密碼返回給上一個(gè)頁面
Intent intent = new Intent(); // 創(chuàng)建一個(gè)新意圖
intent.putExtra("new_password", password_first); // 存入新密碼
setResult(Activity.RESULT_OK, intent); // 攜帶意圖返回上一個(gè)頁面
finish(); // 結(jié)束當(dāng)前的活動(dòng)頁面
}
}
}
}
部分代碼與XML文件省略...文章來源:http://www.zghlxwxcb.cn/news/detail-778102.html
創(chuàng)作不易 覺得有幫助請點(diǎn)贊關(guān)注收藏文章來源地址http://www.zghlxwxcb.cn/news/detail-778102.html
到了這里,關(guān)于Android Studio App開發(fā)中數(shù)據(jù)庫SQLite的解析及實(shí)戰(zhàn)使用(包括創(chuàng)建數(shù)據(jù)庫,增刪改查,記住密碼等 附源碼必看)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!