【发布时间】:2023-01-18 02:14:14
【问题描述】:
我正在开发 MVVM 应用程序,在使用 GoogleMap 可组合的位置跟踪时出现以下错误:
2022-10-02 18:43:48.734 31711-31750/com.park.reserved W/MobStoreFlagStore: Unable to update local snapshot for com.google.android.libraries.consentverifier#com.park.reserved, may result in stale flags.
java.util.concurrent.ExecutionException: java.lang.SecurityException: GoogleCertificatesRslt: not allowed: pkg=com.park.reserved, sha256=[462925ab37c5ec4ab8550323438372023f34e9897a556848dd8c35d18c4e71c6], atk=false, ver=223616044.true (go/gsrlt)
at ahn.s(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):3)
at ahn.get(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):2)
at aix.g(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):2)
at xq.d(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):1)
at xs.run(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):0)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:463)
at java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:307)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at java.lang.Thread.run(Thread.java:1012)
Caused by: java.lang.SecurityException: GoogleCertificatesRslt: not allowed: pkg=com.park.reserved, sha256=[462925ab37c5ec4ab8550323438372023f34e9897a556848dd8c35d18c4e71c6], atk=false, ver=223616044.true (go/gsrlt)
at android.os.Parcel.createExceptionOrNull(Parcel.java:2426)
at android.os.Parcel.createException(Parcel.java:2410)
at android.os.Parcel.readException(Parcel.java:2393)
at android.os.Parcel.readException(Parcel.java:2335)
at em.c(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):2)
at rc.a(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):4)
at it.e(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):2)
at js.t(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):2)
at js.u(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):3)
at js.e(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):2)
at jw.handleMessage(:com.google.android.gms.dynamite_mapsdynamite@223616044@22.36.16 (190400-0):69)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.os.HandlerThread.run(HandlerThread.java:67)
发生这种情况时,该应用程序仍在运行,但 GoogleMap compose 上的位置跟踪不起作用 [我可以成功跟踪手机位置,但尝试在 GoogleMap compose 上显示位置时出现异常]
Gradle:
implementation "com.google.maps.android:maps-compose:2.7.2"
implementation "com.google.android.gms:play-services-maps:18.1.0"
我查看了以下类似的 StackOverflow 帖子,但我得到的错误是不同的:SecurityException - GoogleCertificatesRslt: not allowed
我能够解决此问题的唯一方法是在 NavHost 之外创建 viewModel。位置跟踪以这种方式工作,但异常仍然会在 Logcat 中抛出
这是代码:
我有 SharedLocationManager 类作为位置数据源:
class SharedLocationManager constructor(
private val context: Context,
// The Fused Location Provider provides access to location APIs
private val fusedLocationClient: FusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(context)
) {
. . .
}
我有 LocationRepository 类:
class LocationRepository @Inject constructor(
private val sharedLocationManager: SharedLocationManager
) {
// Observe flow for device last location updates
fun lastLocation(): Flow<Location> = sharedLocationManager.lastLocationFlow()
// Observable flow for device location updates
fun getLocationFlow(): SharedFlow<Location?> = sharedLocationManager.locationFlow()
}
我有 viewModel 需要 LocationRepository:
@HiltViewModel
class FindParkingViewModel @Inject constructor(
private val repository: LocationRepository // Data store from which to receive location updates via Flow, injected via Hilt
) : ViewModel() {
. . .
}
然后,我有一个采用 viewModel 参数的可组合项,从 viewModel 获取位置并将其显示在 GoogleMaps 上:
@Composable
fun FindParking(findParkingViewModel: FindParkingViewModel) {
findParkingViewModel location has value
val deviceCurrentLoc by findParkingViewModel.location.collectAsState(initial = null)
. . .
val cameraPosState = rememberCameraPositionState {
position = CameraPosition.fromLatLngZoom(deviceCurrentLocLatLng, 12f)
}
GoogleMap(
modifier = modifier,
cameraPositionState = cameraPositionState,
properties = mapProperties,
uiSettings = uiSettings,
onMapLoaded = onMapLoaded
) {
}
}
最后,我有NavHost:
@Composable
fun MapAppNavHost(
navController: NavHostController,
modifier: Modifier = Modifier
) {
// ** Creating the viewModel here solves the issue
location tracking val findParkingViewModel: FindParkingViewModel = hiltViewModel()
NavHost(
navController = navController,
startDestination = TopLevelDestination.Parking.route,
modifier = modifier
) {
composable(route = TopLevelDestination.Parking.route) {
FindParking(findParkingViewModel)
}
. . .
}
按照以下方式执行会引发异常:
我更喜欢#1 方法,因为代码更清晰。
#1. 将 viewModel 分配为默认参数会引发错误:
@Composable
fun FindParking(findParkingViewModel: FindParkingViewModel = hiltViewModel()) {
. . .
}
#2 在NavHost Composable 函数中创建viewModel 也会抛出错误:
NavHost(
navController = navController,
startDestination = TopLevelDestination.Parking.route,
modifier = modifier
) {
composable(route = TopLevelDestination.Parking.route) {
// ---> creating this here breaks it
val findParkingViewModel: FindParkingViewModel = hiltViewModel()
FindParking(findParkingViewModel)
}
}
【问题讨论】:
标签: android google-maps google-api android-jetpack-compose