美文网首页
Android开发(10)——手机号验证登录

Android开发(10)——手机号验证登录

作者: 让时间走12138 | 来源:发表于2021-03-23 20:08 被阅读0次

    本节内容

    1.EditText简介

    2.Button简介

    3.Bomb三方库提供短信验证服务

    4.首页布局

    5.实现手机号自动分割

    6.解决bug并删除号码

    7.添加按钮界面跳转

    8.使用selector设置按钮点击状态颜色

    9.按钮文字颜色切换

    10.解决格式化号码转换为正常号码bug

    11.布局验证页面提示信息

    12.将输入的内容显示到小方格中

    13.Bmob环境搭建

    14.请求验证码

    15.验证输入的验证码

    一、EditText简介
    1.它可以监听文本改变的事件
    mPhoneEditText.addTextChangedListener(object:LoginTextWatcher(){
    override fun afterTextChanged(s: Editable?) {
      }
    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
          }
    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {           
         }
    }
    
    • 这三个事件分别是: afterTextChanged(文本改变之后)、onTextChanged(文本正在改变)和beforeTextChanged(文本改变之前)
    2.如果不想显示EditText中的光标,可以设置一下,将它去除
    android:cursorVisible="false"
    
    3.输入数字时,如果觉得数字间的间距很大,可以设置一下把间距加大
     android:letterSpacing="0.1"
    
    4.如果想要输入内容,但是又不想显示输入框,那么就可以将它的透明度设置得小一点,这样就可以将其隐藏起来。
    android:alpha="0.01"
    
    二、Button简介
    1.通过text属性设置按钮的文本,颜色,文字大小等前面都讲过,这里就不再详述。
    2.给按钮添加一个id之后,就可以给它设置点击事件了。
    3.比较特别的按钮有switch,也可以给switch设置点击事件。switch有一个比较特别的属性就是isChecked。在手机的设置里面可能会使用到switch。
     switch1.setOnClickListener {
                val s = it as Switch
                  if(s.isChecked){
                      mLogin.text = "打开了"
                  }else{
                      mLogin.text = "关闭了"
                  }
            }
    
    4.还有checkBox按钮,这些属性都比较简单,可以自行琢磨。
    三、Bmob三方库提供短信验证服务
    1.先在Bmob注册一个账号,进入主页之后,点击左上角创建应用
    image.png
    • 我这里是已经创建好了一个
    2.回到网站首页,点击文档进入文档中心。然后点击数据服务的Android。
    QQ图片20210322181427.png
    3.之后按照那一页的提示操作即可。
    • 首先导入SDK
    image.png
    • 反正跟着它一路向下操作即可。
    • 先在这里面添加底下那一行代码,也就是仓库地址
    allprojects { 
    repositories {
     //Bmob的maven仓库地址--必填
            maven {url 'https://dl.bintray.com/chaozhouzhang/maven' }
    
    • 然后在app的buildGradle的android里面添加依赖库
     useLibrary 'org.apache.http.legacy'
    
    • 然后在dependencies里面添加以下的依赖文件,然后同步一下。
     implementation 'cn.bmob.android:bmob-sdk:3.7.8'
        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'
    
    • 然后配置一下Mainfest,在里面添加以下权限
     <!-- 允许联网 -->
        <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" />
    
    • 配置ContentProvider
     <provider
                android:name="cn.bmob.v3.util.BmobContentProvider"
                android:authorities="com.example.message.BmobContentProvider"
                android:exported="false">
            </provider>
    
    • 初始化Bomb,重新创建一个类,重写onCreate()方法
    class MyApplication:Application() {
        override fun onCreate() {
            super.onCreate()
            //第一.默认初始化
            Bmob.initialize(this, "c12f5ff15568e1e18c72649071389bea");
        }
    }
    
    • Application ID从之前创建的应用的key里面查看。
    image.png
    • 通过 requestSMSCode 方式给绑定手机号的该用户发送指定短信模板的短信验证码:
    /**
     * TODO template 如果是自定义短信模板,此处替换为你在控制台设置的自定义短信模板名称;如果没有对应的自定义短信模板,则使用默认短信模板。
     */
    BmobSMS.requestSMSCode(phone, "DataSDK", new QueryListener<Integer>() {
        @Override
        public void done(Integer smsId, BmobException e) {
            if (e == null) {
                mTvInfo.append("发送验证码成功,短信ID:" + smsId + "\n");
            } else {
                mTvInfo.append("发送验证码失败:" + e.getErrorCode() + "-" + e.getMessage() + "\n");
            }
        }
    });
    
    四、首页布局
    我们要将界面布局成如下效果:
    QQ图片20210322190621.png
    image.png
    1.布局首页的时候,添加几个guideline,这样方便我们布局。
    image.png
    2.图片是一个正方形,我们之前讲过,在右侧属性中,点击那个矩形的左上角,让它的比例为1:1。
    3.中间添加一个EditText,调节一下它的大小。
    4.给输入框添加一个边框,所以在drawable中新建一个名为shape_roundrect的xml文件,然后把<selector>改为<shape>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    
        <corners android:radius="10dp"/>
        <stroke android:color="@color/colorGray"
            android:width="1dp"/>
        <solid android:color="@color/colorAlphaGray"/>
    </shape>
    
    5.然后找到EditText,把这个边框应用上
     android:background="@drawable/shape_roundrect"
    
    6.为了有更多的颜色可以选择,可以在values下添加一个colors.xml,在里面添加一些颜色
    <resources>
        <color name="colorPrimary">#6200EE</color>
        <color name="colorPrimaryDark">#3700B3</color>
        <color name="colorAccent">#03DAC5</color>
        <color name="colorGray">#666</color>
        <color name="colorAlphaGray">#2666</color>
        <color name="colorRed">#FF0000</color>
        <color name="colorBlack">#000</color>
    </resources>
    
    7.想要输入框内部的内容和边框有一点间距,那么就可以设置一下padding。(自己和自己的间距)
    android:paddingStart="10dp"
    
    8.给输入框设置一下默认提示文字
     android:hint="输入手机号"
    
    五、实现手机号自动分割
    1.我们平常输入手机号码时,都会自动分割为3 4 4 的形式。我们的实现思路为:时刻监听文本输入,当输入了三个数字之后添加一个空格,当输入八个字符之后,再添加一个空格。所以我们要给EditText添加一个监听事件,时刻监听它的变化。
     mPhoneEditText.addTextChangedListener(object:LoginTextWatcher(){
                override fun afterTextChanged(s: Editable?) {
                    //设置按钮是否可以点击
                    mLogin.isEnabled = (s.toString().length == 13)
    
                    //判断是在删除还是输入
                    if (!shouldAutoSplit) return
                    s.toString().length.also {
                        if (it == 3 || it == 8) {
                            //需要添加空格
                            s?.append(" ")
                        }
                    }
                }
    
                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                      shouldAutoSplit =( count ==1)
                }
            })
    
    2.对于TextWatcher监听器,我们只会用到其中的两个方法,但使用的时候还是不得不实现所有的方法。所以我们可以新建一个类,让它继承于TextWatcher,然后空实现这个接口的所有方法。后面新建的对象继承于我们创建的类即可。
    3.新建一个类,继承TextWatcher。
    open class LoginTextWatcher: TextWatcher{
        override fun afterTextChanged(s: Editable?) {
    
        }
    
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    
        }
    
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
    
        }
    
    }
    
    4.当字符串的长度为3和8时,需要添加空格。
     s.toString().length.also {
                        if (it == 3 || it == 8) {
                            //需要添加空格
                            s?.append(" ")
                        }
                    }
    
    5.因为输入的数字不超过11位,加上两个空格,就不超过13位。所以在EditText设置它的最大长度位13.
     android:maxLength="13"
    
    六、解决删除bug并获取号码
    1.经过上面的操作,我们发现了一个bug。当我们发现输错号码,想要删除时,结果到了空格那里,发现空格删不掉。
    • 因为当我们删到第八个的时候,它又执行afterTextChanged方法,结果发现长度为8,又添加一个空格,反反复复,所以删不掉。
    2.实验过程中,我们发现,在 onTextChanged方法中,添加数字的时候 count = 1,删除数据的时候 count=0。所以我们可以根据count的值来判断用户是在增加还是删除。所以我们可以定义一个变量来记录这个。
     private var shouldAutoSplit = true
    
    3.在afterTextChanged方法中,加一个判断是在删除还是输入。如果是在输入的话,那么就执行下面的添加空格。如果是在删除的话,那么就return,就不会执行添加空格的操作。
     if (!shouldAutoSplit) return
    
    4.如果count = 1,那么就是在做增加,那么 shouldAutoSplit = true,否则就是false
     override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                      shouldAutoSplit =( count ==1)
                }
    
    5.因为在输入的时候添加了空格,所以到时候传递过去的数据可能也包含空格。为了避免出现这种情况,我们就要把它转化为正常的数据。
     private fun getPhoneNumber(editable: Editable):String{
            //创建一个新的对象 用于操作editable对象里面的内容
            SpannableStringBuilder(editable.toString()).also {
                it.delete(3,4)
                it.delete(7,8)
                return it.toString()
            }
        }
    
    七、添加按钮界面跳转
    1.添加一个按钮,设置一个id,然后给它设置一个点击事件
    2.因为要跳转到另外一个界面,所以我们要准备好另外一个界面。在这个监听事件中只需要启动一下页面即可。
     mLogin.setOnClickListener{
                Intent().apply {
                    //跳转方向
                    setClass(this@MainActivity,VerifyActivity::class.java)
                    //配置跳转携带的数据
                    putExtra("phone",getPhoneNumber(mPhoneEditText.text))
                    //启动
                    startActivity(this)
                }
            }
    
    3.跳转过来的页面需要接收一下数据
    intent.getStringExtra("phone").also {
                    //显示号码
                      mPhone.text = it
                  }
    
    八、使用selector设置按钮点击状态颜色
    1.输入手机号的时候,只有输入了13位手机号,登录按钮才会被点击,界面才会跳转。为了实现这个功能,我们设置一下按钮的enabled属性,当它为fasle的时候,按钮是不能被点击的。
     android:enabled="false"
    
    2.在afterTextChanged方法中设置按钮是否可以点击,只有当位数为13时,按钮才能被点击。
       mLogin.isEnabled = (s.toString().length == 13)
    
    3.为了让用户能够直观到感受到按钮能否被点击,我们可以让按钮在不同时刻变更不一样的颜色。所以我们在drawable中新建一个xml。enabled状态不同,显示的颜色也不同。这样就可以根据控件的状态,实现选择器的效果。
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <!--
        根据控件的enable值 设置不同的颜色
        注意顺序:特殊在前 常规在后
        enable状态 运行起来正常状态 enable = true 其他状态 enable = false
        从上至下匹配
        -->
         <item android:drawable="@color/colorAccent"  android:state_enabled="true"/>
        <item android:drawable="@color/colorAlphaGray" android:state_enabled="false"/>
    </selector>
    
    4.把selector整好了以后,在按钮那里使用起来,把它的背景选为这个xml文件
    android:background="@drawable/btn_status_selector"
    
    九、按钮文字颜色切换
    1.为了美观,我们希望登录按钮文字的颜色也随用户的输入而变化,所以我们再创建一个xml。不能点击时,颜色为黑色。可以点击时,颜色为白色。
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item android:state_enabled="false" android:color="@color/colorBlack"/>
        <item android:state_enabled="true" android:color="@color/colorRed"/>
    </selector>
    
    2.在code再把textColor改为这个drawable中的文件
     android:textColor="@drawable/btn_text_selector"
    
    十、解决格式化号码转化为正常号码bug
    1.bug:当我们输入号码时,它会按照3 4 4 的格式正常分割,然后我们进行界面跳转。再返回当前界面时,会发现显示的是去空格后格式化的号码,而不是3 4 4 形式的号码。
    2.要避免出现这种情况,我们一开始就不能直接对editable进行操作。必须先把里面的东西取出来,然后再进行操作。所以我们用的是SpannableStringBuilder。
     SpannableStringBuilder(editable.toString()).also {
                it.delete(3,4)
                it.delete(7,8)
                return it.toString()
            }
    
    这就是前面我们这样使用的原因。
    十一、布局验证页面提示信息
    1.输入手机号之后,进入验证码验证页面,也就是输入验证码
    image.png
    2.上方图片调整为正方形,然后添加几个TextView即可。
    3.输入验证码的地方有六个小边框,每个框框对应一个数字。最外面用一个EditText来包裹一下,小的框框是TextView。
    4.添加六个TextView,让文字居中
    android:gravity="center"
    
    5.给这六个TextView添加六个边框,边框就是在drawable中新建一个xml,然后设置一下<shape>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <stroke android:color="@color/colorPrimary" android:width="1dp"/>
        <solid android:color="@color/colorAlphaGray"/>
        <corners android:radius="6dp"/>
    </shape>
    
    6.然后在code里面把background设置为这个drawable中的文件。
    7.拖动一个EditText,和这六个小框框重合,设置为match_parent,并设置其透明度为0.01
    十二、将输入的内容显示到小方格中
    1.给每个小框框添加id,为mv1——mv6。
    2.让EditText中的内容显示到每一个小方框中的方法:EditText中是一串字符串,字符串又有索引。只需要将索引对应的字符作为每一个小的TextView中的Text即可。
    3.保存所有显示验证码的textView
     private val verifyViews:Array<TextView> by lazy {
            arrayOf(mv1,mv2,mv3,mv4,mv5,mv6)
        }
    
    4.监听文本框内容改变的事件
     mOrigin.addTextChangedListener(object:TextWatcher{
                override fun afterTextChanged(s: Editable?) {
    
                }
    
                override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    
                }
    
                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
    }
    }
    
    5.这次我们只需要实现最后一个onTextChanged方法,所以后面的代码都是写在这个方法里面的。
    6.将输入的内容拆分到每一个textView中,其中i是索引,item是字符。
    for((i,item)in s?.withIndex()!!){
                       //获取i对应的textView
                       verifyViews[i].text = item.toString()
                   }
    
    7.如果位数小于6个 后面的文本框不显示任何内容。
     for(i in s.length..5){
                        verifyViews[i].text= ""
                    }
    
    8.设置Edit Text文本框最长输入长度为6.
    android:maxLength="6"
    
    十三、Bmob环境搭建
    1.当我们进入输入验证码的界面的时候,我们希望终端能自动向我们输入的号码发送短信。输入验证码之后,它又会将接收到的验证码和服务器发给用户的验证码进行比较,如果一致就返回一个结果,如果不一致就提示输入错误。这里我们就需要用到一个服务器发送短信。
    2.关于配置数据库和依赖库等,我已经在前面写过了。其中配置的应用包名为applicationId后面显示的内容。
    3.在Manifest里面配置一下name
    android:name=".MyApplication"
    
    十四、请求验证码
    1.不让这个EditText被长按。
    android:longClickable="false"
    
    2.为了方便管理Bmob操作,我们创建一个类来管理关于Bmob的操作。
    object BmobUtil {}
    
    3.实现的功能就是①向服务器 请求发送验证码,完成之后有两个返回值(发送成功、发送失败)②验证用户输入的验证码 (验证成功 、验证失败)
    4.先写一个发送验证码的方法,传递两个参数,第一个是手机号,第二个是回调的结果。我们这里用高阶函数作为返回的结果。
    fun requestSMSCode(phone:String,callBack:(Int)->Unit){
               BmobSMS.requestSMSCode(phone,"",object:QueryListener<Int>(){
                   override fun done(p0: Int?, p1: BmobException?) {
                       if(p1==null){
                            callBack(SUCCESS)
                       }else{
                            callBack(FAILURE)
                       }
                   }
               } )
        }
    
    • 为了方便理解,定义两个静态参数。
        const val SUCCESS = 0
        const val FAILURE = 1
    
    5.对于客户端来说,只要调用我们这里写好的方法就可以发送短信了。
    override fun onResume() {
            super.onResume()
            BmobUtil.requestSMSCode(mPhone.text.toString()){
                if(it==BmobUtil.SUCCESS){
                    Toast.makeText(this,"发送验证码成功",Toast.LENGTH_SHORT).show()
                }else{
                    Toast.makeText(this,"发送验证码失败",Toast.LENGTH_SHORT).show()
                }
            }
        }
    
    十五、验证输入的验证码
    1.在BmobUtil 类中重写一下验证的方法。第一个参数为电话号码,第二个参数为用户输入的验证码,第三个参数为匿名内部类。
    fun verifySMSCode(phone:String,code:String,callBack: (Int) -> Unit){
            BmobSMS.verifySmsCode(phone,code,object :UpdateListener(){
                override fun done(p0: BmobException?) {
                  if(p0==null){
                      //验证码验证成功
                      callBack(SUCCESS)
                  }else{
                      //验证失败
                      callBack(FAILURE)
                  }
                }
            })
        }
    
    2.发送验证请求之后,再判断验证成功与否。如果成功,则进行界面跳转。如果失败就提示一下,并清空文本框中的内容。
     if(s.length==6){
                        //发起验证的请求
                     BmobUtil.verifySMSCode(mPhone.text.toString(),s.toString()){
                         if(it==BmobUtil.SUCCESS){
                                startActivity(Intent(this@VerifyActivity,HomeActivity::class.java))
                         }else{
                             Toast.makeText(this@VerifyActivity,"验证失败",Toast.LENGTH_SHORT).show()
                            mOrigin.text.clear()
                         }
                     }
                    }
    
    3.自己创建一个简单的页面,作为验证成功后跳转的界面。就改一下背景颜色即可。只要能分辨得出和前面的页面不一样都行。之后在manifest中注册一下。
     <activity android:name=".HomeActivity"/>
    
    所有的操作基本完成,我们运行之后,发送短信,如果是正确的号码,就会收到这样的短信。
    QQ图片20210323200717.png

    相关文章

      网友评论

          本文标题:Android开发(10)——手机号验证登录

          本文链接:https://www.haomeiwen.com/subject/litocltx.html