Android基于Bmob后端云实现注册、登陆、找回密码、短信验证码


  • 注重版权,转载请注明原作者和原文链接
  • 作者:Bald programmer

整体功能展示

(1)对手机号码进行检测(中国大陆+港澳地区)和密码要求检测
(2)通过短信验证码进行账号注册
(3)账号和密码都保存到云端
(4)小眼睛(密码可见切换)
(5)获取验证码按钮60s冷却

创建应用

首先在Bmob注册自己的账号 https://www.bmob.cn/ 注册账号就不一一教学了

然后打开我的控制台 → 创建应用,名称自己填写,类型看自己选择,我们选择开发版
在这里插入图片描述
创建好应用之后,打开刚刚创建的应用,在这里可以管理我们的应用

点击短信,选择自定义模板
在这里插入图片描述
模板名称一定要填写,短信内容、签名我们使用默认的即可(有需要也可以自行修改)

在这里插入图片描述
保存之后等待审核,这个时间还是比较久的,大家耐心等待即可
在这里插入图片描述

配置Bmob

implementation 'io.github.bmob:android-sdk:3.8.2'
implementation "io.reactivex.rxjava2:rxjava:2.2.8"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'com.squareup.okhttp3:okhttp:3.14.1'
implementation 'com.squareup.okio:okio:2.2.2'
implementation 'com.google.code.gson:gson:2.8.5'

复制上面代码到如图位置,然后点击右上角的Sync Now加载
在这里插入图片描述

<!--允许联网 --> 
<uses-permission android:name="android.permission.INTERNET" /> 
<!--获取GSM(2g)、WCDMA(联通3g)等网络状态的信息  --> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<!--获取wifi网络状态的信息 --> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<!--保持CPU 运转,屏幕和键盘灯有可能是关闭的,用于文件上传和下载 -->
<uses-permission android:name="android.permission.WAKE_LOCK" /> 
<!--获取sd卡写的权限,用于文件上传和下载-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--允许读取手机状态 用于创建BmobInstallation--> 
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

复制上面代码到如图位置
在这里插入图片描述

<provider
android:name="cn.bmob.v3.util.BmobContentProvider"
android:authorities="com.example.bmobloginservice.BmobContentProvider">
</provider>

复制上面代码到如图位置,并将图中小方形的代码修改为你自己的包名
在这里插入图片描述
Bmob的配置工作到这里就结束了,接下来就是敲代码了······

前期准备

一、数据表

首先我们创建一个类,类名自己取(到时候在自动Bmob后台会创建一个和类名一样的表),继承BmobObject类
在这里插入图片描述

package com.example.bmobloginservice;

import cn.bmob.v3.BmobObject;

public class User_Table extends BmobObject {
    
    
    //账号
    private String Account;
    //密码
    private String Password;

    public String getAccount() {
    
    
        return Account;
    }

    public void setAccount(String account) {
    
    
        Account = account;
    }

    public String getPassword() {
    
    
        return Password;
    }

    public void setPassword(String password) {
    
    
        Password = password;
    }
}

表数据有Account账号、Password密码两个字段

二、工具类

新建一个Check类,创建两个方法用于号码检测(PhoneCheck)和密码检测(PasswordCheck)

号码检测
判断输入的收集号码是否满足国内号码的要求
密码检测
判断输入的密码是否满足要求(最少有3个字母)
package com.example.bmobloginservice;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Check {
    
    
    /**
     * 手机号码检测
     * @param phone:输入的号码
     * @return true -->>号码正确,false-->>号码不正确
     */
    public static boolean PhoneCheck(String phone){
    
    
        String ChineseMainland = "^((13[0-9])|(14[5,7,9])|(15[0-3,5-9])|(166)|(17[3,5,6,7,8])" + "|(18[0-9])|(19[8,9]))\\d{8}$";
        String HongKong = "^(5|6|8|9)\\d{7}$";

        Matcher C = Pattern.compile(ChineseMainland).matcher(phone);
        Matcher H = Pattern.compile(HongKong).matcher(phone);
        return C.matches() || H.matches();
    }

    /**
     * 密码检测(是否符合最少3个字母的要求)
     * @param password:输入的密码
     * @return true-->>密码格式正确,false-->>密码格式不正确
     */
    public static boolean PasswordCheck(String password){
    
    
        char[] s = password.toCharArray();
        int count=0;
        for (int i = 0; i < s.length; i++) {
    
    
            if ((s[i]>='a'&&s[i]<='z') || (s[i]>='A'&&s[i]<='Z')){
    
    
                count++;
            }
        }
        if (count>=3){
    
    
            return true;
        }else {
    
    
            return false;
        }
    }
}

