由于我不会做IOS开发,文章里面没有IOS的代码。下面的参考教程里有具体的IOS代码
参考教程:flutter中文网–Flutter实战–插件开发,平台介绍和实现Android端API
最后的执行效果如下:
平台通道
平台指的是flutter运行的平台,如Android或者ios,可以认为就是应用的原生部分,所以,平台通道正是Flutter和原生之间通信的桥梁,它也是Flutter插件的底层基础设施。
Flutter使用了一个灵活的系统,允许调用特定平台的API,无论在Android上的Java或者Kotlin代码中,还是在IOS上的OC或者swift代码中均可用。
Flutter与原生之间的通信依赖灵活的消息传递方式:
- 应用的Flutter部分通过平台通道(platform channel)将消息发送到其应用程序所在的宿主(IOS或者Android)应用(原生应用)
- 宿主监听平台通道,并接受该消息,然后它会调用该平台的API,并将响应发送回客户端,即应用程序的Flutter部分。
使用平台通道在Flutter(client)和原生(host)之间传递消息,如下图所示:
当在Flutter中调用原生方法时,调用信息通过平台通道传递到原生,原生收到调用信息后可以执行指定的操作,如果需要返回数据,则原生会将数据再通过平台通道传递给Flutter,需要注意的是消息的传递是异步的,这确保了用户界面再消息传递时不会被挂起。
在客户端,MethodChannel API可以发送与方法调用相对应的消息,在宿主平台上,MethodChannel在Android API和FlutterMethodChannel IOS API可以接收方法调用并返回结果,这些类可以帮助我们用很少的代码就能开发平台插件。
如果需要,方法调用(消息传递)可以是反向的,即宿主作为客户端调用Dart中实现的API,quick_actions
插件就可以这么做。
开发Flutter插件
使用平台通道调用原生代码
下面是一个获取电池电量的插件,该插件在Dart中通过getBatteryLevel
调用Android BatteryManager
API和IOS的相关API。
Flutter中的代码如下:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
/**
* 插件开发--获取宿主平台的电量信息
*/
class BetteryInfoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"插件开发--获取电量",
style: TextStyle(
color: Colors.greenAccent,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
elevation: 0.0,
backgroundColor: Colors.lime,
),
body: BetteryInfoRoute(),
);
}
}
class BetteryInfoRoute extends StatefulWidget {
@override
_BetteryInfoRouteState createState() {
return _BetteryInfoRouteState();
}
}
class _BetteryInfoRouteState extends State with SingleTickerProviderStateMixin {
static const platform = const MethodChannel("samples.flutter.io/battery");
//默认电量100%
double _currentBetteryInfo = 100;
//当前的文字颜色,根据不同的电量改变
Color _betteryColor = Colors.greenAccent;
//动画控制器
AnimationController _animationController;
//动画
Animation _animation;
//显示当前获取电量的状态信息
String _currentState = "正在获取信息";
@override
void initState() {
// TODO: implement initState
super.initState();
setBatteryColor();
getValueColorAnimation();
_getBatteryLevel();
}
@override
Widget build(BuildContext context) {
//一个圆形进度条中间显示电量的百分比
return Center(
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
constraints: BoxConstraints.expand(width: 120.0, height: 120.0),
child: CircularProgressIndicator(
backgroundColor: Colors.redAccent,
valueColor: _animation,
value: _currentBetteryInfo / 100,
),
),
Padding(
padding: EdgeInsets.all(10.0),
child: Text(
_currentState,
style: TextStyle(
color: _betteryColor,
),
),
),
],
),
);
}
//设置动画
void getValueColorAnimation() {
if (_animationController == null) {
_animationController =
AnimationController(duration: Duration(seconds: 5), vsync: this);
}
_animation =
CurvedAnimation(parent: _animationController, curve: Curves.ease);
_animation = Tween(begin: _betteryColor, end: Colors.greenAccent)
.animate(_animation);
}
//设置不同电量的颜色
void setBatteryColor() {
if (_currentBetteryInfo > 80) {
_betteryColor = Colors.greenAccent;
} else if (_currentBetteryInfo > 50) {
_betteryColor = Colors.orangeAccent;
} else {
_betteryColor = Colors.redAccent;
}
}
//获取电量
Future<Null> _getBatteryLevel() async {
try {
_currentBetteryInfo = await platform.invokeMethod("getBatteryLevel");
_currentState = "${_currentBetteryInfo.toString()}%";
} on PlatformException catch (e) {
//出现异常
_currentState = "failed";
} finally {
//最终都会执行刷新操作
setState(() {
setBatteryColor();
getValueColorAnimation();
});
}
}
}
//Android中的代码如下:
package com.example.basicwidgetdemo1;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "samples.flutter.io/battery";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if(methodCall.method.equals("getBatteryLevel")){
double batteryLevel = getBatteryLevel();
if(batteryLevel != -1){
result.success(batteryLevel);
}else{
result.error("UNAVAILABLE","Battery level not available",null);
}
}else{
result.notImplemented();
}
}
}
);
}
//获取手机剩余电量
private double getBatteryLevel(){
double battery = -1;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
BatteryManager manager = (BatteryManager) getSystemService(BATTERY_SERVICE);
battery = manager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
}else{
Intent intent = new ContextWrapper(getApplicationContext()).registerReceiver(null,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
battery = intent.getIntExtra(BatteryManager.EXTRA_LEVEL,-1) / intent.getIntExtra(BatteryManager.EXTRA_SCALE,-1);
}
return battery;
}
}