热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Android如何通过手机获取验证码来完成注册功能

注册app或者网络帐号的时候,经常需要手机获取验证码,来完成注册功能,那么android如何通过手机获取验证码来完成注册功能,代码是怎么实现的呢?下面看看小编给大家带了的一段代码分析吧

注册很多app或者网络账户的时候,经常需要手机获取验证码,来完成注册,那时年少,只是觉得手机获取验证码这件事儿很好玩,并没有关心太多,她是如何实现的,以及她背后的故事到底是什么样子的,现在小编接手的这个项目里面,就需要通过手机号进行注册,并且手机号发送相应的验证码,来完成注册,那么在一些应用app里面到底是如何实现点击按钮获取验证码,来完成注册这整个流程的呢?今天小编就以注册为例,和小伙伴们分享一下,如何通过手机号获取验证码来完成注册的一整套流程以及如何采用正则表达式来验证手机号码是否符合电信、移动、联通的规范。

       首先我们需要做的第一步就是ApiClient里面编写获取验证码的方法,具体代码如下:


/** 
   * 说明:获取验证码 
   * 作者:丁国华 
   * 时间:2015-8-27 下午5:47:36 
   */ 
  public static String getValidateCode(AppContext appContext, 
      Map map) throws AppException { 
    // 定义要访问的接口和要强转的实体 
    String validateUrl = _MakeURL(URLs.VALIDATE_CODE_URL, map); 
    ValidateCode validateCode = null; 
    try { 
      // 获取服务器端Json数据 
      String json = http_get(appContext, validateUrl); 
 
      // 解析为制定的实体对象 
      validateCode = (ValidateCode) JSON.parseObject(json, 
          ValidateCode.class); 
 
    } catch (Exception e) { 
      if (e instanceof AppException) 
        throw (AppException) e; 
      throw AppException.network(e); 
    } 
 
    // 返回验证码 
    return validateCode.getCode(); 
  } 
 

       第二步编写AppContent里面的接口方法,具体代码如下所示:

/** 
   * 说明:获取服务器验证码(不需要缓存) 
   * 作者:丁国华 
   * @date 2015-8-28 上午9:07:14 
   */ 
  public String getCode(Map map) throws AppException { 
 
    String validateCode = ""; 
 
    // 如果网络可连接且解析无误返回正确的验证码,否则返回空字符串 
    if (isNetworkConnected()) { 
      try { 
        validateCode = ApiClient.getValidateCode(this, map); 
      } catch (AppException e) { 
        if (validateCode == "") { 
          throw e; 
        } 
      } 
    } 
    return validateCode; 
  } 
 

        第三步,在StringUtils里面编写验证号码是否是手机号的正则表达式,具体代码如下:

 /* 说明:移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188 
   * 联通:130、131、132、152、155、156、185、186 
   * 电信:133、153、180、189 
   * 总结起来就是第一位必定为1,第二位必定为3或5或8,其他位置的可以为0-9 
   * 验证号码 手机号 固话均可 
   * 作者:丁国华 
   * 2015年9月20日 13:52:35 
   */ 
   public static boolean isPhoneNumberValid(String phoneNumber) { 
   boolean isValid = false; 
   String expression = "((^(13|15|18)[0-9]{9}$)|(^0[1,2]{1}\\d{1}-?\\d{8}$)|(^0[3-9] {1}\\d{2}-?\\d{7,8}$)|(^0[1,2]{1}\\d{1}-?\\d{8}-(\\d{1,4})$)|(^0[3-9]{1}\\d{2}-? \\d{7,8}-(\\d{1,4})$))"; 
   CharSequence inputStr = phoneNumber; 
   Pattern pattern = Pattern.compile(expression);  
   Matcher matcher = pattern.matcher(inputStr);  
   if (matcher.matches() ) { 
   isValid = true; 
   } 
   return isValid; 
   } 
   

      第四步:编写xml里面的文件,具体代码如下所示:

<&#63;xml version="1.0" encoding="utf-8"&#63;> 
 
   
    

        第五步:编写java类RegisterActivity里面的代码,具体如下所示:

