You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.4 KiB
106 lines
3.4 KiB
import 'package:flutter/services.dart';
|
|
|
|
class LocationService {
|
|
static final LocationService _instance = LocationService._internal();
|
|
|
|
/// 获取单例
|
|
factory LocationService() => _instance;
|
|
|
|
// 方法通道
|
|
final MethodChannel _methodChannel = MethodChannel(
|
|
'com.yunqiinnovation.location_service',
|
|
);
|
|
|
|
// 内部构造函数
|
|
LocationService._internal();
|
|
|
|
/// 检查定位权限
|
|
Future<Map<String, bool>> checkPermission() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<Map>('checkPermission');
|
|
return {
|
|
'hasPermission': result?['hasPermission'] ?? false,
|
|
'hasForegroundPermission': result?['hasForegroundPermission'] ?? false,
|
|
'hasBackgroundPermission': result?['hasBackgroundPermission'] ?? false,
|
|
};
|
|
} catch (e) {
|
|
throw Exception('检查权限失败: $e');
|
|
}
|
|
}
|
|
|
|
/// 请求定位权限
|
|
Future<bool> requestPermission() async {
|
|
try {
|
|
final result = await _methodChannel.invokeMethod<Map>(
|
|
'requestPermission',
|
|
);
|
|
return result?['granted'] ?? false;
|
|
} catch (e) {
|
|
throw Exception('请求权限失败: $e');
|
|
}
|
|
}
|
|
|
|
/// 检查系统位置服务是否开启
|
|
/// 参数:无
|
|
/// 返回值:true 表示已开启;false 表示未开启或检测失败
|
|
/// 异常:抛出 Exception,表示方法通道调用失败或平台异常
|
|
Future<bool> isLocationServiceEnabled() async {
|
|
try {
|
|
final enabled = await _methodChannel.invokeMethod<bool>(
|
|
'isLocationServiceEnabled',
|
|
);
|
|
return enabled ?? false;
|
|
} catch (e) {
|
|
throw Exception('检查位置服务失败: $e');
|
|
}
|
|
}
|
|
|
|
/// 取一次当前位置和省市区(2026-09-25 新增,给百炼 `${location}` 用)。
|
|
///
|
|
/// **不申请权限**:没权限、超时、定位失败都返回 `{'error': 原因}`,由调用方决定何时申请权限。
|
|
/// 成功返回键:latitude / longitude(double)、province / city / district / street / address
|
|
/// (String,可能为空)。
|
|
Future<Map<String, dynamic>> currentPlace({int timeoutMs = 15000}) async {
|
|
try {
|
|
final r = await _methodChannel.invokeMethod<Map>(
|
|
'getCurrentPlace',
|
|
{'timeoutMs': timeoutMs},
|
|
);
|
|
if (r == null) return {'error': 'empty'};
|
|
return r.map((k, v) => MapEntry('$k', v));
|
|
} on PlatformException catch (e) {
|
|
return {'error': e.message ?? e.code};
|
|
} on MissingPluginException {
|
|
return {'error': 'not_implemented'};
|
|
} catch (e) {
|
|
return {'error': '$e'};
|
|
}
|
|
}
|
|
|
|
/// 获取当前位置(按需获取)
|
|
Future<Map<String, dynamic>> location() async {
|
|
try {
|
|
// 先检查权限
|
|
final permissionStatus = await checkPermission();
|
|
if (!permissionStatus['hasPermission']!) {
|
|
// 请求权限
|
|
final granted = await requestPermission();
|
|
if (!granted) {
|
|
throw Exception('用户拒绝了定位权限');
|
|
}
|
|
}
|
|
|
|
final result = await _methodChannel.invokeMethod<Map>('location');
|
|
if (result != null) {
|
|
return {
|
|
'latitude': double.tryParse(result['user_lat'] ?? '0.0') ?? 0.0,
|
|
'longitude': double.tryParse(result['user_lng'] ?? '0.0') ?? 0.0,
|
|
'address': result['user_location'] ?? '未知地址',
|
|
};
|
|
}
|
|
throw Exception('获取位置信息失败');
|
|
} catch (e) {
|
|
throw Exception('定位失败: $e');
|
|
}
|
|
}
|
|
}
|
|
|