Bmob實現短信登陸驗證自動記錄密碼安卓6.0動態獲取權限1.0版本
文章目錄
前言:
關於Bmob的問題太多而且那個官方文檔看的也雲裏霧裏,解決問題最好就是直接看他那個demo最實在
這個是我基於前面的文章寫的如果沒有看我前面的一些文章可能有些地方會看不懂
利用Bmob快速實現安卓的簡單登陸註冊功能Bmobsdk3.6.9版本親測可用(詳細圖文攻略附帶處理小bug)
利用Bmob快速實現安卓的登陸註冊功能帶正則手機號註冊驗證和基本密碼的判斷0.2版本
本文代碼下載地址:https://download.csdn.net/download/qq_16519957/11008139
1.自動記錄密碼
在原有的基礎之上添加自動記錄賬號密碼的功能
解決方案我們就使用SharedPreferences 這個輕量級的存儲類。我們先介紹一下SharedPreferences,SharedPreferences是Android平臺上一個輕量級的存儲類,主要是保存一些常用的配置參數,它是採用xml文件存放數據。SharedPreferences是一個接口,而且在這個接口裏沒有提供寫入數據和讀取數據的能力。但它是通過其Editor接口中的一些方法來操作SharedPreference的。(SharedPreferences對象本身只能獲取數據而不支持存儲和修改,存儲修改是通過Editor對象實現)
先來看一下我們的佈局:
非常簡單的一個佈局1個textview+2個edittext+1個CheckBox+2個button
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.beta.bmobtest.MainActivity"
android:orientation="vertical">
<TextView
android:gravity="center"
android:textSize="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登錄" />
<EditText
android:id="@+id/id_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="手機號"
android:inputType="phone" />
<EditText
android:id="@+id/id_userpassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="password"
android:inputType="textPassword" />
<CheckBox
android:id="@+id/remember"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="是否記住用戶名和密碼" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/id_ok"
android:layout_width="0dp"
android:text="登錄"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/id_register"
android:text="註冊"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
第一步我們先調用
private SharedPreferences pref;
private SharedPreferences.Editor editor;
組件綁定
pref= PreferenceManager.getDefaultSharedPreferences(this);
rememberPass=(CheckBox)findViewById(R.id.remember);
然後做一個判斷是不是設置
boolean isRemenber=pref.getBoolean("remember_password",false);
if(isRemenber){
//將賬號和密碼都設置到文本中
String account=pref.getString("account","");
String password=pref.getString("password","");
lgUser.setText(account);
lgPassword.setText(password);
rememberPass.setChecked(true);
}
最後chekbox的值傳入
editor=pref.edit();
if(rememberPass.isChecked()){
editor.putBoolean("remember_password",true);
editor.putString("account",lgU);
editor.putString("password",lgp);
}else {
editor.clear();
}
editor.apply();
我們來看一下完整的代碼:
package com.beta.bmobtest;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobUser;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.SaveListener;
public class MainActivity extends AppCompatActivity {
private Person p2;
private TextView lgUser;
private TextView lgPassword;
private Button btn_ok;
private Button btn_rg;
private CheckBox rememberPass;
private SharedPreferences pref;
private SharedPreferences.Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bmob.initialize(this, "你自己的appid");
addControl();
addLogin();
}
private void addLogin() {
btn_rg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
startActivity(intent);
}
});
btn_ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String lgU = lgUser.getText().toString().trim();
String lgp = lgPassword.getText().toString().trim();
editor=pref.edit();
if(rememberPass.isChecked()){
editor.putBoolean("remember_password",true);
editor.putString("account",lgU);
editor.putString("password",lgp);
}else {
editor.clear();
}
editor.apply();
final BmobUser bu2 = new BmobUser();
bu2.setUsername(lgU);
bu2.setPassword(lgp);
bu2.login(new SaveListener<BmobUser>() {
@Override
public void done(BmobUser bmobUser, BmobException e) {
if (e == null) {
Intent in_success = new Intent(MainActivity.this, Success.class);
startActivity(in_success);
} else {
Toast.makeText(MainActivity.this, "賬戶名或密碼不正確", Toast.LENGTH_SHORT).show();
//loge(e);
}
}
});
}
});
}
private void addControl() {
pref= PreferenceManager.getDefaultSharedPreferences(this);
rememberPass=(CheckBox)findViewById(R.id.remember);
lgUser = (TextView) findViewById(R.id.id_username);
lgPassword = (TextView) findViewById(R.id.id_userpassword);
btn_ok = (Button) findViewById(R.id.id_ok);
btn_rg = (Button) findViewById(R.id.id_register);
boolean isRemenber=pref.getBoolean("remember_password",false);
if(isRemenber){
//將賬號和密碼都設置到文本中
String account=pref.getString("account","");
String password=pref.getString("password","");
lgUser.setText(account);
lgPassword.setText(password);
rememberPass.setChecked(true);
}
}
}
參考:Android:用SharePreferences實現記住密碼功能
2.安卓6.0動態獲取權限
參考:一行代碼搞定漂亮的Android6.0權限申請界面
我們主要用到的就是發送短信那個和讀取手機狀態的權限申請,其他的權限暫且用不到。
我們使用是hipermissio這個開源來動態獲取權限這種就比較方便了自己寫的話就麻煩多了。
首先第一個步我們先在Gradle裏面dependencies
compile ‘me.weyye.hipermission:library:1.0.7’
然後就非常簡單了
寫入一行代碼
private void Permissionx() {
List<PermissionItem> permissions = new ArrayList<PermissionItem>();
permissions.add(new PermissionItem(Manifest.permission.SEND_SMS, getString(R.string.permission_send_sms_phone), R.drawable.permission_ic_sms));
permissions.add(new PermissionItem(Manifest.permission.READ_PHONE_STATE, getString(R.string.permission_read_phone_state), R.drawable.permission_ic_phone));
HiPermission.create(mContext)
.title(getString(R.string.permission_cus_title))
.permissions(permissions)
.msg(getString(R.string.permission_cus_msg))
.animStyle(R.style.PermissionAnimModal)
.style(R.style.PermissionDefaultGreenStyle)
.checkMutiPermission(new PermissionCallback() {
@Override
public void onClose() {
Log.i(TAG, "onClose");
showToast(getString(R.string.permission_on_close));
}
@Override
public void onFinish() {
showToast(getString(R.string.permission_completed));
}
@Override
public void onDeny(String permission, int position) {
Log.i(TAG, "onDeny");
}
@Override
public void onGuarantee(String permission, int position) {
Log.i(TAG, "onGuarantee");
}
});
}
然後我們直接在申請短信驗證發送請求最開始調用即可
case R.id.btn_countdown: {
mIntent = new Intent(mContext, RegisterCodeTimerService.class);
Permissionx();//安卓6.0動態獲取權限
// 將按鈕設置爲不可用狀態
register_countdown.setEnabled(false);
// 啓動倒計時的服務
startService(mIntent);
// 通過requestSMSCode方式給綁定手機號的該用戶發送指定短信模板的短信驗證碼
BmobSMS.requestSMSCode(mobile, "1", new QueryListener<Integer>() {
@Override
public void done(Integer smsId, BmobException e) {
if (e == null) {
showToast(getString(R.string.smssuccess) + smsId);
} else {
showToast(getString(R.string.failed) + smsId);
}
}
});
break;
}
3.Bmob手機短信驗證註冊基於bmobSDK3.6.9
這個短信驗證真的是坑,3.6.9版本集成了sms的功能以後就不用再去導入sms1.0.1的包但是文檔沒說,找了其他的別人寫的文檔又是老版本換成我自己的3.6.9版本導致發送不出去,然後各種問題頻發。最後還是在看bmob那個demo後才明白。
不得不說這個demo藏的有多深這裏我就不吐槽了。
github:https://github.com/bmob/bmob_android_demo_sms
關於導包
由於sdk3.6.9集成sms功能所以導包就是這個樣子請務必在最開頭的時候導入
import cn.bmob.v3.BmobSMS;
發送短信
這裏並沒有什麼太大的問題只要能獲取到editext中的手機號碼那個數據然後將其發送出去一般是沒有問題。
// 通過requestSMSCode方式給綁定手機號的該用戶發送指定短信模板的短信驗證碼
BmobSMS.requestSMSCode(mobile, "1", new QueryListener<Integer>() {
@Override
public void done(Integer smsId, BmobException e) {
if (e == null) {
showToast(getString(R.string.smssuccess) + smsId);
} else {
showToast(getString(R.string.failed) + smsId);
}
}
});
短信驗證
使用bmob的話自己會有一個在開頭需要進行驗證碼的輸入
而且如果根據環境和登陸情況的不同signorlogin這方法也不是一直用的要根據情況來具體要看bmob的開發文檔進行使用。
//Bmob註冊驗證方法
User p2 = new User();
p2.setMobilePhoneNumber(mobile);
p2.setPassword(password);
p2.signOrLogin(valiation,new SaveListener<BmobUser>() {//valiation關於獲取到驗證碼
@Override
public void done(BmobUser bmobUser, BmobException e) {
if (e == null) {
//判斷是否註冊成功成功則跳轉到登陸的頁面
Intent intent_register = new Intent(RegisterActivity.this, MainActivity.class);
startActivity(intent_register);
showToast(getString(R.string.user_success));
} else {
showToast(getString(R.string.user_failed)+e.getErrorCode()+e.getMessage());
}
}
});
PS關於這個問題一定要注意
setMobilePhoneNumber就是這個回調如果你用的是手機號註冊且沒有其他的方式登錄一定要用這個不然如果用setUsername來註冊的話會不行的手機號登錄註冊就只能用那個。
我們來看完整的代碼關於手機短信驗證註冊這一個的
RegisterCodeTimerService一個倒計時的廣播按鈕服務
package com.beta.bmobtest;
import android.app.Service;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.IBinder;
/**
* 註冊驗證碼計時服務
*
*/
public class RegisterCodeTimerService extends Service {
public static final String IN_RUNNING = "com.beta.bmobtest.IN_RUNNING";
public static final String END_RUNNING = "com.beta.bmobtest.END_RUNNING";
private static Handler mHandler;
private static CountDownTimer mCodeTimer;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 第一個參數是總時間, 第二個參數是間隔
mCodeTimer = new CountDownTimer(60000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
// 廣播剩餘時間
broadcastUpdate(IN_RUNNING, millisUntilFinished / 1000 + "");
}
@Override
public void onFinish() {
// 廣播倒計時結束
broadcastUpdate(END_RUNNING);
// 停止服務
stopSelf();
}
};
// 開始倒計時
mCodeTimer.start();
return super.onStartCommand(intent, flags, startId);
}
// 發送廣播
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
// 發送帶有數據的廣播
private void broadcastUpdate(final String action, String time) {
final Intent intent = new Intent(action);
intent.putExtra("time", time);
sendBroadcast(intent);
}
}
RegisterActivity
package com.beta.bmobtest;
import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.bmob.v3.BmobSMS;
import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobUser;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.QueryListener;
import cn.bmob.v3.listener.SaveListener;
import me.weyye.hipermission.HiPermission;
import me.weyye.hipermission.PermissionCallback;
import me.weyye.hipermission.PermissionItem;
/**
* Created by Kevein on 2019/3/1.8:03
*/
public class RegisterActivity extends Activity implements View.OnClickListener{
public static final String TAG = "RegisterActivity";
private Intent mIntent;
private Context mContext;
private EditText register_phone;
private EditText register_password;
private Button register_ok, register_countdown;
private EditText register_ValiDation;//輸入驗證碼
private void showToast(String text) {//簡化Toast
Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
}
//倒計時廣播
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
switch (action) {
case RegisterCodeTimerService.IN_RUNNING:
if (register_countdown.isEnabled())
register_countdown.setEnabled(false);
//正在倒計時
register_countdown.setText("獲取驗證碼(" + intent.getStringExtra("time") + ")");
Log.e(TAG, "倒計時中(" + intent.getStringExtra("time") + ")");
break;
case RegisterCodeTimerService.END_RUNNING:
//完成倒計時
register_countdown.setEnabled(true);
register_countdown.setText("獲取驗證碼");
break;
}
}
};
// 註冊廣播
private static IntentFilter updateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(RegisterCodeTimerService.IN_RUNNING);
intentFilter.addAction(RegisterCodeTimerService.END_RUNNING);
return intentFilter;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register_layout);
mContext = this;
addControl();//加載控件
Bmob.initialize(this, "你自己的appid");
}
@Override
protected void onResume() {
super.onResume();
// 註冊廣播
registerReceiver(mBroadcastReceiver, updateIntentFilter());
}
@Override
protected void onPause() {
super.onPause();
// 移除註冊
unregisterReceiver(mBroadcastReceiver);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy 方法調用");
}
private boolean isPhoneNumber(String phoneStr) {
//定義電話格式的正則表達式
String regex = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$";
//設定查看模式
Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
//判斷Str是否匹配,返回匹配結果
Matcher m = p.matcher(phoneStr);
return m.matches();
}
private boolean PasswordJudge(String pwStr) {
//密碼判斷以字母開頭,長度在6~18之間,只能包含字母、數字和下劃線
String pattern = "^[a-zA-Z]\\w{5,17}$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(pwStr);
return m.find();
}
private void addControl() {
register_ok = (Button) findViewById(R.id.id_register_ok);
register_phone = (EditText) findViewById(R.id.register_phone);
register_password = (EditText) findViewById(R.id.register_password);
register_countdown = (Button) findViewById(R.id.btn_countdown);
register_ValiDation = (EditText) findViewById(R.id.et_validation);
register_countdown.setOnClickListener(this);
register_ok.setOnClickListener(this);
}
//動態獲取手機狀態和發送短信權限
private void Permissionx() {
List<PermissionItem> permissions = new ArrayList<PermissionItem>();
permissions.add(new PermissionItem(Manifest.permission.SEND_SMS, getString(R.string.permission_send_sms_phone), R.drawable.permission_ic_sms));
permissions.add(new PermissionItem(Manifest.permission.READ_PHONE_STATE, getString(R.string.permission_read_phone_state), R.drawable.permission_ic_phone));
HiPermission.create(mContext)
.title(getString(R.string.permission_cus_title))
.permissions(permissions)
.msg(getString(R.string.permission_cus_msg))
.animStyle(R.style.PermissionAnimModal)
.style(R.style.PermissionDefaultGreenStyle)
.checkMutiPermission(new PermissionCallback() {
@Override
public void onClose() {
Log.i(TAG, "onClose");
showToast(getString(R.string.permission_on_close));
}
@Override
public void onFinish() {
showToast(getString(R.string.permission_completed));
}
@Override
public void onDeny(String permission, int position) {
Log.i(TAG, "onDeny");
}
@Override
public void onGuarantee(String permission, int position) {
Log.i(TAG, "onGuarantee");
}
});
}
@Override
public void onClick(View view) {
String mobile = register_phone.getText().toString().trim();
// String password = register_password.getText().toString().trim();
switch (view.getId()) {
case R.id.btn_countdown: {//發送短信驗證
mIntent = new Intent(mContext, RegisterCodeTimerService.class);//接收倒計時廣播
Permissionx();//安卓6.0動態獲取權限
// 將按鈕設置爲不可用狀態
register_countdown.setEnabled(false);
// 啓動倒計時的服務
startService(mIntent);
// 通過requestSMSCode方式給綁定手機號的該用戶發送指定短信模板的短信驗證碼
BmobSMS.requestSMSCode(mobile, "1", new QueryListener<Integer>() {
@Override
public void done(Integer smsId, BmobException e) {
if (e == null) {
showToast(getString(R.string.smssuccess) + smsId);
} else {
showToast(getString(R.string.failed) + smsId);
}
}
});
break;
}
case R.id.id_register_ok:
String password = register_password.getText().toString().trim();//獲取密碼
String valiation = register_ValiDation.getText().toString();//獲取驗證碼
boolean phone = isPhoneNumber(mobile);
//判斷密碼
boolean pwd = PasswordJudge(password);
if (mobile.isEmpty()||password.isEmpty()) {
showToast(getString(R.string.user_or_password_empty));
return;
}
else if(!phone)
{
showToast(getString(R.string.phone_failed));
return;
}
else if (!pwd) {
showToast(getString(R.string.userpassword_failed));
return;
} else if(TextUtils.isEmpty(valiation)){
showToast(getString(R.string.valiation_empty));
return;
}else
{
//Bmob註冊驗證方法
User p2 = new User();
p2.setMobilePhoneNumber(mobile);
p2.setPassword(password);
p2.signOrLogin(valiation,new SaveListener<BmobUser>() {//valiation關於獲取到驗證碼
@Override
public void done(BmobUser bmobUser, BmobException e) {
if (e == null) {
//判斷是否註冊成功成功則跳轉到登陸的頁面
Intent intent_register = new Intent(RegisterActivity.this, MainActivity.class);
startActivity(intent_register);
showToast(getString(R.string.user_success));
} else {
showToast(getString(R.string.user_failed)+e.getErrorCode()+e.getMessage());
}
}
});
break;
}
}
}
}
關於我的源碼已上傳github如果不錯的話麻煩點個star和點個贊:https://github.com/307572384/bmobtest