代码设计

一、注册模块

布局文件
在这里插入图片描述
drawable包下的button_bg布局文件的代码

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#D1EEEE"></solid>
            <corners android:radius="50dp"></corners>
        </shape>
    </item>
</selector>

res包下的register布局文件的代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/background">

    <EditText
        android:id="@+id/AccountText"
        android:layout_width="300dp"
        android:layout_height="50dp"
        android:layout_marginTop="175dp"
        android:ems="10"
        android:hint="手机号码"
        android:textSize="16dp"
        android:drawableLeft="@mipmap/account"
        android:drawablePadding="10dp"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/PasswordText"
        android:layout_width="300dp"
        android:layout_height="45dp"
        android:layout_marginTop="30dp"
        android:ems="10"
        android:hint="密码由6~16位组成(最少3位字母)"
        android:textSize="16dp"
        android:drawableLeft="@mipmap/psd"
        android:drawablePadding="10dp"
        android:inputType="textPassword"
        app:layout_constraintStart_toStartOf="@+id/AccountText"
        app:layout_constraintTop_toBottomOf="@+id/AccountText" />

    <Button
        android:id="@+id/RegisterButton"
        android:layout_width="200dp"
        android:layout_height="60dp"
        android:layout_marginTop="100dp"
        android:background="@drawable/button_bg"
        android:text="注册"
        android:textSize="25dp"
        app:layout_constraintTop_toBottomOf="@+id/PasswordText"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <TextView
        android:id="@+id/RegisterTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="60dp"
        android:text="Register"
        android:textSize="40dp"
        app:layout_constraintBottom_toTopOf="@+id/AccountText"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/LoginButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="已有账号?点击登陆"
        android:textSize="15dp"
        app:layout_constraintRight_toRightOf="@id/PasswordText"
        app:layout_constraintTop_toBottomOf="@id/RegisterButton"/>

    <EditText
        android:id="@+id/SMS_Code"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:layout_marginTop="30dp"
        android:ems="10"
        android:hint="验证码"
        android:textSize="16dp"
        android:inputType="textPersonName"
        android:paddingLeft="10dp"
        app:layout_constraintLeft_toLeftOf="@id/PasswordText"
        app:layout_constraintTop_toBottomOf="@id/PasswordText" />

    <Button
        android:id="@+id/GetCode"
        android:layout_width="140dp"
        android:layout_height="50dp"
        android:layout_marginTop="30dp"
        android:background="#00000000"
        android:text="获取验证码"
        android:textSize="18dp"
        app:layout_constraintTop_toBottomOf="@id/PasswordText"
        app:layout_constraintRight_toRightOf="@id/PasswordText"/>

    <TextView
        android:id="@+id/ShowButton"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginBottom="5dp"
        android:background="@mipmap/eye"
        app:layout_constraintBottom_toBottomOf="@+id/PasswordText"
        app:layout_constraintRight_toRightOf="@+id/PasswordText"/>
</androidx.constraintlayout.widget.ConstraintLayout>

后台java代码

package com.example.bmobloginservice;


import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.BmobSMS;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.QueryListener;
import cn.bmob.v3.listener.SaveListener;
import cn.bmob.v3.listener.UpdateListener;

public class Register extends AppCompatActivity {
    
    
    TextView RegisterTitle; //注册标题
    EditText AccountText;   //账号
    EditText PasswordText;  //密码
    EditText SMS_Code;      //验证码

    TextView LoginButton;   //回到登录按钮
    Button RegisterButton;  //注册按钮
    Button GetCode;         //获取验证码按钮

