easylink_flutter 0.9.2

  • Readme
  • Changelog
  • Example
  • Installing
  • new48

EasylinkFlutter

EasylinkFlutter #

对基于 MXCHIP/MXOS 的 IoT WiFi 硬件模组进行无线网络设置的发送工作的 Flutter 插件。

使用方法 #

  1. 引入本插件。
  • 修改 pubspec.yaml 文件,在 dependencies: 里面加入:
  easylink_flutter:
    git:
      url: https://github.com/kagurazakayashi/EasylinkFlutter.git
  1. 向用户索取「位置服务」权限(在 iOS > 12 或 Android > 8 时)。
  • 要获得当前 SSID ,「位置服务」权限是必须的。
  • 如果让用户自己输入网络名,可以跳过本步骤和下一步骤。
  • 示例程序中使用的权限获取插件是 permission_handler
  1. 获取 SSID 。
  • 调用 EasylinkFlutter.getwifiinfo() ,可以获得一个包含各种信息的字典。
  • 该字典(Map)通常包括三个字符串数据 [BSSID,SSID,SSIDDATA]
  • 下面是一个示例:
  Future<void> getssid() async {
    try {
      Map wifiinfo = await EasylinkFlutter.getwifiinfo();
      print(wifiinfo["SSID"]);
    } on PlatformException {
      print("ERROR");
    }
  }
  1. 开始配网。
  • 调用 EasylinkFlutter.linkstart ,该方法需要以下参数:
    • ssid: Wi-Fi 网络名
    • password: Wi-Fi 网络密码
    • mode: EasyLink 的模式,可选项:
      • EASYLINK_V1,EASYLINK_V2,EASYLINK_PLUS,EASYLINK_V2_PLUS,EASYLINK_AWS,EASYLINK_SOFT_AP,EASYLINK_MODE_MAX
      • 示例使用的是 EasyLinkMode.EASYLINK_V2_PLUS,安卓只支持此项(此项包括V1和V2)。
    • timeout: 超时时间
  • 方法会返回一个字符串状态信息。
  • 下面是一个示例:
  await EasylinkFlutter.linkstart(
    ssid: "testwifi",
    password: "testpwd",
    mode: EasyLinkMode.EASYLINK_V2_PLUS,
    timeout: 60
  );
  1. 监听返回通知
  • 使用 EasyLinkNotification.instance.addObserver('linkstate', (object) 来监听通知。
  • objectString 类型,可以返回以下内容:
    • Start: 开始执行
    • Stop: 执行结束、终止、超时
    • Unknown: 状态未知
    • 其他 String: 错误信息
    • JSON: 成功,插件将设备返回的详细信息解析整理为 JSON 返回,内容为字符串字典类型。
  • 下面是一个示例:
  try {
    EasyLinkNotification.instance.addObserver('linkstate', (object) {
      setState(() {
        String cbstr = object;
        if (cbstr != "Stop" && cbstr != "Unknown") {
          EasylinkFlutter.linkstop();
        }
        if (cbstr.substring(0,1) == "{") { //是 JSON
          _jsoninfo = object;
          _displayinfo = "OK!";
        } else {
          _displayinfo = object;
        }
      });
      EasyLinkNotification.instance.removeNotification('linkstate');
    });
  } on PlatformException {
    displayinfo = 'ERROR!';
  }

注意事项 #

  1. Android 版加入插件前,需要修改 android\app\src\main\AndroidManifest.xml 文件:
  • <manifest> 节点添加 xmlns:tools="http://schemas.android.com/tools"
  • <application> 节点添加 tools:replace="android:label"
  1. 在 iOS > 12 或 Android > 8 时,要获取 WiFi 网络名称必须先拥有「位置服务」权限。

支持版本 #

  • EASYLINK_V2
  • EASYLINK_V3
  • EASYLINK_PLUS

不支持 EasylinkP2P

截图(找到设备并返回由设备提供的信息) #

Android:

Android

iOS:

iOS

0.9.2 2020.7.5 #

  • 改进Android超时计时器,增强释放
  • 优化示例程序的体验

0.9.1 2020.7.1 #

  • 停止前自动判断运行状态

0.9.0 2020.7.1 #

  • Android处理超时和后台结束事件

0.8.2 2020.6.30 #

  • 更新图标、协议

0.8.1 2020.6.30 #

  • 获取ssid逻辑修改

0.8.0 2020.6.30 #

  • iOS和Android返回统一的信息和json格式

0.7.0 2020.6.29 #

  • 修复判断权限是否获取成功时的问题

0.6.0 2020.4.2 #

  • 修复 EasyServer 导致崩溃的问题

0.5.0 2020.4.1 #

  • 修复Android版启动画面

0.4.1 2020.5.30 #

  • Android手动停止时触发invokeMethod

0.4.0 2020.5.30 #

  • 删除日志输出,修改权限要求

0.3.2 2020.3.22 #

  • 增加停止按钮

0.3.1 2020.3.21 #

  • Android-Java端代码

0.3.0 2020.3.20 #

  • Android端支持准备工作

0.2.1 2020.2.13 #

  • 配网成功时可以返回详细信息(原始数据)

0.2.0 2020.2.12 #

  • Flutter插件代码和简单示例

0.1.0 2020.2.11 #

  • iOS-OC端代码

0.0.1 2020.2.10 #

  • Initial commit

example/lib/main.dart

// 示例程序
import 'dart:io';
import 'dart:ui';

import 'package:flutter/material.dart';
// ignore: directives_ordering
import 'dart:async';

import 'package:connectivity/connectivity.dart';
import 'package:flutter/services.dart';
import 'package:easylink_flutter/easylink_flutter.dart';
import 'package:easylink_flutter/easylink_notification.dart';
import 'package:permission_handler/permission_handler.dart';

void main() => runApp(MyApp());

class PersonData {
  String name = '';
  String password = '';
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  String _displayinfo = 'Unknown';
  String _jsoninfo = '';
  String _btntext = '▶️ START';
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  TextEditingController ssidController = TextEditingController();
  TextEditingController pwController = TextEditingController();
  PersonData person = PersonData();
  bool _autovalidate = false;
  bool isstartlink = false;
  String tag = '[EasyLinkFlutter Example APP] ';
  int getrepnum = 0;

  @override
  void initState() {
    getssid();
    getConnectivity();
    ssidController.text = '';
    pwController.text = '';
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.inactive: // 处于这种状态的应用程序应该假设它们可能在任何时候暂停。
        // print('处于这种状态的应用程序应该假设它们可能在任何时候暂停。');
        break;
      case AppLifecycleState.resumed: // 应用程序可见,前台
        // print('应用程序可见,前台');
        break;
      case AppLifecycleState.paused: // 应用程序不可见,后台
        // print('应用程序不可见,后台');
        // ignore: always_put_control_body_on_new_line
        if (isstartlink) stopbtn();
        break;
      case AppLifecycleState.detached:
        // print('detached');
        break;
    }
  }

  @override
  void dispose() {
    super.dispose();
    ssidController.clear();
    pwController.clear();
    EasylinkFlutter.linkstop();
  }

  // ignore: always_declare_return_types
  getConnectivity() async {
    // ignore: unnecessary_parenthesis
    final ConnectivityResult connectivityResult = await (Connectivity().checkConnectivity());
    if (connectivityResult != ConnectivityResult.wifi) {
      print('没开WiFi');
    }
  }

//获取权限
  // ignore: always_declare_return_types
  requestPermission(Permission rep) async {
    print('申请权限');
    await rep.request();
    checkPermission(rep);
    getrepnum++;
  }

  // ignore: always_declare_return_types
  checkPermission(Permission rep) async {
    // PermissionStatus permission =
    // await PermissionHandler().checkPermissionStatus(rep);
    // Scaffold.of(context).showSnackBar(SnackBar(
    //   content: Text((await rep.status).toString()),
    // ));
    if (await rep.status.isGranted) {
      print('权限申请通过');
      // 以下两种方式都能获取SSID
      getConnectivity();
      getssid();
    } else {
      print('权限申请被拒绝');
      if (getrepnum < 1) {
        requestPermission(rep);
      }
    }
  }

  Future<void> getssid() async {
    try {
      // ignore: always_specify_types
      final Map wifiinfo = await EasylinkFlutter.getwifiinfo();
      print(tag + '插件返回信息:');
      print(wifiinfo);
      //wifiinfo: BSSID,SSID,SSIDDATA
      if (wifiinfo.isEmpty) {
        checkPermission(Permission.locationWhenInUse);
      } else {
        ssidController.text = wifiinfo['SSID'] as String;
      }
    } on PlatformException {
      //ssidController.text  = '';
    }
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> linkstart() async {
    String displayinfo;
    // Platform messages may fail, so we use a try/catch PlatformException.
    setState(() {
      _displayinfo = 'Searching...';
    });

    try {
      displayinfo = await EasylinkFlutter.linkstart(
          ssid: person.name,
          password: person.password,
          mode: EasyLinkMode.EASYLINK_V2_PLUS,
          timeout: 60);
    } on PlatformException {
      displayinfo = 'ERROR ID 1';
    }
    try {
      // ignore: always_specify_types
      EasyLinkNotification.instance.addObserver('linkstate', (object) {
        setState(() {
          final String cbstr = object as String;
          if (cbstr != 'Stop' && cbstr != 'Unknown') {
            EasylinkFlutter.linkstop();
          }
          if (cbstr.substring(0, 1) == '{') {
            _jsoninfo = object as String;
            _displayinfo = 'OK';
          } else {
            _displayinfo = object as String;
          }
          isstartlink = false;
          _btntext = '▶️ START';
        });
        EasyLinkNotification.instance.removeNotification('linkstate');
      });
    } on PlatformException {
      displayinfo = 'ERROR! ID 2';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    // ignore: always_put_control_body_on_new_line
    if (!mounted) return;

    setState(() {
      _displayinfo = displayinfo;
    });
  }

  String _validateName(String value) {
    // ignore: always_put_control_body_on_new_line
    if (value.isEmpty) return '用户名不能为空.';
    // final RegExp nameExp = RegExp(r'^[0-9a-zA-Z]+$');
    // if (!nameExp.hasMatch(value)) return '只能输入字母和数字.';
    return null;
  }

  String _validatePassWord(String value) {
    // ignore: always_put_control_body_on_new_line
    if (value.isEmpty) return '密码不能为空.';
    return null;
  }

  void startbtn() {
    // checkPermission();
    final FormState form = _formKey.currentState;
    if (!form.validate()) {
      _autovalidate = true; // 开始验证每个更改.
      print(tag + '表单输入不正确');
    } else {
      form.save();
      if (!isstartlink) {
        isstartlink = true;
        _btntext = '⏹ STOP';
        _jsoninfo = '';
        linkstart();
      }
    }
  }

  void startorstopbtn() {
    if (isstartlink) {
      stopbtn();
    } else {
      startbtn();
    }
  }

  Future<void> slbtn() async {
    await EasylinkFlutter.ls();
  }

  void stopbtn() {
    isstartlink = false;
    _btntext = '▶️ START';
    EasylinkFlutter.linkstop();
    _displayinfo = 'Stopped.';
  }

  @override
  Widget build(BuildContext context) {
    final MediaQueryData mqdwindow = MediaQueryData.fromWindow(window);
    final double windowWidth = mqdwindow.size.width;
    return MaterialApp(
      home: WillPopScope(
        onWillPop: () async {
          // ignore: always_put_control_body_on_new_line
          if (isstartlink) stopbtn();
          // ignore: always_specify_types
          return Future.value(true);
        },
        child: Scaffold(
          appBar: AppBar(
            leading: Image.asset('images/icon.png'),
            title: Text(_displayinfo),
          ),
          body: Form(
            key: _formKey,
            autovalidate: _autovalidate,
            child: SingleChildScrollView(
              child: Column(
                children: <Widget>[
                  TextFormField(
                    // initialValue: person.name,
                    textCapitalization: TextCapitalization.words,
                    // style: TextStyle(color: Colors.white),
                    decoration: const InputDecoration(
                      border: UnderlineInputBorder(),
                      filled: true,
                      icon: Icon(
                        Icons.wifi,
                        // color: Colors.white,
                      ),
                      hintText: 'WiFi SSID',
                      // hintStyle: TextStyle(color: Colors.white54),
                      labelText: 'WiFi SSID',
                      // labelStyle: TextStyle(color: Colors.white54),
                      // fillColor: Colors.white,
                    ),
                    onSaved: (String value) {
                      person.name = value;
                    },
                    validator: _validateName,
                    controller: ssidController,
                  ),
                  const SizedBox(height: 24.0),
                  TextFormField(
                    decoration: const InputDecoration(
                      border: UnderlineInputBorder(),
                      filled: true,
                      icon: Icon(
                        Icons.vpn_key,
                        // color: Colors.white,
                      ),
                      hintText: 'WiFi Password',
                      // hintStyle: TextStyle(color: Colors.white54),
                      labelText: 'WiFi Password',
                      // labelStyle: TextStyle(color: Colors.white54),
                      // fillColor: Colors.white,
                    ),
                    validator: _validatePassWord,
                    onSaved: (String value) {
                      setState(() {
                        person.password = value;
                      });
                    },
                    controller: pwController,
                  ),
                  Center(
                    child: Column(
                      children: <Widget>[
                        FlatButton(
                          onPressed: startorstopbtn,
                          child: Text(_btntext),
                        ),FlatButton(
                          onPressed: () {
                            stopbtn();
                            exit(0);
                          },
                          child: const Text('EXIT'),
                        ),
                      ],
                    ),
                  ),
                  Container(
                    width: windowWidth,
                    child: Text(_jsoninfo),
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  easylink_flutter: ^0.9.2

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:easylink_flutter/easylink_flutter.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
0
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
88
Overall:
Weighted score of the above. [more]
48
Learn more about scoring.

We analyzed this package on Jul 11, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.15
  • Flutter: 1.17.5

Analysis suggestions

Package does not support Flutter platform Linux

Because:

  • package:easylink_flutter/easylink_flutter.dart that declares support for platforms: Android, iOS

Package does not support Flutter platform Web

Because:

  • package:easylink_flutter/easylink_flutter.dart that declares support for platforms: Android, iOS

Package does not support Flutter platform Windows

Because:

  • package:easylink_flutter/easylink_flutter.dart that declares support for platforms: Android, iOS

Package does not support Flutter platform macOS

Because:

  • package:easylink_flutter/easylink_flutter.dart that declares support for platforms: Android, iOS

Package not compatible with SDK dart

Because:

  • easylink_flutter that is a package requiring null.

Health suggestions

Format lib/easylink_flutter.dart.

Run flutter format to format lib/easylink_flutter.dart.

Format lib/easylink_notification.dart.

Run flutter format to format lib/easylink_notification.dart.

Maintenance suggestions

The package description is too short. (-12 points)

Add more detail to the description field of pubspec.yaml. Use 60 to 180 characters to describe the package, what it does, and its target use case.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12 1.14.13
meta 1.1.8 1.2.2
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8 2.1.0-nullsafety
Dev dependencies
flutter_test