《flutter适配鸿蒙Next笔记》:使用ArkTs开发Flutter鸿蒙插件获取微信开放平台中需要的Identifier

977 阅读2分钟

最近正在将用 Flutter 开发的应用适配到鸿蒙 Next,使用的版本是 3.7.12-ohos。适配过程相对简单,本文将记录如何通过 Flutter 开发鸿蒙插件,来获取微信开放平台所需的 identifier。

插件相关代码(使用ArkTs)

在项目根目录的 ohos 文件夹下创建插件相关的文件,文件路径 ohos/src/main/ets/plugins/NativePlugin(插件名).ets

// ohos/src/main/ets/plugins/NativePlugin.ets

import { FlutterPlugin, FlutterPluginBinding } from 
'@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin';
import Log from '@ohos/flutter_ohos/src/main/ets/util/Log';
import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger';
import MethodChannel from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel';
import MethodCall from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall';
import { MethodResult } from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel';

import { bundleManager } from '@kit.AbilityKit';

import { BusinessError } from '@kit.BasicServicesKit';

const TAG: string = 'NativePlugin';

export class NativePlugin implements FlutterPlugin {
  private methodChannel: MethodChannel | null = null;

  getUniqueClassName(): string {
    return TAG;
  }

  onAttachedToEngine(binding: FlutterPluginBinding): void {
    Log.i(TAG, 'onAttachedToEngine');
    this.startListening(binding?.getBinaryMessenger());
  }

  onDetachedFromEngine(): void {
    this.methodChannel?.setMethodCallHandler(null);
  }

  private startListening(message: BinaryMessenger): void {
    this.methodChannel = new MethodChannel(message, 'com.example.app/native');
    this.methodChannel.setMethodCallHandler({
      onMethodCall : (call: MethodCall, result: MethodResult) => {
        console.log(`${TAG}-->[${call.method}]: ${JSON.stringify(call.args)}`);
        switch (call.method) {
          // 获取应用包签名信息
          case "signatureInfo":
            let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO
            try {
              bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => {
                result.success(JSON.stringify(data))
              }).catch((err: BusinessError) => {
              });
            } catch (err) {
            }
            break;
          default:
            result.notImplemented();
            break;
        }
      }
    });
  }
}

EntryAbility.ets 加载插件,文件路径:ohos/src/main/ets/entryability/EntryAbility.ets

import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos';
import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';
// 新增:将插件代码引入
import { NativePlugin } from '../plugins/NativePlugin';

export default class EntryAbility extends FlutterAbility {
  configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    GeneratedPluginRegistrant.registerWith(flutterEngine)
    // 新增:加载插件
    flutterEngine.getPlugins()?.add(new NativePlugin());
  }
}

flutter 使用插件

在 lib 目录下的 Dart 代码中,使用 MethodChannel 与原生代码进行通信。

定义方法:

import 'package:flutter/services.dart';

class NativeBridge {
  // 定义与原生的通信通道
  static const MethodChannel _channel =
      MethodChannel('com.example.app/native');

  // 调用原生方法
  static void getNativeData() async {
    try {
      final String result = await _channel.invokeMethod('signatureInfo');
      print('原生打印');
      print(result);
    } catch (e) {
      print(e);
    }
  }
}

在 Flutter 应用中,调用 NativeBridge.getNativeData() 方法

import 'package:flutter/material.dart';
import 'native_bridge.dart';

void main() {
  runApp(MyApp());
}

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

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
    NativeBridge.getNativeData();
  }

  @override
  Widget build(BuildContext context) {
    ...
  }
}

最终打印:

{"name":"com.example.app","vendor":"example","versionCode":1,"versionName":"1.0.0","minCompatibleVersionCode":1,"targetVersion":xxxxxx,"appInfo":null,"hapModulesInfo":[],"reqPermissionDetails":[],"permissionGrantStates":[],"signatureInfo":{"appId":"xxx","fingerprint":"xxxxx","appIdentifier":"xxxxx"},"installTime":xxxxx,"updateTime":xxxxx,"routerMap":[],"appIndex":0}