    TextView ShowButton;    //小眼睛按钮
    boolean ShowPassword;   //密码可见状态(初始不可见)

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.register);
        Bmob.initialize(Register.this,"你的Application ID(Bmob设置里可以看到)");
        init();

        //获取验证码
        GetCode.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //获取客户端输入的账号
                final String Account = AccountText.getText().toString().trim();
                //isEmpty()方法判断是否为空
                if (TextUtils.isEmpty(Account)){
    
    
                    Toast.makeText(Register.this,"请填写手机号码",Toast.LENGTH_SHORT).show();
                }else if (Check.PhoneCheck(Account.trim()) != true){
    
    
                    Toast.makeText(Register.this,"请填写正确的手机号码",Toast.LENGTH_SHORT).show();
                }else {
    
    
                    BmobQuery<User_Table> bmobQuery = new BmobQuery<>();
                    bmobQuery.findObjects(new FindListener<User_Table>() {
    
    
                        @Override
                        public void done(List<User_Table> object, BmobException e) {
    
    
                            if (e == null) {
    
    
                                int count=0;    //判断是否查询到尾
                                for (User_Table user_table : object) {
    
    
                                    if (user_table.getAccount().equals(Account)){
    
    
                                        Toast.makeText(Register.this,"该账号已注册过",Toast.LENGTH_SHORT).show();
                                        break;
                                    }
                                    count++;
                                }
                                //查询到尾,说明没有重复账号
                                if (count == object.size()){
    
    
                                    SendSMS(Account);
                                }
                            }else {
    
    
                                SendSMS(Account);
                            }
                        }
                    });
                }
            }
        });

        /**
         * 注册
         */
        RegisterButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //账号(Account)、密码(Password)
                final String Account = AccountText.getText().toString().trim();
                final String Password = PasswordText.getText().toString().trim();
                if (TextUtils.isEmpty(Password)){
    
    
                    Toast.makeText(Register.this,"请填写密码",Toast.LENGTH_SHORT).show();
                }else if (Password.length()<6){
    
    
                    Toast.makeText(Register.this,"密码不得少于6位数",Toast.LENGTH_SHORT).show();
                }else if (Password.length()>16){
    
    
                    Toast.makeText(Register.this,"密码不得多于16位数",Toast.LENGTH_SHORT).show();
                }else if (Check.PasswordCheck(Password) != true){
    
    
                    Toast.makeText(Register.this,"密码最少包含3个字母",Toast.LENGTH_SHORT).show();
                }else if (TextUtils.isEmpty(SMS_Code.getText().toString().trim())){
    
    
                    Toast.makeText(Register.this,"请填写验证码",Toast.LENGTH_SHORT).show();
                } else {
    
    
                    //短信验证码效验
                    BmobSMS.verifySmsCode(Account, SMS_Code.getText().toString().trim(), new UpdateListener() {
    
    
                        @Override
                        public void done(BmobException e) {
    
    
                            if (e == null) {
    
    
                                //将用户信息存储到Bmob云端数据
                                final User_Table user = new User_Table();
                                user.setAccount(Account);
                                user.setPassword(Password);
                                user.save(new SaveListener<String>() {
    
    
                                    @Override
                                    public void done(String s, BmobException e) {
    
    
                                        if (e == null) {
    
    
                                            //注册成功,回到登录页面
                                            Toast.makeText(Register.this,"注册成功",Toast.LENGTH_SHORT).show();
                                            finish();
                                        }else {
    
    
                                            Toast.makeText(Register.this,"注册失败",Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                });
                            }else {
    
    
                                SMS_Code.setText("");
                                Toast.makeText(Register.this,"验证码错误"+e.getErrorCode(),Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
                }
            }
        });

        //返回登陆界面
        LoginButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                finish();
            }
        });

        ShowButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                if (ShowPassword == false) {
    
    
                    //密码不可见-->>密码可见
                    PasswordText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
                    PasswordText.setSelection(PasswordText.getText().toString().length());
                    ShowPassword = true;
                }else {
    
    
                    //密码可见-->>密码不可见
                    PasswordText.setTransformationMethod(PasswordTransformationMethod.getInstance());
                    PasswordText.setSelection(PasswordText.getText().toString().length());
                    ShowPassword = false;
                }
            }
        });
    }

    public void init(){
    
    
        //注册标题(Title)、账号(Account)、密码(Password)、验证码(SMS_Code)
        RegisterTitle = findViewById(R.id.RegisterTitle);
        AccountText = findViewById(R.id.AccountText);
        PasswordText = findViewById(R.id.PasswordText);
        SMS_Code = findViewById(R.id.SMS_Code);

        //回到登录按钮(Login)、注册按钮(Register)、验证码获取按钮(GetCode)
        LoginButton = findViewById(R.id.LoginButton);
        RegisterButton = findViewById(R.id.RegisterButton);
        GetCode = findViewById(R.id.GetCode);

        //将密码文本初始设置为不可见状态
        ShowButton = findViewById(R.id.ShowButton);
        ShowPassword = false;

        //设置标题字体样式(方舒整体 常规)
        RegisterTitle.setTypeface(Typeface.createFromAsset(getAssets(),"font/FZSTK.TTF"));
        //设置按钮文本字体样式(方舒整体 常规)
        RegisterButton.setTypeface(Typeface.createFromAsset(getAssets(),"font/FZSTK.TTF"));
        //设置背景图片透明度(0~255,值越小越透明)
        RegisterButton.getBackground().setAlpha(100);
    }

    /**
     * 发送验证码
     * @param account:输入的手机号码
     *  SMS 为Bmob短信服务自定义的短信模板名字
     */
    private void SendSMS(String account){
    
    
        BmobSMS.requestSMSCode(account, "自定义短信模板的名字", new QueryListener<Integer>() {
    
    
            @Override
            public void done(Integer smsId, BmobException e) {
    
    
                if (e == null) {
    
    
                    Toast.makeText(Register.this,"验证码已发送",Toast.LENGTH_LONG).show();
                } else {
    
    
                    Toast.makeText(Register.this,"发送验证码失败:" + e.getErrorCode() + "-" + e.getMessage(),Toast.LENGTH_SHORT).show();
                }
            }
        });
        /**
         * 设置按钮60s等待
         * onTick()方法——>>计时进行时的操作
         *      :显示倒计时,同时设置按钮不可点击
         * onFinish()方法——>>计时完成时的操作
         *      :刷新原文本,同时设置按钮可以点击
         */
        CountDownTimer timer =new CountDownTimer(60000,1000) {
    
    
            @Override
            public void onTick(long millisUntilFinished) {
    
    
                GetCode.setEnabled(false);
                GetCode.setText("重新获取("+millisUntilFinished/1000+"s)");
            }

            @Override
            public void onFinish() {
    
    
                GetCode.setEnabled(true);
                GetCode.setText("获取验证码");
            }
        }.start();
    }
}

