请选择 进入手机版 | 继续访问电脑版

石家庄老站长

点击联系客服
客服QQ:509006671 客服微信:mengfeiseo
 找回密码
 立即注册
查看: 20|回复: 0

Flutter学习15天:2021年最新版超详细Flutter实现Mob SMSSDK手机验证码登录实现 Android和Flutter混合开发?

[复制链接]

1

主题

1

帖子

-7

积分

限制会员

积分
-7
发表于 2021-4-3 14:36:36 | 显示全部楼层 |阅读模式
Flutter实现手机验证码登录

第一步:在mob平台上配置SMSSDK环境第二步:为flutter项目和Android创建library文件第三步:在Android的library文件中部署mob  SMSSDK环境1。添加到project的build.gradle文件将权限添加到RoidMainfest.xml文件步骤4:在flutter的Android文件中配置环境1。将Android端库导入版本2.flutter的Android文件并配置mob环境第5步:实现flutter验证码功能tter端MethodChannel3。在Android端,配置发送验证码和确认验证码所需的方法。4 .在Android端配置method通道。5 .最后,注册插件以进行数据通信

实现该功能的灵感来源于flutter实现百度语音转换文字功能的这个博客,我以前以为Android是如何实现手机号码登录的博客,因为这个博客主要针对Android端的实现,所以我们可以通过flutter和Android相互通信,Flutter也可以实现手机验证码登录的效果。(大卫亚设,Northern  Exposure(美国电视剧),Northern  Exposure  

)

废话少说吧。我们先看看效果由于个人信息保护问题,将手柄号码设置为密码类型,但不影响效果。





白城汽车也很好,但首先这个平台的每个账户每天只能发送10次验证码,所以请首先声明。(大卫亚设,北方执行部队)。

因此,建议直接注册该平台,并创建应用程序密钥和应用程序脚本,以获得验证码登录功能。关于如何注册这个平台应用程序,可以查看我的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 StateMyApp> {
  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 FutureString> telephone(String phone) async{
    return await _channel.invokeMethod('telephone',phone);
  }
  static Futuredynamic> 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","提交验证码正确");
                                MapString, 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","验证码已发送");
                                MapString, 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();
                                    MapString, 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端的一段代码。

MapString, 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,发送你的电子邮箱或者私聊等方法都可以。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|无图版|手机版|小黑屋|石家庄@IT精英团

GMT+8, 2021-5-10 14:58 , Processed in 0.100317 second(s), 25 queries .

Powered by Discuz! X3.4

© 2001-2021 Comsenz Inc.

快速回复 返回顶部 返回列表