2

I am working on MVVM app and I am getting the following error when using location tracking with GoogleMap composable:

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)

The app still runs when this happens, but the location tracking on GoogleMap compose doesn't work [I can successfully track the phone location, but I get the exception when trying to show the location on GoogleMap compose]

Gradle:

implementation "com.google.maps.android:maps-compose:2.7.2"
implementation "com.google.android.gms:play-services-maps:18.1.0"

I looked at the following similar StackOverflow post, but the error I'm getting is different: SecurityException - GoogleCertificatesRslt: not allowed


The only way I was able to fix the issue is by creating the viewModel outside of the NavHost. The location tracking works doing it this way, but the exception still gets thrown in Logcat

Here's the code:

I have SharedLocationManager class that serves as location data source:

class SharedLocationManager constructor(
    private val context: Context,
    // The Fused Location Provider provides access to location APIs
    private val fusedLocationClient: FusedLocationProviderClient =
        LocationServices.getFusedLocationProviderClient(context)
) {
 
. . . 

}

I have LocationRepository class:

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()
}

I have viewModel that takes the LocationRepository:

@HiltViewModel
class FindParkingViewModel @Inject constructor(
    private val repository: LocationRepository // Data store from which to receive location updates via Flow, injected via Hilt
) : ViewModel() {

. . .
}

Then, I have a composable that takes the viewModel argument, gets the location from the viewModel and displays it on 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
    ) {
        
    }

}

Finally, I have the 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)
        }

        . . .
      
    }


Doing it the following way throws the exception:

I prefer #1 approach because the code is cleaner.

#1. Assigning the viewModel as a default parameter throws an error:

@Composable
fun FindParking(findParkingViewModel: FindParkingViewModel = hiltViewModel()) {
    . . .
}

#2 creating the viewModel within the NavHost Composable function also throws an error:

 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)
        }
 }
leo
  • 113
  • 3
  • 11

1 Answers1

0

I tried almost every available solution and the only one which helped me, was: uninstalling the app from emulator and installing it again. It may sound stupid, but it worked for me.

Arturr300
  • 96
  • 5