二、登陆模块

布局文件
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/background">

    <EditText
        android:id="@+id/AccountText"
        android:layout_width="300dp"
        android:layout_height="50dp"
        android:layout_marginTop="175dp"
        android:ems="10"
        android:hint="手机号码"
        android:drawableLeft="@mipmap/account"
        android:drawablePadding="10dp"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/PasswordText"
        android:layout_width="300dp"
        android:layout_height="50dp"
        android:layout_marginTop="44dp"
        android:ems="10"
        android:hint="密码"
        android:drawableLeft="@mipmap/psd"
        android:drawablePadding="10dp"
        android:inputType="textPassword"
        app:layout_constraintStart_toStartOf="@+id/AccountText"
        app:layout_constraintTop_toBottomOf="@+id/AccountText" />

    <Button
        android:id="@+id/LoginButton"
        android:layout_width="200dp"
        android:layout_height="60dp"
        android:layout_marginTop="16dp"
        android:background="@drawable/button_bg"
        android:drawableLeft="@mipmap/login_button"
        android:paddingLeft="50dp"
        android:textSize="26dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/PasswordText" />

    <TextView
        android:id="@+id/LoginTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="60dp"
        android:text="Login"
        android:textSize="40dp"
        app:layout_constraintBottom_toTopOf="@+id/AccountText"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

    <TextView
        android:id="@+id/FindPasswordButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="忘记密码?"
        android:textSize="18dp"
        app:layout_constraintLeft_toLeftOf="@+id/PasswordText"
        app:layout_constraintTop_toBottomOf="@+id/LoginButton"/>

    <TextView
        android:id="@+id/RegisterButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="注册"
        android:textSize="18dp"
        app:layout_constraintRight_toRightOf="@id/PasswordText"
        app:layout_constraintTop_toBottomOf="@id/LoginButton"/>

    <TextView
        android:id="@+id/ShowButton"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginBottom="5dp"
        android:background="@mipmap/eye"
        app:layout_constraintRight_toRightOf="@+id/PasswordText"
        app:layout_constraintBottom_toBottomOf="@+id/PasswordText"/>

