位置访问时无法捕获的异常

时间:2018-03-22 08:55:37

标签: android kotlin wear-os android-permissions android-location

我正试图让我的Android Wear手表面确定设备的当前位置。这已经成功,但在卸载并重新安装软件包之后,它就失败了。我认为我做的一切都是正确的,它已经像那样工作了。我不知道问题是什么,甚至不知道如何抓住它。这是相关的代码:

class MyWatchFaceService : CanvasWatchFaceService() {
    override fun onCreateEngine(): Engine {
        return Engine()
    }

    inner class Engine : CanvasWatchFaceService.Engine() {
        private lateinit var fusedLocationClient: FusedLocationProviderClient
        private var lastKnownLocation: Location? = null

        override fun onCreate(holder: SurfaceHolder) {
            super.onCreate(holder)
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(this@MyWatchFaceService)
            updateLocation()
        }

        fun updateLocation() {
            Logger.getAnonymousLogger().info("updateLocation")
            try {
                fusedLocationClient.lastLocation
                        .addOnSuccessListener { location: Location? ->
                            if (location != null) {
                                // Location available, use it and update later
                                Logger.getAnonymousLogger().info("- location available")
                                lastKnownLocation = location
                            }
                        }
                        .addOnFailureListener {ex: Exception ->
                            Logger.getAnonymousLogger().warning("- location NOT accessible (inner): " + ex.toString())
                        }
            } catch (ex: SecurityException) {
                // Nothing we can do, no location available
                Logger.getAnonymousLogger().warning("- location NOT accessible: " + ex.toString())
            }
            Logger.getAnonymousLogger().info("updateLocation (end)")
        }
    }
}

然后我在日志中找到了这个:

03-22 09:41:59.521 7390-7390/de.unclassified.watchface1 I/null: updateLocation
03-22 09:41:59.536 7390-7390/de.unclassified.watchface1 I/null: updateLocation (end)
03-22 09:41:59.830 7390-7405/de.unclassified.watchface1 E/AndroidRuntime: FATAL EXCEPTION: GoogleApiHandler
                                                                          Process: de.unclassified.watchface1, PID: 7390
                                                                          java.lang.SecurityException: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations.
                                                                              at android.os.Parcel.readException(Parcel.java:1684)
                                                                              at android.os.Parcel.readException(Parcel.java:1637)
                                                                              at com.google.android.gms.internal.zzeu.zza(Unknown Source)
                                                                              at com.google.android.gms.internal.zzcfa.zzif(Unknown Source)
                                                                              at com.google.android.gms.internal.zzcfd.getLastLocation(Unknown Source)
                                                                              at com.google.android.gms.internal.zzcfk.getLastLocation(Unknown Source)
                                                                              at com.google.android.gms.location.zzg.zza(Unknown Source)
                                                                              at com.google.android.gms.common.api.internal.zze.zza(Unknown Source)
                                                                              at com.google.android.gms.common.api.internal.zzbo.zzb(Unknown Source)
                                                                              at com.google.android.gms.common.api.internal.zzbo.zzaiw(Unknown Source)
                                                                              at com.google.android.gms.common.api.internal.zzbo.onConnected(Unknown Source)
                                                                              at com.google.android.gms.common.internal.zzac.onConnected(Unknown Source)
                                                                              at com.google.android.gms.common.internal.zzn.zzakr(Unknown Source)
                                                                              at com.google.android.gms.common.internal.zze.zzw(Unknown Source)
                                                                              at com.google.android.gms.common.internal.zzi.zzaks(Unknown Source)
                                                                              at com.google.android.gms.common.internal.zzh.handleMessage(Unknown Source)
                                                                              at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                              at android.os.Looper.loop(Looper.java:154)
                                                                              at android.os.HandlerThread.run(HandlerThread.java:61)
03-22 09:41:59.843 7390-7405/de.unclassified.watchface1 I/Process: Sending signal. PID: 7390 SIG: 9

所以它调用我的updateLocation函数,然后再次离开,然后有一个例外。但是,就我所见,它并非来自我的代码。它从何而来?它没有包含源文件的堆栈跟踪。

该软件包已经具有所有相关权限,如前所述,还有其他任务用于其他任务。

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

那么这里发生了什么,为什么try / catch和失败监听器都没有做什么?

2 个答案:

答案 0 :(得分:0)

COARSE位置很危险,因此,Google强制您在运行时请求它,只需在Android Manifest中声明是不够的。请参阅此链接以获取示例:https://developer.android.com/training/permissions/requesting.html

快速代码在这里:

if (ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.ACCESS_FINE_LOCATION)
    != PackageManager.PERMISSION_GRANTED) {
   ActivityCompat.requestPermissions(thisActivity,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                0x0)
}

您应该同时请求Fine和Coarse权限。

答案 1 :(得分:0)

在启动服务之前,或者更好的是,为用户提供该服务,您需要确保它们允许为您提供粗略/精细的位置,因此您需要在活动中为他们提供选项。

以这种方式思考,您的服务在background中运行,并且您需要用户的权限来完成您的工作,并且您不能假设用户在服务运行时存在。因此,当用户在场时,您需要获得权限,即活动正在运行时。