Flutter跨平台开发鸿蒙化定位组件使用指南

1. 插件介绍
localtion_demo 是一个专为 Flutter 跨平台开发鸿蒙化应用设计的定位组件,通过 Flutter 与鸿蒙原生代码的交互,实现了设备位置信息的获取功能。该组件提供了简洁的 API,帮助开发者轻松实现跨平台定位功能,特别针对鸿蒙平台的定位服务进行了优化,确保定位数据的准确性和稳定性。
主要功能特点:
- 支持获取设备当前位置信息
- 提供完整的位置数据(包括经度、纬度、高度、速度等)
- 支持定位权限管理
- 实现了 Flutter 与鸿蒙原生的双向通信
2. 环境要求
在使用本组件前,请确保您的开发环境满足以下要求:
- Flutter SDK 版本:≥ 2.19.6
- Dart SDK 版本:≥ 2.19.6
- 鸿蒙 SDK API 版本:≥ 9
- DevEco Studio 版本:≥ 3.0
- 鸿蒙定位服务支持:需要设备支持定位功能
3. 包的引入
由于本组件依赖于自定义修改版本的三方库,需要通过 git 形式引入。在您的 Flutter 项目的 pubspec.yaml 文件中,按照以下方式添加依赖:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
# 吐司提示组件
fluttertoast:
git:
url: "https://atomgit.com/openharmony-sig/flutter_fluttertoast.git"
path: "./"
添加完依赖后,执行以下命令获取依赖包:
flutter pub get
4. 权限配置
在鸿蒙应用中使用定位功能需要配置相应的权限。在 ohos/entry/src/main/module.json5 文件中添加以下权限配置:
"requestPermissions": [
{
"name": "ohos.permission.LOCATION",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.LOCATION_IN_BACKGROUND",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
}
]
5. 功能实现与API调用
5.1 Flutter端实现
// ignore_for_file: library_private_types_in_public_api
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('获取定位信息'),
),
body: const MessageReceiver(),
),
);
}
}
class MessageReceiver extends StatefulWidget {
const MessageReceiver({Key? key}) : super(key: key);
_MessageReceiverState createState() => _MessageReceiverState();
}
class _MessageReceiverState extends State<MessageReceiver> {
String? message;
void initState() {
super.initState();
_setupMethodChannel();
}
Future<void> _setupMethodChannel() async {
// 创建 MethodChannel 用于与原生通信
const channel = MethodChannel('com.example.yourapp/channel');
// 设置方法调用处理器
channel.setMethodCallHandler((call) async {
if (call.method == 'sendMessage') {
// 接收来自原生的定位信息
final String? msg = call.arguments as String?;
setState(() {
message = msg;
});
// 显示定位信息吐司
Fluttertoast.showToast(
msg: msg.toString(),
toastLength: Toast.LENGTH_SHORT,
backgroundColor: Colors.red,
textColor: Colors.white
);
}
});
}
Widget build(BuildContext context) {
return Center(
child: message == null
? Text('未接收到定位信息.')
: Text('来自Arkts的定位信息: $message'),
);
}
}
5.2 鸿蒙原生插件实现
5.2.1 自定义插件类
import MethodChannel, {
MethodCallHandler,
MethodResult
} from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel';
import common from '@ohos.app.ability.common';
import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger';
import MethodCall from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall';
import {
FlutterPlugin,
FlutterPluginBinding
} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin';
export default class CustomPlugin implements FlutterPlugin, MethodCallHandler {
private context: common.Context | null = null;
private channel: MethodChannel | null = null;
private static instance: CustomPlugin | null = null;
public static getInstance(): CustomPlugin {
if (!CustomPlugin.instance) {
CustomPlugin.instance = new CustomPlugin();
}
return CustomPlugin.instance;
}
constructor() {
if (!CustomPlugin.instance) {
CustomPlugin.instance = this;
} else {
return CustomPlugin.instance;
}
}
getUniqueClassName(): string {
return "CustomPlugin";
}
onAttachedToEngine(binding: FlutterPluginBinding): void {
this.context = binding.getApplicationContext();
this.channel = new MethodChannel(binding.getBinaryMessenger(), 'com.example.yourapp/channel');
this.channel.setMethodCallHandler(this);
}
onDetachedFromEngine(binding: FlutterPluginBinding): void {
this.channel?.destroy();
this.context = null;
}
onMethodCall(call: MethodCall, result: MethodResult): void {
// 可以在此处理来自Flutter的方法调用
}
// 向Flutter发送消息的方法
public sendMessage(res: String): void {
this.channel?.invokeMethod('sendMessage', res);
}
}
5.2.2 定位功能实现
import common from '@ohos.app.ability.common';
import { FlutterPage } from '@ohos/flutter_ohos';
import { geoLocationManager } from '@kit.LocationKit';
import { BusinessError } from '@kit.BasicServicesKit';
import CustomPlugin from '../entryability/CustomPlugin';
// 获取当前位置信息
function getCurrentLocationInfo() {
// 配置定位请求参数
const requestInfo: geoLocationManager.LocationRequest = {
'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
'scenario': geoLocationManager.LocationRequestScenario.UNSET,
'timeInterval': 1,
'distanceInterval': 0,
'maxAccuracy': 0
};
// 获取自定义插件实例
const custom = CustomPlugin.getInstance();
try {
// 调用鸿蒙定位服务获取当前位置
geoLocationManager.getCurrentLocation(requestInfo)
.then((location: geoLocationManager.Location) => {
// 将位置信息转换为JSON字符串
let value: ESObject = JSON.stringify(location);
// 发送位置信息到Flutter端
custom.sendMessage(value);
})
.catch((err: BusinessError) => {
console.error(`获取位置失败. 错误码: ${err.code}, 错误信息: ${err.message}`);
});
} catch (err) {
console.error(`获取位置失败. 错误码: ${err.code}, 错误信息: ${err.message}`);
}
}
// 定义位置按钮组件
@Component
struct LocationButton {
build() {
Button('获取定位')
.width(200)
.height(50)
.fontSize(18)
}
}
let storage = LocalStorage.getShared();
const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS';
@Entry(storage)
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext;
@LocalStorageLink('viewId') viewId: string = "";
build() {
Column() {
// 嵌入Flutter页面
FlutterPage({ viewId: this.viewId });
// 添加定位按钮
Button('获取定位')
.width(200)
.height(50)
.fontSize(18)
.onClick((event: ClickEvent) => {
console.info("点击了获取定位按钮");
// 调用获取位置信息函数
getCurrentLocationInfo();
})
.position({ x: '35%', y: '20%' })
}
}
onBackPress(): boolean {
this.context.eventHub.emit(EVENT_BACK_PRESS);
return true;
}
}
5.2.3 注册插件
import { FlutterAbility } from '@ohos/flutter_ohos';
import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';
import FlutterEngine from '@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine';
import CustomPlugin from './CustomPlugin';
export default class EntryAbility extends FlutterAbility {
configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine);
GeneratedPluginRegistrant.registerWith(flutterEngine);
// 注册自定义插件
this.addPlugin(new CustomPlugin());
}
}
6. 代码解析
6.1 关键组件说明
- MethodChannel:用于 Flutter 与鸿蒙原生代码之间的双向通信
- CustomPlugin:自定义插件类,实现了 FlutterPlugin 接口,用于注册和管理 MethodChannel
- geoLocationManager:鸿蒙定位服务,用于获取设备当前位置信息
- FlutterPage:用于在鸿蒙页面中嵌入 Flutter 组件
6.2 定位流程
- 用户点击鸿蒙页面上的"获取定位"按钮
- 调用
getCurrentLocationInfo()函数获取当前位置信息 - 使用
geoLocationManager.getCurrentLocation()方法获取设备位置 - 将位置信息转换为 JSON 字符串
- 通过
CustomPlugin的sendMessage()方法将位置信息发送到 Flutter 端 - Flutter 端通过 MethodChannel 接收位置信息并显示
7. 常见问题与解决方案
7.1 定位权限问题
如果无法获取位置信息,请检查是否已正确配置定位权限。在鸿蒙应用中,需要配置 ohos.permission.LOCATION 和 ohos.permission.LOCATION_IN_BACKGROUND 权限。
7.2 MethodChannel 通信失败
确保 Flutter 和鸿蒙原生代码中使用的 MethodChannel 名称一致,本示例中使用的名称是 com.example.yourapp/channel。
7.3 依赖包问题
确保已正确添加 fluttertoast 依赖包,并且版本兼容。
8. 总结
localtion_demo 组件为 Flutter 跨平台开发鸿蒙化应用提供了简洁、高效的定位功能解决方案:
- 跨平台通信:通过 MethodChannel 实现了 Flutter 与鸿蒙原生代码的无缝通信
- 完整的定位功能:支持获取设备当前位置信息,包括经度、纬度、高度、速度等
- 权限管理:提供了完整的定位权限配置示例
- 易于集成:提供了详细的代码示例和使用说明
该组件的实现充分考虑了鸿蒙平台的特性,确保了定位功能的准确性和稳定性,同时提供了简洁易用的 API,帮助开发者快速集成到自己的应用中。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐




所有评论(0)