</androidx.constraintlayout.widget.ConstraintLayout>

后台java代码

package com.example.bmobloginservice;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.TextUtils;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;

public class Login extends AppCompatActivity {
    
    
    //标题、账号、密码
    TextView LoginTitle;
    EditText AccountText;
    EditText PasswordText;

    //登陆按钮、注册按钮、密码找回按钮
    Button LoginButton;
    TextView RegisterButton;
    TextView FindPasswordButton;

    //眼睛按钮
    TextView ShowButton;
    //密码可见状态
    boolean ShowPassword;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        Bmob.initialize(Login.this,"你的Application ID(Bmob设置里可以看到)");
        init();

        /**
         * 登陆监听
         */
        LoginButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //账号(Account)、密码(Password)
                final String Account = AccountText.getText().toString().trim();
                final String Password = PasswordText.getText().toString().trim();
                if (TextUtils.isEmpty(Account)) {
    
    
                    Toast.makeText(Login.this, "请填写手机号码", Toast.LENGTH_SHORT).show();
                } else if (TextUtils.isEmpty(Password)) {
    
    
                    Toast.makeText(Login.this, "请填写密码", Toast.LENGTH_SHORT).show();
                } else {
    
    
                    BmobQuery<User_Table> bmobQuery = new BmobQuery<>();
                    bmobQuery.findObjects(new FindListener<User_Table>() {
    
    
                        @Override
                        public void done(List<User_Table> object, BmobException e) {
    
    
                            if (e == null) {
    
    
                                //判断信号量,若查找结束count和object长度相等,则没有查找到该账号
                                int count=0;
                                for (User_Table user_table : object) {
    
    
                                    if (user_table.getAccount().equals(Account)) {
    
    
                                        //已查找到该账号,检测密码是否正确
                                        if (user_table.getPassword().equals(Password)) {
    
    
                                            //密码正确,跳转(Home是登陆后跳转的页面)
                                            Toast.makeText(Login.this, "登陆成功", Toast.LENGTH_SHORT).show();
                                            Intent intent = new Intent(Login.this,Home.class);
                                            startActivity(intent);
                                            break;
                                        }else {
    
    
                                            Toast.makeText(Login.this, "密码错误", Toast.LENGTH_SHORT).show();
                                            break;
                                        }
                                    }
                                    count++;
                                }
                                if (count >= object.size()){
    
    
                                    Toast.makeText(Login.this,"该账号不存在",Toast.LENGTH_SHORT).show();
                                }
                            }else {
    
    
                                Toast.makeText(Login.this,"该账号不存在",Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
                }
            }
        });

        //跳转到密码找回界面
        FindPasswordButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                Intent intent = new Intent();
                intent.setClass(Login.this, FindPassword.class);
                startActivity(intent);
            }
        });

        //跳转到注册界面
        RegisterButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                Intent intent =  new Intent();
                intent.setClass(Login.this, Register.class);
                startActivity(intent);
            }
        });

        //密码可见和不可见
        ShowButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                if (ShowPassword == false) {
    
    
                    PasswordText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
                    PasswordText.setSelection(PasswordText.getText().toString().length());
                    ShowPassword = true;
                }else {
    
    
                    PasswordText.setTransformationMethod(PasswordTransformationMethod.getInstance());
                    PasswordText.setSelection(PasswordText.getText().toString().length());
                    ShowPassword = false;
                }
            }
        });
    }

    //View初始化
    public void init(){
    
    
        //Login标题(LoginTitle)、账号(AccountText)、密码(PasswordText)
        LoginTitle = findViewById(R.id.LoginTitle);
        AccountText = findViewById(R.id.AccountText);
        PasswordText = findViewById(R.id.PasswordText);

        //登录按钮(Login)、跳到注册按钮(Register)、跳到密码找回按钮(FindPassword)
        LoginButton = findViewById(R.id.LoginButton);
        RegisterButton = findViewById(R.id.RegisterButton);
        FindPasswordButton = findViewById(R.id.FindPasswordButton);
        ShowButton = findViewById(R.id.ShowButton);

        //密码初始状态为不可见(false不可见,true可见)
        ShowPassword = false;
        //设置Login标题字体样式(华文彩云)
        LoginTitle.setTypeface(Typeface.createFromAsset(getAssets(),"font/FZSTK.TTF"));
        //设置背景图片透明度(0~255,值越小越透明)
        LoginButton.getBackground().setAlpha(100);
    }
}