package com.jczb.car.ui; 
import java.lang.ref.WeakReference; 
import java.util.HashMap; 
import java.util.Map; 
import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 
import android.widget.Toast; 
import com.jczb.car.AppContext; 
import com.jczb.car.AppException; 
import com.jczb.car.R; 
import com.jczb.car.common.StringUtils; 
/** 
 * 说明:注册功能页面 我们实现了取消线程的机制,从而保证它不会泄露 onDestroy()常常被用来在Activity推出前取消线程 
 * 作者: 吴利昌 
 * 时间: 2015-9-3上午9:19:15 
 */ 
public class RegisterActivity extends Activity implements OnClickListener { 
    // 声明用到的页面控件 
  private EditText etRegisterName; 
  private EditText etCode; 
  private EditText etPassword; 
  private Button btCode; 
  private Button btRegister; 
  private TextView tvUserProtocol; 
  private Button btRegisterLoginBack; 
  // 定义变量 
  private String userName; 
  private String passWord; 
  public boolean isChange = false; 
  private boolean tag = true; 
  private int i = 60; 
  Thread thread = null; 
  /**客户端输入的验证码*/ 
  private String valicationCode; 
  /**服务器端获取的验证码*/ 
  private static String serverValicationCode; 
  /** 注册时所带的参数 */ 
  private Map registerParams = new HashMap(); 
  /** 获取验证码时所带的参数 */ 
  private Map codeParams = new HashMap(); 
  /** 注册是否成功 */ 
  private String regisgerStatus; 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.register); 
    initView();    
  } 
  /** 
   * 说明:初始化页面控件和事件 
   * 作者: 吴利昌 
   * 时间: 2015-9-3 上午9:23:42 
   */ 
  public void initView() { 
    // 初始化控件 
    etRegisterName = (EditText) findViewById(R.id.et_register_username_id); 
    etCode = (EditText) findViewById(R.id.et_register_code_id); 
    etPassword = (EditText) findViewById(R.id.et_register_password_id); 
    btCode = (Button) findViewById(R.id.bt_getcode_id); 
    btRegister = (Button) findViewById(R.id.bt_register_id); 
    tvUserProtocol=(TextView)findViewById(R.id.user_protocol); 
    btRegisterLoginBack=(Button)findViewById(R.id.register_back_login); 
    // 初始化监听事件 
    btCode.setOnClickListener(this); 
    btRegister.setOnClickListener(this); 
    tvUserProtocol.setOnClickListener(this); 
    btRegisterLoginBack.setOnClickListener(this); 
  } 
  private boolean isvalidate() { 
    // TODO Auto-generated method stub 
    // 获取控件输入的值 
    String userName = etRegisterName.getText().toString().trim(); 
    if (StringUtils.isEmpty(userName)) { 
      Toast.makeText(this, "手机号不能为空", Toast.LENGTH_SHORT).show(); 
      return false; 
    } 
    if (!StringUtils.isPhoneNumberValid(userName)) { 
      Toast.makeText(this, "手机号有误", Toast.LENGTH_SHORT).show(); 
      return false; 
    } 
    return true; 
  } 
 
  @Override 
  public void onClick(View v) { 
    switch (v.getId()) { 
    case R.id.bt_getcode_id: 
      if(!isvalidate()) 
        break;   
      btCode.setText("获取验证码"); 
      btCode.setClickable(true); 
      isChange = true; 
      changeBtnGetCode(); 
      getValidateCode(); 
      break; 
    case R.id.bt_register_id: 
      register(); 
      break; 
    case R.id.user_protocol: 
      Intent intentUserProtocol = new Intent(this,UserProtocolActivity.class); 
      startActivity(intentUserProtocol); 
      break; 
    case R.id.register_back_login: 
      this.finish(); 
      break; 
    default: 
      break; 
    } 
  } 
     private void changeBtnGetCode() { 
    thread = new Thread() { 
      @Override 
      public void run() { 
        if (tag) { 
          while (i > 0) { 
            i--; 
            if (RegisterActivity.this == null) { 
              break; 
            }   
            RegisterActivity.this 
                .runOnUiThread(new Runnable() { 
                  @Override 
                  public void run() { 
                    btCode.setText("获取验证码(" 
                        + i + ")"); 
                    btCode 
                        .setClickable(false); 
                  } 
                }); 
            try { 
              Thread.sleep(1000); 
            } catch (InterruptedException e) { 
              throw new RuntimeException(e); 
            } 
          } 
          tag = false; 
        } 
        i = 60; 
        tag = true; 
        if (RegisterActivity.this != null) { 
          RegisterActivity.this.runOnUiThread(new Runnable() { 
            @Override 
            public void run() { 
              btCode.setText("获取验证码"); 
              btCode.setClickable(true); 
            } 
          }); 
        } 
      }; 
    }; 
    thread.start(); 
  } 
  /** 
   * 说明:获取验证码 
   * 
   * 作者: 吴利昌 
   * 时间: 2015-9-3 下午3:26:55 
   */ 
  public boolean getValidateCode() { 
     String name = etRegisterName.getText().toString().trim(); 
    String code = etCode.getText().toString().trim(); 
    if (name.equals("")) { 
      Toast.makeText(this, "请输入用户名或手机号!", Toast.LENGTH_SHORT).show(); 
      return false; 
    }else { 
      userName = name; 
      valicatiOnCode= code; 
      Thread codeThread = new Thread(codeRunnable); 
      codeThread.start(); 
    } 
    return true; 
  } 
  /** 
   * 说明:注册 
   * 
   * 作者: 吴利昌 
   * 时间: 2015-9-3 下午3:27:23 
   */ 
  public void register() { 
    // 1.首先判断输入的值是否有效 
    // 2.然后判断输入的验证码是否有效(防止没有点击获取验证码自己填的错误验证码) 
    // 3.最后注册 
    if (isValid()) { 
      if (valicationCode.equals(serverValicationCode)) { 
        Thread thread = new Thread(sRunnable); 
        thread.start(); 
      }else { 
        Toast.makeText(this, "输入的验证码不正确!", Toast.LENGTH_SHORT).show(); 
      } 
       
    } 
  }
  //--------------------------------获取验证码线程处理过程---开始----------------------------- 
  /** 
   * 自定义一个静态的具有弱引用的Handler,解决内存泄漏的问题,本handler用来获取验证码 
   */ 
  private static class CodeHandler extends Handler { 
    // 持有对本外部类的弱引用 
    private final WeakReference mActivity; 
    public CodeHandler(RegisterActivity activity) { 
      mActivity = new WeakReference(activity); 
    } 
    @Override 
    public void handleMessage(Message msg) { 
      // 获取上下文对象 
      RegisterActivity activity = mActivity.get(); 
      if (activity != null) { 
        switch (msg.what) { 
        case 1: 
          serverValicatiOnCode= (String)msg.obj; 
          //activity.etCode.setText(serverValicationCode); 
          break; 
        case -1: 
          Toast.makeText(activity, "获取验证码失败!", Toast.LENGTH_SHORT).show(); 
          break; 
        case 0: 
          Toast.makeText(activity, "哎呀,出错啦..", Toast.LENGTH_SHORT).show(); 
          break; 
        default: 
          break; 
        } 
      } 
    } 
  } 
  /**实例化自定义的handler*/ 
  private final CodeHandler codeHandler = new CodeHandler(this); 
  private String serverCode=null; 
  /**定义获取验证码的子线程*/ 
  private Runnable codeRunnable = new Runnable() { 
    @Override 
    public void run() { 
      Message msg = new Message(); 
      Map map = new HashMap(); 
      map.put("jbPhone", userName); 
      // 获取全局对象Application 
      AppContext appCOntext= (AppContext) getApplication(); 
      try { 
        // 获取服务器数据 
        serverValicatiOnCode= appContext.getCode(map); 
        // 返回true则将消息的what值为1,为false则what为-1,异常为0 
        if (serverValicationCode.equals("")) { 
          msg.what = -1; 
        } else { 
          msg.what = 1; 
          msg.obj = serverValicationCode; 
        } 
      } catch (AppException e) { 
        msg.what = 0; 
        e.printStackTrace(); 
      } 
      codeHandler.sendMessage(msg); 
    } 
  }; 

    //--------------------------------获取验证码线程处理过程----完成------------------------------  

   //--------------------------------注册线程处理过程--开始----------------------------------  

  /** 
   * 自定义一个静态的具有弱引用的Handler,解决内存泄漏的问题,注册使用 
   */ 
  private static class MyHandler extends Handler { 
    // 持有对本外部类的弱引用 
    private final WeakReference mActivity; 
 
    public MyHandler(RegisterActivity activity) { 
      mActivity = new WeakReference(activity); 
    } 
    @Override 
    public void handleMessage(Message msg) { 
       
      // 获取上下文对象 
      RegisterActivity activity = mActivity.get(); 
      if (activity != null) { 
        switch (msg.what) { 
        case 1: 
          Toast.makeText(activity, "注册成功!", Toast.LENGTH_SHORT).show(); 
          activity.finish(); 
          break; 
        case -1: 
          Toast.makeText(activity, "注册失败!", Toast.LENGTH_SHORT).show(); 
          break; 
        case -2: 
          Toast.makeText(activity, "该号已经注册!", Toast.LENGTH_SHORT).show(); 
          break; 
        case 0: 
          Toast.makeText(activity, "哎呀,出错啦..", Toast.LENGTH_SHORT).show(); 
          break; 
        default: 
          break; 
        } 
      } 
    } 
  } 
  /**实例化自定义的handler*/ 
  private final MyHandler mHandler = new MyHandler(this); 
  /**自定义子线程*/ 
  private Runnable sRunnable = new Runnable() { 
    @Override 
    public void run() { 
      Message msg = new Message(); 
      // 获取全局对象Application 
      AppContext appCOntext= (AppContext) getApplication(); 
      try { 
        // 获取服务器数据 
        regisgerStatus = appContext.register(registerParams); 
 
        // 返回true则将消息的what值为1,为false则what为-1,异常为0 
        if (regisgerStatus.equals("true")) { 
          msg.what = 1;          
          msg.obj = regisgerStatus; 
        } else if(regisgerStatus.equals("1")){ 
          msg.what = -2;            
        }else if(regisgerStatus.equals("false")){ 
          msg.what = -1;} 
      } catch (AppException e) { 
        msg.what = 0; 
        e.printStackTrace(); 
      } 
      mHandler.sendMessage(msg); 
    } 
  }; 

    //--------------------------------注册线程处理过程---完成-----------------------------------  

  /** 
   * 说明:注册之前判断数据是否为空 
   * 
   * @return 
   * 作者: 吴利昌 
   * 时间: 2015-9-3 下午3:29:04 
   */ 
  public boolean isValid() { 
    userName = etRegisterName.getText().toString().trim(); 
    valicatiOnCode= etCode.getText().toString().trim(); 
    passWord = etPassword.getText().toString().trim();      
    if (userName.equals("")) { 
      Toast.makeText(this, "用户名不能为空!", Toast.LENGTH_SHORT).show(); 
      return false; 
    } 
    if (valicationCode.equals("")) { 
      Toast.makeText(this, "验证码不能为空!", Toast.LENGTH_SHORT).show(); 
      return false; 
    }  
    if(!serverValicationCode.equals(valicationCode)) 
     { 
      Toast.makeText(this, "验证码错误", Toast.LENGTH_SHORT).show(); 
      return false; 
    }  
    if (passWord.equals("")) { 
      Toast.makeText(this, "密码不能为空!", Toast.LENGTH_SHORT).show(); 
      return false; 
    } else if (passWord.length() <6) { 
      Toast.makeText(this, "密码至少6位!", Toast.LENGTH_SHORT).show(); 
      return false; 
    }  
    registerParams.put("username", userName); 
    registerParams.put("psd", passWord);  
    return true; 
  } 
} 
 


       最后,我们来运行一下,看看我们的效果,由于小编的genymotion不知道为什么不能运行了,所以委屈小伙伴们一下,看不了动态图片了,不过并不影响,我们首先用一个号码好注册一下,如下图所示:

        看一下手机收到的验证码:   

        最后来看一下,我们的注册:       

 

