Flutter地理位置获取插件flutter_z_location的使用
Flutter地理位置获取插件flutter_z_location的使用
Flutter开源免费定位插件
现如今几乎每一个 App 都存在定位的逻辑,方便更好地推荐产品或服务,获取当前设备的经纬度、所在城市几乎是必备的功能了!iOS 定位经纬度及反向地理编码原生均能很好地实现。然而 Android 由于系统原因,反向地理编码获取地址信息需要使用谷歌服务。大多需要依赖高德/百度三方定位库实现该功能。
本项目是 Flutter 定位插件,支持获取经纬度及经纬度、IP 反向地理编码获取地址信息(省、市、区),纯原生获取 GPS 定位信息。反向地理编码获取地址信息均来自本地,没有并发限制、次数限制且无收费。
这里尤其感谢 pikaz-18 大佬的数据源。JS 定位大家可使用 pikaz-location。
请大佬们多多指教,给个 Star,你的支持就是我不断前进的动力,谢谢。
特性
- 单次获取经纬度信息
- 经纬度、IP 反向地理编码获取地址信息(省、市、区),精确度到区/县
- 资源文件目前仅支持本地,尚未实现远程按需下载使用。后续将会完善此功能
安装
在 pubspec.yaml
中添加:
dependencies:
# 最新版本
flutter_z_location: ^0.0.7
Android 端配置
在 <code>AndroidManifest.xml</code>
文件中添加定位权限:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
iOS 端配置
在 <code>info.plist</code>
文件中添加定位权限:
<!-- 在使用期间访问位置 -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>App需要您的同意, APP才能在使用期间访问位置</string>
使用
将 <code>example/assets</code>
目录下的资源文件添加到自己的项目的 <code>assets</code>
中,并在 <code>pubspec.yaml</code>
中加入如下配置。
assets:
- assets/province/
- assets/ip/
- assets/city/
- assets/district/
- assets/areaList/
目前五个文件夹必须在同一级目录,如果您的资源目录结构不一致,对应设置 <code>pathHead</code>
参数即可。
详细使用请参考项目 <code>example</code>
用例,下面只列出常用方法:
import 'package:flutter_z_location/flutter_z_location.dart';
import 'package:permission_handler/permission_handler.dart';
// 获取GPS定位经纬度
final coordinate = await FlutterZLocation().getCoordinate();
// 经纬度反向地理编码获取地址信息(省、市、区)
final res1 = await FlutterZLocation().geocodeCoordinate(coordinate.latitude, coordinate.longitude, pathHead: 'assets/');
// 获取ip地址
final ipStr = await FlutterZLocation().getIp();
// 经纬度反向地理编码获取地址信息(省、市、区)
final res2 = await FlutterZLocation.geocodeIp(ipStr, pathHead: 'assets/');
示例代码
以下是完整的示例代码,展示了如何使用 flutter_z_location
插件获取经纬度信息并进行反向地理编码。
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_z_location/flutter_z_location.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
double latitude = 0;
double longitude = 0;
String geocodeStr = '';
String ipInfo = 'ip: ,\ngeocode: ';
[@override](/user/override)
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
String platformVersion;
try {
platformVersion = await FlutterZLocation.getPlatformVersion() ?? 'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
children: [
const SizedBox(height: 12),
Text('Running on: $_platformVersion\n'),
const SizedBox(height: 12),
OutlinedButton(
onPressed: () async {
Permission.location.request().then((value) async {
final res = await FlutterZLocation.getCoordinate(accuracy: 1);
debugPrint(res.toString());
setState(() {
latitude = res.latitude;
longitude = res.longitude;
geocodeCoordinate();
});
});
},
child: const Text('getCoordinate'),
),
const SizedBox(height: 12),
Text(
'latitude: $latitude \nlongitude: $longitude \ngeocode:$geocodeStr',
style: const TextStyle(fontSize: 15, color: Colors.black),
),
OutlinedButton(
onPressed: () async {
// 获取ip地址
final ipStr = await FlutterZLocation.getIp();
// ip反编码出地址
final res = await FlutterZLocation.geocodeIp(
ipStr,
pathHead: 'assets/',
hasGetCoordinate: true,
);
debugPrint(ipStr);
debugPrint(res.toString());
setState(() {
ipInfo = 'ip: $ipStr,\ngeocode: ${res.address}';
});
},
child: const Text('get ip'),
),
Text(
ipInfo,
style: const TextStyle(fontSize: 15, color: Colors.black),
),
],
),
),
),
);
}
Future<void> geocodeCoordinate() async {
final res = await FlutterZLocation.geocodeCoordinate(latitude, longitude);
if (kDebugMode) {
print(res);
}
setState(() {
geocodeStr = res.address;
});
}
}
更多关于Flutter地理位置获取插件flutter_z_location的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter地理位置获取插件flutter_z_location的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用flutter_z_location
插件来获取地理位置信息的示例代码。
首先,你需要在pubspec.yaml
文件中添加flutter_z_location
依赖:
dependencies:
flutter:
sdk: flutter
flutter_z_location: ^最新版本号 # 请替换为实际最新版本号
然后,运行flutter pub get
命令来安装依赖。
接下来,我们编写一些代码来获取地理位置信息。下面是一个完整的示例,包括权限请求和位置获取的逻辑。
- 创建一个新的Flutter项目(如果还没有的话):
flutter create my_location_app
cd my_location_app
- 修改
android/app/src/main/AndroidManifest.xml
: 确保你已经添加了必要的权限。通常,flutter_z_location
插件会自动处理这些权限请求,但最好手动检查一下。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.my_location_app">
<!-- 添加必要的权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
... >
...
</application>
</manifest>
- 修改
lib/main.dart
:
import 'package:flutter/material.dart';
import 'package:flutter_z_location/flutter_z_location.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: LocationScreen(),
);
}
}
class LocationScreen extends StatefulWidget {
@override
_LocationScreenState createState() => _LocationScreenState();
}
class _LocationScreenState extends State<LocationScreen> {
FlutterZLocation? _flutterZLocation;
String? _locationResult;
@override
void initState() {
super.initState();
_flutterZLocation = FlutterZLocation();
_requestPermissions();
}
Future<void> _requestPermissions() async {
Map<Permission, PermissionStatus> statuses = await Permission.requestMultiple([
Permission.locationWhenInUse,
Permission.locationAlways,
]);
if (statuses[Permission.locationWhenInUse] == PermissionStatus.granted ||
statuses[Permission.locationAlways] == PermissionStatus.granted) {
_getCurrentLocation();
} else {
setState(() {
_locationResult = "位置权限被拒绝";
});
}
}
Future<void> _getCurrentLocation() async {
try {
LocationResult result = await _flutterZLocation!.getLocation();
if (result.resultCode == 0) {
setState(() {
_locationResult = "经度: ${result.latitude}, 纬度: ${result.longitude}";
});
} else {
setState(() {
_locationResult = "获取位置失败,错误码: ${result.resultCode}";
});
}
} catch (e) {
setState(() {
_locationResult = "获取位置时发生错误: $e";
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("获取地理位置"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
_locationResult ?? "正在请求位置权限...",
style: TextStyle(fontSize: 18),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
_getCurrentLocation();
},
child: Text("重新获取位置"),
),
],
),
),
);
}
}
在这个示例中,我们:
- 请求位置权限。
- 使用
flutter_z_location
插件获取当前位置。 - 将结果显示在屏幕上。
请确保你的项目已经配置好必要的权限,并且在Android模拟器或真实设备上运行此代码,因为模拟器有时可能无法模拟位置权限请求。
注意:flutter_z_location
插件的具体方法和类名可能会随着版本更新而变化,因此请参考该插件的官方文档以获取最新和最准确的信息。