三、找回密码

布局文件
在这里插入图片描述
XML代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/background">

    <EditText
        android:id="@+id/AccountText"
        android:layout_width="280dp"
        android:layout_height="50dp"
        android:layout_marginTop="175dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="手机号码"
        android:textSize="16dp"
        android:drawableLeft="@mipmap/account"
        android:drawablePadding="10dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <EditText
        android:id="@+id/SMS_Code"
        android:layout_width="120dp"
        android:layout_height="50dp"
        android:layout_marginTop="40dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="验证码"
        android:textSize="16dp"
        android:paddingLeft="10dp"
        app:layout_constraintTop_toBottomOf="@id/AccountText"
        app:layout_constraintLeft_toLeftOf="@id/AccountText"/>

    <Button
        android:id="@+id/GetCode"
        android:layout_width="140dp"
        android:layout_height="50dp"
        android:layout_marginTop="40dp"
        android:background="#00000000"
        android:text="获取验证码"
        android:textSize="18dp"
        app:layout_constraintTop_toBottomOf="@id/AccountText"
        app:layout_constraintRight_toRightOf="@id/AccountText"/>

    <EditText
        android:id="@+id/PasswordText"
        android:layout_width="280dp"
        android:layout_height="50dp"
        android:layout_marginTop="40dp"
        android:ems="10"
        android:hint="密码由6~16位组成(最少3位字母)"
        android:textSize="16dp"
        android:drawableLeft="@mipmap/psd"
        android:drawablePadding="10dp"
        android:inputType="textPassword"
        app:layout_constraintTop_toBottomOf="@id/SMS_Code"
        app:layout_constraintLeft_toLeftOf="@id/SMS_Code"/>

    <TextView
        android:id="@+id/FindPasswordTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="60dp"
        android:text="密码找回"
        android:textSize="30dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toTopOf="@id/AccountText"/>

    <TextView
        android:id="@+id/LoginButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="返回登陆"
        android:textSize="18dp"
        app:layout_constraintTop_toBottomOf="@id/ModifyButton"
        app:layout_constraintRight_toRightOf="@id/PasswordText"/>

    <Button
        android:id="@+id/ModifyButton"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:layout_marginTop="20dp"
        android:background="@drawable/button_bg"
        android:text="确认修改"
        android:textSize="20dp"
        app:layout_constraintTop_toBottomOf="@+id/PasswordText"
        app:layout_constraintRight_toRightOf="@+id/PasswordText"
        app:layout_constraintLeft_toLeftOf="@+id/PasswordText"/>

    <TextView
        android:id="@+id/ShowButton"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginBottom="3dp"
        android:background="@mipmap/eye"
        app:layout_constraintRight_toRightOf="@+id/PasswordText"
        app:layout_constraintBottom_toBottomOf="@+id/PasswordText"/>
</androidx.constraintlayout.widget.ConstraintLayout>

后台java代码

