Flutter插件开发-SMS

前言

flutter是一个跨平台UI框架,但是在跨平台上需要与Android和iOS进行各种交互, 比如短信验证就是其中, 就昂封装Android和iOS SDK为flutter所用

创建

使用flutter命令行工具快速创建 plugin 模板:

1
2
flutter create --template=plugin flutter_mod_sms_plugin
flutter create --org com.xyxj.flutter --plugin -i swift -a kotlin flutter_mod_sms_plugin

命令行启动模拟器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ avdmanager.bat -h

Usage:
avdmanager [global options] [action] [action options]
Global options:
-s --silent : Silent mode, shows errors only.
-v --verbose : Verbose mode, shows errors, warnings and all messages.
--clear-cache: Clear the SDK Manager repository manifest cache.
-h --help : Help on a specific command.

Valid actions are composed of a verb and an optional direct object:
- list : Lists existing targets or virtual devices.
- list avd : Lists existing Android Virtual Devices.
- list target : Lists existing targets.
- list device : Lists existing devices.
- create avd : Creates a new Android Virtual Device.
- move avd : Moves or renames an Android Virtual Device.
- delete avd : Deletes an Android Virtual Device.

失败:

1
Android Emulator Error Message: “PANIC: Missing emulator engine program for 'x86' CPUS.”

解决方案:

1
2
3
4
//启动cmd 1. mklink
mklink emulator64-x86 emulator-x86 //如果存在就不用了
//启动sdk/emulator的命令不是tools下的命令
emulator -avd 模拟器名字

分析结构

新创建插件项目:

  • android
  • ios
  • lib
  • example
  • pubspec.yaml

可以看出比正常的项目多了个example, 这个可以当做测试用.进入example可以看到,其实这也是个flutter项目,注意几点:

  • 这是一个可以运行的项目 ==> flutter run
  • 调用方式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 首先是异步初始化
Future<void> initPlatformState() async {
String platformVersion;
try {
platformVersion = await FlutterModSms.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}

// 如果widget被移除,就直接返回
if (!mounted) return;

// 更新UI状态
setState(() {
_platformVersion = platformVersion;
});
}

插件中的类和方法(路径 = > ../lib/flutter_mod_sms.dart):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import 'dart:async';

import 'package:flutter/services.dart';

class FlutterModSms {
// 就记作调用管道
static const MethodChannel _channel =
const MethodChannel('flutter_mod_sms');

// 反射到平台的方法 'getPlatformVersion' 不能为空 支持标准message和JSON message
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
}

MethodChannel:

  • 异步方法回调
  • 二进制传输 通过MethodCodec
  • 必须能有独一的方法name而且不能为空

平台对应的代码实现:

  • Android
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/** FlutterModSmsPlugin */
public class FlutterModSmsPlugin implements MethodCallHandler {
/** 插件注册 */
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_mod_sms");
channel.setMethodCallHandler(new FlutterModSmsPlugin());
}

@Override
public void onMethodCall(MethodCall call, Result result) {
// dart中反射的方法
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
}
  • iOS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#import "FlutterModSmsPlugin.h"

@implementation FlutterModSmsPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"flutter_mod_sms"
binaryMessenger:[registrar messenger]];
FlutterModSmsPlugin* instance = [[FlutterModSmsPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@"getPlatformVersion" isEqualToString:call.method]) {
result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
} else {
result(FlutterMethodNotImplemented);
}
}

@end

改造

过程已经清楚了, 进行改造.

Android端配置:点击

Android Studio打开android项目 配置 build.gradle

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
group 'com.example.fluttermodsms'
version '1.0-SNAPSHOT'

buildscript {
repositories {
google()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.mob.sdk:MobSDK:+'
}
}

rootProject.allprojects {
repositories {
google()
jcenter()
}
}

apply plugin: 'com.android.library'

// 添加插件
apply plugin: 'com.mob.sdk'

// 在MobSDK的扩展中注册SMSSDK的相关信息
MobSDK {
appKey "2a30d2996fce1"
appSecret "8221c3c04a935f7a18a66ba451690789"

SMSSDK {}
}

android {
compileSdkVersion 27

defaultConfig {
minSdkVersion 16
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'armeabi-v7a'
//'armeabi',
//'arm64-v8a',
//'x86', 'x86_64'
}
}
lintOptions {
disable 'InvalidPackage'
}

repositories {
flatDir {
dirs 'libs'
}
}

sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}

dependencies {
//compile fileTree(include: ['*.jar'], dir: 'libs')
compileOnly files('libs/flutter.jar')
}
}

有些可能不用需要自行去掉

Donate comment here