Android 必知必会 - 极简版 Leancloud 短信验证码功能

使用 LeanCloud 的 REST API 来自定义短信验证码相关功能,不再需要臃肿的 SDK 。

背景

公司的项目仅仅使用了 Leancloud 短信功能来发送验证码,刚开始 Leancloud 的短信 SDK 还会和项目中的 okhttpfastjson 产生冲突,后来使用了独立的命名空间解决了冲突,但这样处理会导致项目中产生大量的冗余库。在仅仅使用短信验证码功能 SDK 的情况下会有下列文件被引入到项目中:

  • avoscloud-sdk-v3.13.8.jar
  • fastjson-1.1.39-leancloud.jar
  • okhttp-2.6.0-leancloud.jar
  • okio-1.6.0-leancloud.jar

本来开发 Android 时,大家都尽量避免触碰 64K 个方法的限制,对于发验证码这样一个简单的事情,还需要引入大量的第三方库实在是难以接受。

在目前开发的新项目中,我尽量控制第三方库的筛选和使用,不想引起启用 Multidex 导致应用启动慢的问题。直到我发现 Leancloud 的 REST API ,顿时觉得里面有搞头,对,大有搞头

搞点事情

首先贴下文档地址:短信服务 REST API 详解 ,建议先进行初步阅读了解基础概念。

REST API 是请求接口,与具体的语言无关,这里仅仅演示 Android 下使用 Java 语言的一个实现。

项目中使用的是 okhttp-3.4.1gson-2.7 ,当然你也可以使用其他网络请求库和JSON 解析库。下面上关键代码:

OkHttpUtil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Constants.APP_KEY 和 Constants.APP_ID 在 LeanCloud 控制台获取
// String MD5Util.string2MD5(String s); 进行 MD5 加密的一个方法。
// 项目使用了 Logger 日志库,没使用的话请自行删除相关代码...

public class OkHttpUtil {
private static OkHttpUtil OkHttpUtil = new OkHttpUtil();
private static OkHttpClient client;

public static OkHttpUtil getInstance() {
client = new OkHttpClient().newBuilder().build();
return OkHttpUtil;
}
public Boolean postJson(String target, String json) {
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody requestBody = RequestBody.create(JSON, json);
long timestamp = System.currentTimeMillis();
String sign = MD5Util.string2MD5(timestamp + Constants.APP_KEY);
Request request = new Request.Builder()
.addHeader("X-LC-Id", Constants.APP_ID)
.addHeader("X-LC-Sign", sign + "," + timestamp)
.url(target)
.post(requestBody)
.build();
try {
Response response = client.newCall(request).execute();
//判断请求是否成功
if (response.isSuccessful()) {
return true;
} else {
Logger.e(response.body().string());
}
} catch (Exception e) {
Logger.e(e.toString());
}
return false;
}
}

LoginActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
* 发送短信验证码
* params : mobilePhoneNumber
*/
private class SendCodeTask extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
//ttl后面的值是短信有效时间(分钟)
String json = "{\"mobilePhoneNumber\":\"{0}\",\"ttl\":10,\"name\":\"注册\"}";
json = json.replace("{0}", phone);
return okHttpUtil.postJson("https://api.leancloud.cn/1.1/requestSmsCode", json);
}

@Override
protected void onPostExecute(Boolean s) {
super.onPostExecute(s);
if (s) {
Toast.makeText(LoginActivity.this,"验证码发送成功",Toast.LENGTH_SHORT).show();
} else Toast.makeText(LoginActivity.this, "验证码发送失败",Toast.LENGTH_SHORT).show();
}
}

/**
* 验证短信验证码
* params : mobilePhoneNumber , smsCode
*/
private class VerifySmsCode extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
String json = "{\"mobilePhoneNumber\":\"{0}\"}";
json = json.replace("{0}", params[0]);
return okHttpUtil.postJson("https://api.leancloud.cn/1.1/verifySmsCode/" + params[1], json);
}

@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if {
//do something
}
else Toast.makeText(LoginActivity.this, "验证码不匹配",Toast.LENGTH_SHORT).show();
}
}

总结

自己动手,丰衣足食啊。

顺便吐槽下:国内的很多第三方 SDK 封装的时候,基本上没怎么考虑使用者项目中已经使用了什么类库。对于大部分常见的类库(图片加载库,网络请求库等)进行进一步的抽象,可以大大减少开发者的负担。

如果你不明白我的意思,可以看看 GalleryFinal 这个开源图片选择器对于图片加载库的封装,使得它可以适应多种图片加载库而不需要你修改项目中已有的图片库。

如果你有更好的或者其他想法,欢迎和我交流。

PS:你可以通过下面的方式和我联系