小编寄语:该博文,小编主要简单的介绍了如何通过手机获取验证码来完成注册的功能,以及如何利用正则表达式来验证码手机号码是否符合移动、联通、电信。还是那句话对于小编来说,既是挑战更是机遇,因为知识都是相通的,再者来说,在小编的程序人生中,留下最珍贵的记忆,虽然以后小编不一定从事安卓这个行业,代码世界里,很多种事,有的甜蜜,有的温馨,有的婉转成歌,有的绵延不息,在这些故事里,我们唯一的共通之处就是,某年,某月,某个波澜不惊的日子里,曾经很爱很爱你!爱你--这段实习的日子里,安卓带给小编的种种的惊喜。  


推荐阅读
  • 本文介绍了如何使用Postman构建和发送HTTP请求,包括四个主要部分:方法(Method)、URL、头部(Headers)和主体(Body)。特别强调了Body部分的重要性,并详细说明了不同类型的请求体。 ... [详细]
  • Java EE 平台集成了多种服务、API 和协议,旨在支持基于 Web 的多层应用程序开发。本文将详细介绍 Java EE 中的 13 种关键技术规范,帮助开发者更好地理解和应用这些技术。 ... [详细]
  • 本文介绍了如何查看PHP网站及其源码的方法,包括环境搭建、本地测试、源码查看和在线查找等步骤。 ... [详细]
  • ABP框架是ASP.NET Boilerplate的简称,它不仅是一个开源且文档丰富的应用程序框架,还提供了一套基于领域驱动设计(DDD)的最佳实践架构模型。本文将详细介绍ABP框架的特点、项目结构及其在Web API优先架构中的应用。 ... [详细]
  • 本文讲述了一位80后的普通男性程序员,尽管没有高学历,但通过不断的努力和学习,在IT行业中逐渐找到了自己的位置。从最初的仓库管理员到现在的多技能开发者,他的职业生涯充满了挑战与机遇。 ... [详细]
  • 本文介绍了 JSON Schema 和 XML Schema 的基本概念,并详细讲解了如何使用 AJV 进行 JSON 数据校验。通过具体的示例和扩展方法,帮助读者更好地理解和应用这些工具。 ... [详细]
  • Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ... [详细]
  • java解析json转Map前段时间在做json报文处理的时候,写了一个针对不同格式json转map的处理工具方法,总结记录如下:1、单节点单层级、单节点多层级json转mapim ... [详细]
  • 短视频app源码,Android开发底部滑出菜单首先依赖三方库implementationandroidx.appcompat:appcompat:1.2.0im ... [详细]
  • SvpplyTable: 实现可扩展和可折叠的菜单动画
    SvpplyTable 是一个示例项目,旨在实现类似 Svpply 应用程序中的可扩展和可折叠的菜单动画效果。该项目托管在 GitHub 上,地址为 https://github.com/liuminqian/SvpplyTable。 ... [详细]
  • Bootstrap 插件使用指南
    本文详细介绍了如何在 Web 前端开发中使用 Bootstrap 插件,包括自动触发插件的方法、插件的引用方式以及具体的实例。 ... [详细]
  • 如何解决TS1219:实验性装饰器功能可能在未来版本中更改的问题
    本文介绍了两种方法来解决TS1219错误:通过VSCode设置启用实验性装饰器,或在项目根目录下创建配置文件(jsconfig.json或tsconfig.json)。 ... [详细]
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
  • MongoDB核心概念详解
    本文介绍了NoSQL数据库的概念及其应用场景,重点解析了MongoDB的基本特性、数据结构以及常用操作。MongoDB是一个高性能、高可用且易于扩展的文档数据库系统。 ... [详细]
  • 微信发布 Tinker 1.9.5:增强的 Android 热修复框架
    Tinker 是微信团队开源的一款 Android 热修复框架,能够在不更新 APK 的情况下,动态地修复应用中的问题,包括 dex、库文件和资源文件的更新。 ... [详细]
author-avatar
小古
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有