美文网首页创业安卓开发学习android
注册信息验证时的用户体验提升

注册信息验证时的用户体验提升

作者: hellojammyPlus | 来源:发表于2015-01-26 17:59 被阅读1614次

    点击访问原文
    您还可以加入全栈技术交流群(QQ群号:254842154)


    注册账号时,通常会需要用户填写邮箱或手机号,这两个信息对于同一个网站或App来说需要有这两个特性:唯一性,有效性。

    唯一性是方便我们能准确地“认识”到用户,就像公民身份证号一样,一个用户只能对应一个身份证号,同样地,一个邮箱或手机号只能在网站上被注册一次,被用作登录的账号。

    有效性是为了确保用户信息是经过验证的,这一点需要用户自己来承担。通常,我们通过向用户填写的邮箱发送激活邮件,或者向用户的手机里发送短信验证码来保证。另外,在有效性得到保证后,对用户来说也是有极大好处的,其中之一就是可以很方便地重设密码。

    验证邮箱有效性流程:填写注册信息(包括邮箱) -> 注册完成 -> 系统发送激活邮件到邮箱 -> 用户登录邮箱点击激活链接 -> 验证成功。激活链接里一般会有一个激活码,后台保证该激活码的有效时间。

    验证手机号有效性流程:填写注册信息(包括手机号) -> 注册完成 ->系统发送验证码到手机 -> 用户接收短信并填写验证码 -> 验证成功。

    邮箱验证的过程不在本文的讨论范围,以后有空再另写文章。这里重点讨论使用手机App的场景下,如何提高用户接收短信验证码的体验。我认为可以从以下3方面入手:

    短信内容

    短信内容里要包含以下信息:公司名称,验证码。还有一些附加信息,如告知验证码的过期时间,公司的网站地址,甚至插播一些广告(好吧,微信朋友圈都开始打广告了,我们也别太矜持了)。这些信息的排列最好能有一个优先级。建议排序:公司名称 -> 验证码 -> 其他信息。

    手机在接收到短信时,通常都会有信息预览的功能(假如该功能关闭了,那就没辙了,不过收件箱里也是有预览的)。Android手机会在顶部通知栏中显示,或弹框,iPhone手机也会弹框。预览功能只会显示短信内容的很有限部分,多余的必须点击进去才能看到,所以较好的短信应该是长成这样的:

    【公司名称】验证码是:123877。xxx

    公司名称最好是一个简称,这样能尽量在预览部分能看到验证码数字。
    下面给出一些实际的例子:

    【滴滴打车】(1445)滴滴打车验证码

    验证码:119244,请于10分钟内完成手机号验证操作。【创投圈vc.cn】

    验证码

    验证码最好为纯数字,这样方便用户快速输入,另外,验证码的长度不宜过长,建议为6位数字。数字和字母组合就算了吧,我们没必要在这个环节难为用户。

    自动填充

    用户在收到短信验证码后,需要简单地记一下验证码然后把输入法切换到数字状态,输入验证码。这个过程假如不出BUG,可以在5s内完成。

    现在问,可否帮用户省去这5s的时间?答案当然是可以的。

    这是一个非常细节的体验,我们不做,用户也不会觉得有任何问题,但是假如我们做了,就会给用户一种“智能”的感觉。


    下面以Android为例,看看我是如何帮用户省去这5s时间的。原理非常简单:手机收到验证码短信后,程序自动识别验证码并填充验证码输入框。

    思路是有了,实现的方式也有多种:

    1、开启一个线程,隔一段时间就去查询收件箱是否有变化,有变化再读取出来做处理。

    2、注册一个短信变化的广播,收到广播后再去读取出来做处理。

    3、通过ContentObserver(内容观察者)来捕获特定Uri的变化。

    方案1,显然不可以取,太耗资源。

    方案2,实际应用起来是会有问题的,因为短信的广播是有序广播,假如有其他应用先捕获广播并终止传递,那么我们就永远也收不到这条短信变化的广播了。

    所以,综合比较起来,方案3比较可取。经过笔者实践也是没有问题的。

    先来点介绍性文字吧。

    “ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,相应地ContentObserver也分为“表“ContentObserver、“行”ContentObserver,当然这是与它所监听的Uri MIME Type有关的。”

    下面给出方案3的关键性代码:

    1、AndroidManifest.xml文件中配置短信读取权限

    <uses-permission android:name="android.permission.READ_SMS" />
    

    2、监听短信变化的类

    public class SmsContentObserver extends ContentObserver{
        private static final String TAG = "SmsContentObserver";
        private Context mContext;
        private Handler mHandler;
        public SmsContentObserver(Context context,Handler handler){
            super(handler);
            this.mContext = context;
            this.mHandler = handler;
        }
    
        //短信格式:【白羽毛金融】您的FellowPlus验证码是:394421
        @Override
        public void onChange(boolean selfChange) {
            Uri inBoxUri = Uri.parse("content://sms/inbox");
            Cursor c = mContext.getContentResolver().query(inBoxUri, null, null, null,"date desc");
            if(c != null){
                while(c.moveToNext()){
                    String body = c.getString(c.getColumnIndex("body"));
                    if(body.startsWith("【白羽毛金融】")){
                        String verifyCode = body.substring(body.length() - 6 - 1 , body.length());
                        Message msg = Message.obtain();
                        msg.what = 1;
                        msg.obj = verifyCode;
                        mHandler.sendMessage(msg);
                        break;
                    }
                }
                c.close();
            }
        }
    }
    

    当短信有变化时,把短信内容读取出来,并按时间由高到低排序。根据自己项目需要的短信验证码的格式匹配(我这里的匹配方法写的很LOW,-_-||)。找到后,可以不用继续读取短信直接break。这里通过Handler的去更新UI。

    3、注册/取消注册监听

    通常是在onResum中去注册短信监听,在onStop中取消注册。

    @Override
    protected void onStop() {
        super.onStop();
        unRegisterSmsContentObservers();
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        registerSmsContentObservers();
    }
    
    private void registerSmsContentObservers() {
        Uri smsUri = Uri.parse("content://sms");
       //smsContentObserver是SmsContentObserver的一个实例,可以在onCreate中初始化
       getContentResolver().registerContentObserver(smsUri, true,smsContentObserver);
    }
    
    private void unRegisterSmsContentObservers() {   getContentResolver().unregisterContentObserver(smsContentObserver);
    }
    

    注意,虽然我们监听的是收件箱inbox,但是在注册时需要监听所有短信的变化。这句很重要:

    Uri.parse("content://sms")
    

    不能写成

    Uri.parse("content://sms/inbox")
    

    其实,通过ContentObserver还能做很多事情。更多功能等待大家去发现。

    更高级的体验

    在上述场景中,还是需要用户去填写手机号,接收验证码。我在考虑,有没有这样一种体验,它让用户感知到这不是一个接收验证码的过程的,但是又能很好地验证手机号的有效性呢?答案是有的,我们可以这样做:自动读取手机号,服务器发验证码,客户端接收后自动到服务端验证,最后通过。这个过程没有界面,用户唯一需要做的,就是要授权app一些权限(如发送短信的权限,读取短信的权限,android会弹框提示授权)。这视乎是一个很好的体验。

    目前我只发现一个应用是这样做的,招商证券的android客户端。

    另外,我还发现有些网站的验证码是通过回拨一个电话过来,然后电话里有一个机器人读验证码,你需要记下来然后填写。例如,美团外卖就是这样做的。我认为这样做是有特别原因的,比如,送外卖的需要确保手机就在你身边并且能接听电话,因为外卖来了你要接电话去取。

    欢迎大家跟我交流。

    相关文章

      网友评论

      • yuyu000:在魅族手机上 , 无法监听到短信变化 。 广播和ContentObserver 均无法监听 (华为和模拟器可以监听)。
        大佬可知如何解决?
      • 7f50d621c647:写的很好啊,但是那些onResume和onStop方法写在哪里?我在mainactivity中没有办法注册内容观察者啊,想了很久
        hellojammyPlus:@人间失格 写在接收验证码的那个activity
      • hellojammyPlus:@breakingbad 是的,这样修改会好点。谢谢批评指正。
      • hellojammyPlus:@breakingbad 是的,假如只是单纯地想为用户填写验证码,就不用手机号了。假如要悄悄发短信,那就要读取了。这个是有一个取舍的。
      • breakingbad:读验证短信while(c.moveToNext()){。。。}这里写得有点问题。
        当其他的非验证短信发过来的时候,你这里读取到的是以前的短信验证码(如果有的话)。
        把while改为if就好了,只从最新的一条短信中读取。
      • breakingbad:@hellojamny 有些手机读取不了手机号
      • hellojammyPlus:@truelie 假如不验证的话,那么用户填写的信息准确性就无法保证。也有不需要用户参与的,就是自动读取手机号,然后系统发送一个验证码过来,然后再自动读取验证码,这几个过程都是用户无感知的。缺点就是需要用户授权。招商证券的android客户端注册就是这样的,你完全无感知,只要授权即可。
      • hellojammyPlus:@truelie 还有一种验证方式,就是填完手机号并点击“获取验证码”后,你会收到一个电话,电话里是一个机器人,它会告诉你验证码,然后你再填写。这种方式更加严格,它能确保你的手机是正常的,而且是人在接听。 目前为止我还没有看到其他更新颖的方式,通常都是接收验证码。
        游学者崔斯特:@hellojamny 这种方式我最讨厌了 打什么电话
      • truelie:真好,实现路径都有了
        我在思考三个问题:
        1、可不可以不验证?或者什么样的产品才需要验证?
        2、验证其实是在确定产品与手机/手机号的对话是真实有效的,那么有没有其他更好的方式,甚至不需要让用户参与。
        3、手机验证码是有短信成本的。

      本文标题:注册信息验证时的用户体验提升

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