Flutter實作手機驗證碼登錄
- 第一步:在mob平臺配置SMSSDK環境
- 第二步:建立flutter專案和android的library檔案
- 第三步:在Android的library檔案中部署mob+SMSSDK環境
- 1.在project的build.gradle檔案中加入如下代碼
- 2.在你建立的library中加入如下代碼
- 3.在你的AndroidMainfest.xml檔案中加入權限
- 第四步:在flutter的Android檔案中配置環境
- 1.修改版本
- 2.flutter的Android檔案中匯入android端的library和配置mob環境
- 第五步:實作flutter驗證碼功能
- 1.在flutter端首先UI設計(view層)
- 2.配置flutter端的MethodChannel
- 3.在Android端配置實作發送驗證碼和驗證驗證碼需要的方法
- 4.在Android端配置MethodChannel
- 5.最后注冊plugin,實作資料通信
關于這個功能實作的靈感來自于Flutter實作百度語音轉文字功能這篇博客,以為我以前出過一篇android怎么實作手機號登錄的博客,這篇博客主要是針對Android端的實作,所以我們可以通過flutter和Android實作相互通信,從而達到flutter也可以實作手機驗證碼登錄的效果,
廢話少說,我們先看一下效果,因為個人隱私問題,我把手機號碼設定為了密碼型別,但是不影響效果:

雖然白嫖固然好,但是首先宣告一下,因為這個平臺的每個賬號,一天只能發送10次驗證碼,
所以我建議你自己去注冊這個平臺,建立一個賬號來獲取驗證碼登錄功能的App Key和App Secret,關于如何注冊這個平臺應用,你可以去看一下我的Android實作手機驗證碼登錄這篇博客,說的挺詳細的,大概從開始看到下圖紅色圓圈處就可以了,

第一步:在mob平臺配置SMSSDK環境
因為下面那篇博客已經說的很清楚了,所以我就不在做詳細說明,
關于如何注冊這個平臺應用,你可以去看一下我的Android實作手機驗證碼登錄:https://blog.csdn.net/qq_45137584/article/details/111414308
這篇博客,說的挺詳細的,大概從開始看到下圖紅色圓圈處就可以了,

第二步:建立flutter專案和android的library檔案
關于這個步驟因為我以前的博客有說過,就不在進行說明了,可以看一下我的Flutter實作百度語音轉文字功能,從開頭看到下圖紅色圓圈處部分就可以了,

記得仔細閱讀每一步,如果你缺少了一步,可以就會導致你的功能無法實作,
下面的文字是補充,可以不需要看,
看一下我們建立的專案結構吧,關于Android端那里爆紅是因為我這個是flutter的專案,沒有Android端相關的jar檔案,只需要我們把那個爆紅的檔案,用Android studio打開即可,


下面就我們通過Android studio打開的檔案,然后我們在他里面建立的Android的library的檔案,名字是mob_plugin,

第三步:在Android的library檔案中部署mob+SMSSDK環境
1.在project的build.gradle檔案中加入如下代碼

代碼如下:
classpath "com.mob.sdk:MobSDK:2018.0319.1724"
maven { url 'https://jitpack.io' }
2.在你建立的library中加入如下代碼



代碼如下:
配置mob環境的代碼:
id 'com.mob.sdk'
建議修改為自己的appKey和appSecret
MobSDK {
appKey "31d18b327d099" //修改為你自己的appKey
appSecret "5e6a2e16f58f9c1e374acf77abb70b70" //修改為你自己的appSecret
SMSSDK {}
}
配置flutter的環境:因為我在與flutter端通信的時候需要用到flutter的庫,所以需要配置flutter的環境,
代碼如下:
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
flutter {
source '../..'
}
3.在你的AndroidMainfest.xml檔案中加入權限

代碼如下:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
第四步:在flutter的Android檔案中配置環境
1.修改版本
首先把build.gradle(Module:app)檔案中圖中紅色圓圈處改為與build.gradle(Module:mob_plugin)檔案中版本相同

2.flutter的Android檔案中匯入android端的library和配置mob環境
配置mob環境:

代碼如下:
配置mob環境
apply plugin: 'com.mob.sdk'
匯入library庫
mob_plugin改為你自己的library庫名即可
implementation project(':mob_plugin')
第五步:實作flutter驗證碼功能
1.在flutter端首先UI設計(view層)
這個頁面的實作對于學過flutter的人來說比較簡單,畢竟我們主要是用于測驗功能,所以沒必要做的過于復雜,主要就兩個輸入框和兩個按鈕,
這里我就說一下主要的一個部分吧,代碼如下
///這個方法主要是把你輸入的手機號碼傳輸過去
ArsManager.telephone(myController.text);
///這個方法主要是把你輸入的手機號碼和驗證碼存入Map里面,然后傳輸過去,
Map ages={};
ages['phone']=myController.text;
ages['code']=myController1.text;
ArsManager.correct(ages).then((result){
int code = result["code"];
String message = result["message"];
if(message=="提交驗證碼正確") {
Navigator.of(context).push( MaterialPageRoute(builder: (context)=>Login()));
}else{
print(message);
}
});
main.dart頁面
import 'package:flutter/material.dart';
import 'package:mob_app/asr_manger.dart';
import 'package:mob_app/login.dart';
void main() {
runApp(MaterialApp(
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final myController = TextEditingController();
final myController1=TextEditingController();
@override
void dispose() {
// TODO: implement dispose
myController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: myController,
obscureText: true,
decoration: InputDecoration(
labelText: "請輸入手機號碼",
hintText: "請輸入手機號碼",
prefixIcon: Icon(Icons.people_alt_rounded)),
),
),
Container(
height: 40,
child:OutlineButton(
borderSide:new BorderSide(color: Theme.of(context).primaryColor),
child: new Text('獲取驗證碼',style: new TextStyle(color: Theme.of(context).primaryColor),),
onPressed: (){
_data();
},
),
),
Padding(
padding: const EdgeInsets.all(4.0),
child: TextField(
controller: myController1,
decoration: InputDecoration(
labelText: "請輸入驗證碼",
prefixIcon: Icon(Icons.lock),
hintText: "請輸入驗證碼",
),
),
),
Container(
height: 40,
child:OutlineButton(
borderSide:new BorderSide(color: Theme.of(context).primaryColor),
child: new Text('登錄',style: new TextStyle(color: Theme.of(context).primaryColor),),
onPressed: (){
_login();
},
),
),
],
),
);
}
_data() {
setState(() {
ArsManager.telephone(myController.text);
});
}
_login() {
setState(() {
Map ages={};
ages['phone']=myController.text;
ages['code']=myController1.text;
ArsManager.correct(ages).then((result){
int code = result["code"];
String message = result["message"];
if(message=="提交驗證碼正確") {
Navigator.of(context).push( MaterialPageRoute(builder: (context)=>Login()));
}else{
print(message);
}
});
});
}
}
這個頁面用于我們驗證碼驗證成功的時候跳轉頁面,
login.dart頁面:
import 'package:flutter/material.dart';
class Login extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('登錄成功',style: TextStyle(decoration: TextDecoration.none,fontSize: 20,color:Color(0xFFFFFFFF)),),
);
}
}
2.配置flutter端的MethodChannel
這里我們主要設定了兩個方法:
telephone方法:把手機號碼傳輸給Android端,然后發送驗證碼的方法,
傳送的值是String型別,回傳的值也是String型別
correct方法:把手機號碼和你輸入的驗證碼傳輸給Android端,然后實作驗證驗證碼輸入是否正確,
傳送的值是Map型別,回傳的值是dynamic型別
如果對于那個基礎型別不是很懂,可以去看一下我的這篇文章dart的基礎型別,
代碼如下:
import 'dart:async';
import 'package:flutter/services.dart';
class ArsManager{
static const MethodChannel _channel=const MethodChannel('asr_plugin');
static Future<String> telephone(String phone) async{
return await _channel.invokeMethod('telephone',phone);
}
static Future<dynamic> correct(Map map) async{
return await _channel.invokeMethod('correct',map);
}
}
3.在Android端配置實作發送驗證碼和驗證驗證碼需要的方法
主要使用到三個方法:
send方法:輸入值是phone;主要功能就是通過手機號碼獲取驗證碼
submit方法:主要輸入值是phone,code;主要功能就是通過手機號碼和輸入的驗證碼來驗證驗證碼是否輸入正確,
verification方法:主要輸入值是message;主要功能就是回呼驗證碼的輸入是否正確,然后把結果發送給flutter端,
package com.example.mob_plugin;
import android.app.Activity;
import android.text.TextUtils;
import android.util.Log;
import com.mob.MobSDK;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import cn.smssdk.EventHandler;
import cn.smssdk.SMSSDK;
import io.flutter.plugin.common.MethodChannel;
class ArsManger extends Activity {
EventHandler handler;
boolean f1=false;
public void submit(String phone, String code, Activity activity, MethodChannel.Result result) {
SMSSDK.submitVerificationCode("86",phone,code);
verification(activity,result);
}
//點擊發送驗證碼
public void send(String phone) {
//獲取驗證碼
SMSSDK.getVerificationCode("86",phone);
}
public void verification(Activity activity,MethodChannel.Result message){
MobSDK.init(activity, "31d18b327d099","5e6a2e16f58f9c1e374acf77abb70b70");
handler = new EventHandler(){
@Override
public void afterEvent(int event, int result, Object data) {
if (result == SMSSDK.RESULT_COMPLETE){
//回呼完成
if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {
//提交驗證碼成功
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("123","提交驗證碼正確");
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "提交驗證碼正確");
resultMap.put("code", 200);
//發訊息至 Flutter
//此方法只能使用一次
message.success(resultMap);
}
});
}else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE){
//獲取驗證碼成功
runOnUiThread(new Runnable() {
@Override
public void run() {
// Toast.makeText(MainActivity.this,"驗證碼已發送", Toast.LENGTH_SHORT).show();
Log.e("123","驗證碼已發送");
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "驗證碼已發送");
resultMap.put("code", 200);
//發訊息至 Flutter
//此方法只能使用一次
message.success(resultMap);
}
});
}else if (event == SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES){
}
}else{
((Throwable)data).printStackTrace();
Throwable throwable = (Throwable) data;
try {
JSONObject obj = new JSONObject(throwable.getMessage());
final String des = obj.optString("detail");
if (!TextUtils.isEmpty(des)){
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("123","提交錯誤資訊");
// Toast.makeText(MainActivity.this,"提交錯誤資訊", Toast.LENGTH_SHORT).show();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "提交錯誤資訊");
resultMap.put("code", 200);
//發訊息至 Flutter
//此方法只能使用一次
message.success(resultMap);
}
});
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
};
SMSSDK.registerEventHandler(handler);
}
}
說一下上面代碼中的一段代碼:
代碼如下:
主要用于把我們verification方法的回呼結果回傳給flutter,這里屬于Android發送給flutter端的一段代碼,
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "驗證碼正確");
resultMap.put("code", 200);
//發訊息至 Flutter
//此方法只能使用一次
message.success(resultMap);
4.在Android端配置MethodChannel
主要使用的兩個方法:
registerWith方法:等下會用到,主要用于注冊plugin,實作通信功能,
onMethodCall方法:這個方法是我們繼承MethodChannel.MethodCallHandler類來使用的方法,主要是功能是接受來自flutter發送過來的資料,
package com.example.mob_plugin;
import android.app.Activity;
import androidx.annotation.NonNull;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class AsrPlugin implements MethodChannel.MethodCallHandler {
private final Activity activity;
ArsManger arsManger=new ArsManger();
public static void registerWith(Activity activity, BinaryMessenger messenger) {
MethodChannel channel = new MethodChannel(messenger, "asr_plugin");
AsrPlugin instance = new AsrPlugin(activity);
channel.setMethodCallHandler(instance);
}
public AsrPlugin(Activity activity) {
this.activity = activity;
}
@Override
public void onMethodCall(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
switch (methodCall.method) {
case "telephone":
arsManger.send(methodCall.arguments.toString());
break;
case "correct":
arsManger.submit(methodCall.argument("phone"),methodCall.argument("code"),activity,result);
break;
default:
result.notImplemented();
}
}
}
5.最后注冊plugin,實作資料通信

代碼如下:
package com.example.mob_app;
import android.os.Bundle;
import androidx.annotation.NonNull;
import com.example.mob_plugin.AsrPlugin;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
//flutter sdk >= v1.17.0 時使用下面方法注冊自定義plugin
AsrPlugin.registerWith(this, flutterEngine.getDartExecutor().getBinaryMessenger());
}
@Override
protected void onCreate(Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
}
}
程序還是比較多的,其實全部代碼都已經寫出來,如果你覺得結構不夠明了,可以找我要這個demo,發送你的電子郵箱或者私聊等方法都可以,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/272011.html
標籤:其他
上一篇:ADB釘釘打卡
下一篇:MVP使用以及簡介
