4

I used this class to get current location of device for my map app. I'm using this with GooglePlayServices and its working fine, but I recently switched to HMS for Huawei devices if GooglePlayServices are not available on device. I replaced all GooglePlayServices classes with mirror objects from HMS imported lib and it compiled without errors. But as I call for current location, it will not return anything. No exception, no success or failure.

I did not receive callback to onLocationResult() or catch() block. According to debugger last row called is val task = lp.requestLocationUpdates(lr, this, Looper.getMainLooper())

Anyone has this problem? This is clearly new issue. Testing this on Huawei P40 where GooglePlayServices are not available.

Also HuaweiMap is not working in release mode. getMapAsync() will not return onMapReady() callback. It got stuck there. But if I switch debug mode, it is working correctly.

UDPATE: HuaweiMap is working now. Updated proguard. But Location is still not working. It is not working even in debug mode.

Code:

private inner class LocationCbHua(val lp: com.huawei.hms.location.FusedLocationProviderClient,
                                      val onFailure: (()->Unit)? = null,
                                      val onSuccess: (GpsLocation)->Unit)
        : com.huawei.hms.location.LocationCallback() {

        init {
            val lr = com.huawei.hms.location.LocationRequest.create().apply {
                priority = com.huawei.hms.location.LocationRequest.PRIORITY_HIGH_ACCURACY
                interval = 200
            }
            val lsr = com.huawei.hms.location.LocationSettingsRequest.Builder().run {
//                setAlwaysShow(true)  // TEST
                addLocationRequest(lr)
                build()
            }
            val check = com.huawei.hms.location.LocationServices.getSettingsClient(activity!!).checkLocationSettings(lsr)
            check.addOnCompleteListener {
                try {
                    check.getResultThrowException(com.huawei.hms.common.ApiException::class.java)
                    val task = lp.requestLocationUpdates(lr, this, Looper.getMainLooper())
                    task.addOnFailureListener {
                        onFailure?.invoke()
                    }
                } catch (e: com.huawei.hms.common.ApiException) {
                    when (e.statusCode) {
                        com.huawei.hms.location.LocationSettingsStatusCodes.RESOLUTION_REQUIRED-> if(!locationResolutionAsked){
                            // Location settings are not satisfied. But could be fixed by showing the user a dialog.
                            try {
                                // Cast to a resolvable exception.
                                val re = e as com.huawei.hms.common.ResolvableApiException
                                // Show the dialog by calling startResolutionForResult(), and check the result in onActivityResult().
                                re.startResolutionForResult(mainActivity, MainActivity.REQUEST_LOCATION_SETTINGS)
                                locationResolutionAsked = true
                            } catch (e: Exception) {
                                e.printStackTrace()
                            }
                        }
                        com.huawei.hms.location.LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE->{
                            // Location settings are not satisfied. However, we have no way to fix the settings so we won't show the dialog.
                            App.warn("Location is not available")
                            onFailure?.invoke()
                        }
                    }
                }
            }
        }

        fun cancel(){
            lp.removeLocationUpdates(this)
            currLocCb = null
        }

        override fun onLocationResult(lr: com.huawei.hms.location.LocationResult) {
            cancel()
            val ll = lr.lastLocation
            onSuccess(GpsLocation(ll.longitude, ll.latitude))
        }
    }
zhangxaochen
  • 32,744
  • 15
  • 77
  • 108
martin1337
  • 2,384
  • 6
  • 38
  • 85
  • Hello, did you have a chance to checkout examples on Huawei's Codelabs GitHub? – deadfish May 26 '20 at 21:50
  • Yes. It looks almost same as mine. But core functionality is the same. – martin1337 May 27 '20 at 04:14
  • 1. Did you set up store data location on Developer page? 2. Did you save your app's key fingerprint for release (optional for debug too)? – deadfish May 27 '20 at 15:33
  • I generated SHA256 hash from my .keystore file used for signing APK. And added it to AppGallery. Idk what is that first part. I just downloaded `agconnect-services.json` from my project and placed it to resources similar to firebase google json. – martin1337 May 27 '20 at 16:03
  • Please look at this pages. Make sure you followed the instructions. 1. https://developer.huawei.com/consumer/en/codelab/HMSLocationKit/index.html (step 4) and this 2. https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html (step 6). – deadfish May 27 '20 at 16:17
  • Yep, I did that. I though I need some API key in meta-data inside AndroidManifest like GoogleMaps. I have project there also I updated certificate fingerprint (SHA256 hash). Without fingerprint I couldnt see anything in map even in debug mode. Now Map is perfectly fine in debug but I have white screen in release. onMapReady() is not called. – martin1337 May 27 '20 at 16:24
  • Make sure AppGallery has updated all apps and libs on your P40. – deadfish May 27 '20 at 20:21
  • Everything is updated. – martin1337 May 27 '20 at 20:49
  • 1
    Could you make sure you declared right proguard rules for both libs - maps and location? https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/hms-map-integratingthehmssdk (last point 5) and https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/location-preparation (last point 3). – deadfish May 28 '20 at 08:41
  • I put those lines to `proguard-rules.pro` file and Map is finally working on release. But location is still not working. – martin1337 May 28 '20 at 09:55
  • Also, you are using `check.addOnCompleteListener()`, could you use also `addOnSuccessListener` and `addOnFailureListener` and try catch them? – deadfish May 28 '20 at 14:00
  • On my side it didn't show the dialog as well unless I change the permission of HMS Core app location to "Allow all the time" – Bitwise DEVS Sep 01 '21 at 13:35

2 Answers2

0

The possible cause is as follows:

After checkLocationSettings code was executed, an exception was catched during execution of code check.getResultThrowException. However, the catched error code is not 6 (RESOULTION_REQUIRED).

Therefore, code com.huawei.hms.location.LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE was directly executed to report Location is not available after code com.huawei.hms.location.LocationSettingsStatusCodes.RESOLUTION_REQUIRED-> if(!locationResolutionAsked) was executed.

As a result, neither exception nor location result was obtained. You are advised to add a code line at when (e.statusCode) to record error logs, and then continue error analysis.

deadfish
  • 11,996
  • 12
  • 87
  • 136
zhangxaochen
  • 32,744
  • 15
  • 77
  • 108
  • Catch branch was never executed. I put log above `when()`. Last row was `val task = lp.requestLocationUpdates(lr, this, Looper.getMainLooper())` – martin1337 May 28 '20 at 09:59
  • 1
    You can use addOnSuccessListener and addOnFailureListener instead of addOnCompleteListener, please try again, I see the source code, addOnCompleteListener will directly throw an exception – zhangxaochen May 29 '20 at 03:10
0

Use OnSuccessListener instead of OnCompleteListener

   val check = com.huawei.hms.location.LocationServices.getSettingsClient(activity!!).checkLocationSettings(lsr)
   check.addOnSuccessListener{
       lp.requestLocationUpdates(lr, this, Looper.getMainLooper())
   }

You can also check this post:

https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201272177441270079&fid=0101187876626530001

danms07
  • 141
  • 4