package com.example.bmobloginservice;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Typeface;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.BmobSMS;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.QueryListener;
import cn.bmob.v3.listener.UpdateListener;

public class FindPassword extends AppCompatActivity {
    
    
    EditText AccountText;
    EditText PasswordText;
    EditText SMS_Code;

    Button ModifyButton;
    Button GetCode;
    TextView FindPasswordTitle;
    TextView LoginButton;

    TextView ShowButton;
    boolean ShowPassword;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.find_password);
        Bmob.initialize(FindPassword.this,"你的Application ID(Bmob设置里可以看到)");
        init();
        /**
         * 获取验证码
         */
        GetCode.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //获取账号(Account)
                final String Account = AccountText.getText().toString().trim();
                if (TextUtils.isEmpty(Account)){
    
    
                    Toast.makeText(FindPassword.this,"请填写账号",Toast.LENGTH_SHORT).show();
                }else if (Check.PhoneCheck(Account) != true){
    
    
                    Toast.makeText(FindPassword.this,"请填写正确的手机号码",Toast.LENGTH_SHORT).show();
                }else {
    
    
                    BmobQuery<User_Table> bmobQuery = new BmobQuery<>();
                    bmobQuery.findObjects(new FindListener<User_Table>() {
    
    
                        @Override
                        public void done(List<User_Table> object, BmobException e) {
    
    
                            if (e == null) {
    
    
                                int count=0;
                                for (User_Table user_table : object) {
    
    
                                    //检查是否存在该账号
                                    if (user_table.getAccount().equals(Account)){
    
    
                                        SendSMS(Account);
                                        break;
                                    }
                                    count++;
                                }
                                if (count >= object.size()){
    
    
                                    Toast.makeText(FindPassword.this,"该账户不存在",Toast.LENGTH_SHORT).show();
                                }
                            }else {
    
    
                                Toast.makeText(FindPassword.this,"该账户不存在",Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
                }
            }
        });

        /**
         * 修改密码
         */
        ModifyButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //获取输入的账号(Account)、密码(Password)、验证码(Code)
                final String Account = AccountText.getText().toString().trim();
                final String Password = PasswordText.getText().toString().trim();
                String Code = SMS_Code.getText().toString().trim();
                if (TextUtils.isEmpty(Account)){
    
    
                    Toast.makeText(FindPassword.this,"请填写账号",Toast.LENGTH_SHORT).show();
                }else if (TextUtils.isEmpty(Code)){
    
    
                    Toast.makeText(FindPassword.this,"请填写验证码",Toast.LENGTH_SHORT).show();
                }else if (TextUtils.isEmpty(Password)){
    
    
                    Toast.makeText(FindPassword.this,"请填写密码",Toast.LENGTH_SHORT).show();
                }else if (Password.length()<6){
    
    
                    Toast.makeText(FindPassword.this,"密码不得少于6位数",Toast.LENGTH_SHORT).show();
                }else if (Password.length()>16){
    
    
                    Toast.makeText(FindPassword.this,"密码不得多于16位数",Toast.LENGTH_SHORT).show();
                }else if (Check.PasswordCheck(Password) != true){
    
    
                    Toast.makeText(FindPassword.this,"密码最少包含3个字母",Toast.LENGTH_SHORT).show();
                }else {
    
    
                    //发送验证码
                    BmobSMS.verifySmsCode(Account, Code, new UpdateListener() {
    
    
                        @Override
                        public void done(BmobException e) {
    
    
                            if (e == null) {
    
    
                                BmobQuery<User_Table> bmobQuery = new BmobQuery<>();
                                bmobQuery.findObjects(new FindListener<User_Table>() {
    
    
                                    @Override
                                    public void done(List<User_Table> object, BmobException e) {
    
    
                                        if (e == null) {
    
    
                                            for (User_Table user_table : object) {
    
    
                                                if (user_table.getAccount().equals(Account)){
    
    
                                                    //Bmob云端数据更新
                                                    User_Table user = new User_Table();
                                                    user.setPassword(Password);
                                                    user.update(user_table.getObjectId(), new UpdateListener() {
    
    
                                                        @Override
                                                        public void done(BmobException e) {
    
    
                                                            if (e == null) {
    
    
                                                                Toast.makeText(FindPassword.this,"密码修改成功",Toast.LENGTH_SHORT).show();
                                                            }else {
    
    
                                                                Toast.makeText(FindPassword.this,"修改失败"+"\n"+"错误代码:"+e.getErrorCode(),Toast.LENGTH_LONG).show();
                                                            }
                                                        }
                                                    });
                                                    break;
                                                }
                                            }
                                        }else {
    
    
                                            Toast.makeText(FindPassword.this,"该账号不存在",Toast.LENGTH_LONG).show();
                                        }
                                    }
                                });
                                finish();
                            }else {
    
    
                                Toast.makeText(FindPassword.this,"验证码错误",Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
                }
            }
        });

        //跳转登陆
        LoginButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                finish();
            }
        });

        ShowButton.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                if (ShowPassword == false) {
    
    
                    //密码不可见-->>密码可见
                    PasswordText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
                    PasswordText.setSelection(PasswordText.getText().toString().length());
                    ShowPassword = true;
                }else {
    
    
                    //密码可见-->>密码不可见
                    PasswordText.setTransformationMethod(PasswordTransformationMethod.getInstance());
                    PasswordText.setSelection(PasswordText.getText().toString().length());
                    ShowPassword = false;
                }
            }
        });
    }

    private void init(){
    
    
        //账号、密码、验证码
        AccountText = findViewById(R.id.AccountText);
        PasswordText = findViewById(R.id.PasswordText);
        SMS_Code = findViewById(R.id.SMS_Code);

        //回到登录按钮、获取验证码按钮、修改密码按钮
        FindPasswordTitle = findViewById(R.id.FindPasswordTitle);
        LoginButton = findViewById(R.id.LoginButton);
        GetCode = findViewById(R.id.GetCode);
        ModifyButton = findViewById(R.id.ModifyButton);

        //设置标题字体样式(方舒整体 常规)
        FindPasswordTitle.setTypeface(Typeface.createFromAsset(getAssets(),"font/FZSTK.TTF"));
        //眼睛按钮
        ShowButton = findViewById(R.id.ShowButton);
        ShowPassword = false;
    }

    /**
     * 发送验证码
     * @param account:输入的手机号码
     *  SMS 为Bmob短信服务自定义的短信模板名字
     */
    private void SendSMS(String account){
    
    
        //发送短信验证码
        BmobSMS.requestSMSCode(account, "自定义短信模板的名字", new QueryListener<Integer>() {
    
    
            @Override
            public void done(Integer integer, BmobException e) {
    
    
                if (e == null) {
    
    
                    Toast.makeText(FindPassword.this,"验证码已发送",Toast.LENGTH_LONG).show();
                }else {
    
    
                    Toast.makeText(FindPassword.this,"短信发送失败"+"\n"+"错误代码:"+e.getErrorCode(),Toast.LENGTH_LONG).show();
                }
            }
        });
        //设置按钮60s等待点击
        CountDownTimer timer = new CountDownTimer(60000,1000) {
    
    
            @Override
            public void onTick(long millisUntilFinished) {
    
    
                GetCode.setEnabled(false);
                GetCode.setText("重新获取("+millisUntilFinished/1000+"s)");
            }

            @Override
            public void onFinish() {
    
    
                GetCode.setEnabled(true);
                GetCode.setText("获取验证码");
            }
        }.start();
    }
}

最后运行测试效果,已成功注册到账号,并保存到Bmob后端云中
在这里插入图片描述

四、注意事项

自定义模板一定要等审核成功才能使用,不然会闪退报错
在这里插入图片描述
将代码中的appley里的字符串换成自己Bmob后端云的Application ID
在这里插入图片描述

在这里插入图片描述
完整项目代码下载点击下方链接
https://download.csdn.net/download/weixin_47971206/19965927


  • 本次文章分享就到这,有什么疑问或有更好的建议可在评论区留言,也可以私信我
  • 感谢阅读~

猜你喜欢

转载自blog.csdn.net/weixin_47971206/article/details/118226064