我使用Flutter构建了一个应用程序,适用于iOS和Android平台。它使用版本为7.7.0的地理定位器包。奇怪的是,虽然它可以在iOS模拟器和物理设备上运行,但在Android模拟器或物理设备上却完全不起作用。这是我创建的基于地理定位器的异步函数,用于检查权限并根据pub.dev:
的指导获取用户的当前位置。_determineCurrentPositionStarting() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
return Future.error('Location permissions are denied.');
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
return Future.error(
'Location permissions are permanently denied, so we cannot request permissions.');
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best,
forceAndroidLocationManager: true,
).then((Position position) {
setState(() {
gcStartingLatitudeGEODEG.text = position.latitude.toStringAsFixed(6);
gcStartingLongitudeGEODEG.text = position.longitude.toStringAsFixed(6);
});
}).catchError((e) {
print(e);
});
}
此外,在按钮中调用上述函数的onPressed命令看起来像这样:
onPressed: () async {
_determineCurrentPositionStarting();
},
在iOS上,它工作得很好,获取用户的位置。它只是在Android上不起作用。问题是,它根本没有产生错误日志,所以没有明显的目标供我研究。终端的一切似乎都很正常。我做了一些尝试和错误,看看我是否能找出这个过程在哪个阶段卡住了。这是我发现的:
- 该功能能够检查位置服务是否已启用,如果未启用则显示弹出警告。
- 该函数能够检查权限并通过弹出窗口请求它,如果它还没有权限(总是,只有在使用应用程序时,从不等)。如果never被选中,将生成一个警告,如预期的那样。
- 如果权限永远被拒绝,函数能够给出警告。
- 当我们到达return await Geolocator.getCurrentPosition…
这让我认为android平台和await geollocator . getcurrentposition()函数存在问题。
因为在我的iOS设备和模拟器上一切都很好,但在Android上却不行,我想这一定是与Android特定的设置有关。
在我的androidmanifest.xml文件中,据我所知,我有正确的权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
我使用gradle版本7.0.0和在我的构建。Gradle文件(android>应用程序在我的SDK版本是:
- compileSdkVersion: 31日
- minSdkVersion: 23
- targetSdkVersion: 31日
如果有帮助,说明Flutter Doctor没有错误:
[✓] Flutter (Channel stable, 2.5.3, on macOS 11.6 20G165 darwin-x64, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 2020.3)
[✓] Connected device (2 available)
我错过了什么吗?你能看出为什么它不能在Android上运行吗?任何帮助将不胜感激!
编辑我刚刚在运行Android 11.0的Android模拟器上尝试了它,而不是12.0,它工作得很好。在我看来,这可能与7.0.0版本包中的突破性变化如何与Android 12.0模拟器交互有关。我会看一遍,如果我能找出答案,我会把它作为我的问题的答案贴出来。
首先,根据插件作者在7.0.0版本中描述的突破性变化,我修改了用于获取坐标的函数,主要涉及权限部分。
_determineCurrentPositionStarting() async {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return;
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
return;
}
}
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
return;
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
return await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.bestForNavigation,
forceAndroidLocationManager: true,
timeLimit: null,
).then((Position position) {
setState(() {
gcStartingLatitudeGEODEG.text = position.latitude.toStringAsFixed(6);
gcStartingLongitudeGEODEG.text = position.longitude.toStringAsFixed(6);
});
}).catchError((e) {
print(e);
});
}
然后,我决定做一个时间测试,似乎基本上,即使是我最初认为它不起作用的Android设备,它实际上也起作用了,只是延迟了很长时间。
例如,在我的安卓物理设备三星Galaxy A21s上,它需要48秒到几分钟的时间,但它确实返回坐标。
因此,我只能假设它在所有平台上都能工作,它完全取决于设备的类型,其中的GPS模块的质量以及用户所在位置的GPS连接,以及结果的速度。
这就是它没有产生错误日志的原因。它正在工作,只是需要一些时间。