Flutter插件开发之APK自动安装

本文适用于Android开发人员

个人博客

什么是Flutter Plugin

Flutter Plugin是一种特殊的包,包含一个用Dart编写的API定义,结合Android和iOS的平台特定实现,从而达到二者兼容。

  • 应用的Flutter部分通过平台通道(platform channel)将消息发送到其应用程序的所在的宿主(iOS或Android)
  • 宿主监听的平台通道,并接收该消息。然后它会调用特定于该平台的API(使用原生编程语言) - 并将响应发送回客户端,即应用程序的Flutter部分
    使用平台通道在客户端(Flutter UI)和宿主(平台)之间传递消息,如下图所示


    enter image description here

创建Flutter App

相关代码见运行第一个Flutter App

创建Flutter Plugin

右键工程->New->Module,如下图所示


enter image description here

选择Flutter Plugin,点击Next,如下图所示


enter image description here
输入工程名(Project name),点击Next,如下图所示
enter image description here

输入包名(Package name),点击Finish,入下图所示


enter image description here
到此Flutter plugin创建完成。

引入插件

在工程目录下找到pubspec.yaml文件,在dev_dependencies添加如下依赖,如下图所示

enter image description here
相关代码如下

dev_dependencies:  flutter_test:    sdk: flutter  install_apk_plugin:    path: install_apk_plugin

获取版本号demo

打开插件lib下的dart文件,会有平台自动生成的代码,具体是实现获取APP版本号,如下面代码所示

class InstallApkPlugin {  static const MethodChannel _channel =      const MethodChannel('install_apk_plugin');  static Future get platformVersion async {    final String version = await _channel.invokeMethod('getPlatformVersion');    return version;  }}

java部分的代码如下面所示

public class InstallApkPlugin implements MethodCallHandler {    private static final String TAG = "InstallApkPlugin";    private final Registrar registrar;    /**     * Plugin registration.     */    public static void registerWith(Registrar registrar) {        final MethodChannel channel = new MethodChannel(registrar.messenger(), "install_apk_plugin");        channel.setMethodCallHandler(new InstallApkPlugin(registrar));    }    private InstallApkPlugin(Registrar registrar) {        this.registrar = registrar;    }    @Override    public void onMethodCall(MethodCall call, Result result) {        if (call.method.equals("getPlatformVersion")) {            result.success("Android " + android.os.Build.VERSION.RELEASE);        } else {            result.notImplemented();        }    }}

实现自动安装APK

实现自动安装APK,需要从Flutter应用层传入一个APK安装包的地址到host层,dart代码如下所示:

class InstallApkPlugin {  static const MethodChannel _channel =      const MethodChannel('install_apk_plugin');  static Future get platformVersion async {    final String version = await _channel.invokeMethod('getPlatformVersion');    return version;  }  static Future installApk(String path) async {    final bool isSuccess = await _channel.invokeMethod('installApk', path);    return isSuccess;  }}

java部分的代码如下所示

public class InstallApkPlugin implements MethodCallHandler {    private static final String TAG = "InstallApkPlugin";    private final Registrar registrar;    /**     * Plugin registration.     */    public static void registerWith(Registrar registrar) {        final MethodChannel channel = new MethodChannel(registrar.messenger(), "install_apk_plugin");        channel.setMethodCallHandler(new InstallApkPlugin(registrar));    }    private InstallApkPlugin(Registrar registrar) {        this.registrar = registrar;    }    @Override    public void onMethodCall(MethodCall call, Result result) {        if (call.method.equals("getPlatformVersion")) {            result.success("Android " + android.os.Build.VERSION.RELEASE);        } else if (call.method.equals("installApk")) {            final String path = (String) call.arguments;            Log.d(TAG, "installApk path is " + path);        } else {            result.notImplemented();        }    }}

到此,host层就能获取到APK安装包的路径了,后面只需实现Android安装APK的代码逻辑即可,在日志下面添加如下代码

    File file = new File(path);    installApk(file, registrar.context());

installApk代码实现如下所示

    private void installApk(File apkFile, Context context) {        Intent installApkIntent = new Intent();        installApkIntent.setAction(Intent.ACTION_VIEW);        installApkIntent.addCategory(Intent.CATEGORY_DEFAULT);        installApkIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        Uri apkUri = null;        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {            apkUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", apkFile);            installApkIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);        } else {            apkUri = Uri.fromFile(apkFile);        }        installApkIntent.setDataAndType(apkUri, "application/vnd.android.package-archive");        if (context.getPackageManager().queryIntentActivities(installApkIntent, 0).size() > 0) {            context.startActivity(installApkIntent);        }    }

除此之外,还需修改AndroidManifest.xml内的代码,如下面代码所示

                                                        

file_path.xml放在res->xml文件夹下面,如下面代码所示

<?xml version="1.0" encoding="utf-8"?>    

运行代码如下图所示


enter image description here

源代码

项目地址-OpenGit客户端

更多相关文章

  1. 20172321 2017-2018-2 《程序设计与数据结构》第11周学习总结
  2. Android中自定义控件和属性
  3. Android(安卓)平台软件兼容性问题凸显
  4. Android(安卓)添加系统服务的方法
  5. 【Android(安卓)NDK】(一)Hello World!
  6. Android(安卓)BroadcastAnyWhere(Google Bug 17356824)漏洞详细
  7. Android(安卓)悬浮窗 (附圆形菜单悬浮窗)
  8. 【Android】xml文件里面出现unbound prefix的问题
  9. qt for Android(安卓)环境搭建 win10

随机推荐

  1. Android(安卓)消息处理机制
  2. 【Android】Lambda表达式
  3. Android(安卓)SDK 中常用的几个命令
  4. android 团队开发技巧1 - activity 启动
  5. Android(安卓)TabHost的使用 .
  6. Android定义字符串数组资源并在程序中使
  7. 【解决方法】ADT在线安装
  8. Android(安卓)中文API (33) —— Checkable
  9. Android(安卓)Toolchain与Bionic Libc
  10. Android(安卓)OpenGL学习笔记(二)之----