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

1 回复

更多关于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命令来安装依赖。

接下来,我们编写一些代码来获取地理位置信息。下面是一个完整的示例,包括权限请求和位置获取的逻辑。

  1. 创建一个新的Flutter项目(如果还没有的话)
flutter create my_location_app
cd my_location_app
  1. 修改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>
  1. 修改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("重新获取位置"),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们:

  1. 请求位置权限。
  2. 使用flutter_z_location插件获取当前位置。
  3. 将结果显示在屏幕上。

请确保你的项目已经配置好必要的权限,并且在Android模拟器或真实设备上运行此代码,因为模拟器有时可能无法模拟位置权限请求。

注意flutter_z_location插件的具体方法和类名可能会随着版本更新而变化,因此请参考该插件的官方文档以获取最新和最准确的信息。

回到顶部