android 如何根据Jetpack合成中的流量获取GPS按钮状态

nkcskrwz  于 2023-01-28  发布在  Android
关注(0)|答案(2)|浏览(106)

我想在关闭GPS时看到设置对话框(要求)以关闭GPS,因为我的应用程序需要GPS。我已经为此编写了代码,并将其放在MainActivity中的onCreate()中,但对话框仅在应用程序运行时显示,但我想在应用程序中关闭GPS时看到此对话框。

val settingsClient = LocationServices.getSettingsClient(this)
        val locationRequest = LocationRequest()
        val builder =
            LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
                .setAlwaysShow(false)
                .setNeedBle(false)
        settingsClient.checkLocationSettings(builder.build())
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    val response = task.result ?: return@addOnCompleteListener
                    val locationSettingsStates =
                        response.locationSettingsStates
                    Log.e("yyy", locationSettingsStates.toString())
                    // TODO
                }
            }
            .addOnFailureListener { e ->
                Timber.i("checkLocationSetting onFailure:" + e.message)
                when ((e as ApiException).statusCode) {
                    LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
                        Timber.i("Location settings are not satisfied. Attempting to upgrade " + "location settings ")
                        try {
                            // Show the dialog by calling startResolutionForResult(), and check the
                            // result in onActivityResult().
                            val rae = e as ResolvableApiException
                            rae.startResolutionForResult(this, 0)
                        } catch (sie: IntentSender.SendIntentException) {
                            Timber.i("PendingIntent unable to execute request.")
                        }
                    }
                    else -> {
                    }
                }
            }
    }
brccelvz

brccelvz1#

这是一种方法:

我创建了一个LocationUtil类:

class LocationUtil(context: Context) {
    companion object {
        const val MIN_TIME: Long = 1000L
        const val MIN_DISTANCE: Float = 0.0f
    }

    private val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    private var locationListener: LocationListener? = null

    val locationStateFlow = MutableStateFlow<Location>(Location(LocationManager.GPS_PROVIDER))
    val gpsProviderState = mutableStateOf(false)
    val isStart: MutableState<Boolean> = mutableStateOf(false)

    private val locHandlerThread = HandlerThread("LocationUtil Thread")

    init {
        locHandlerThread.start()
    }

    @SuppressLint("MissingPermission")
    fun start(minTimeMs: Long = MIN_TIME_MS, minDistanceM: Float = MIN_DISTANCE_M) {
        locationListener().let {
            locationListener = it
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTimeMs, minDistanceM, it, locHandlerThread.looper)
        }
        gpsProviderState.value = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
        isStart.value = true
    }

    fun stop() {
        locationListener?.let {
            locationManager.removeUpdates(it)
        }
        isStart.value = false
    }

    private fun locationListener() = object : LocationListener {
        override fun onLocationChanged(location: Location) {
            locationStateFlow.value = location
        }

        override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {
        }

        override fun onProviderEnabled(provider: String) {
            gpsProviderState.value = true
        }

        override fun onProviderDisabled(provider: String) {
            gpsProviderState.value = false
        }
    }

}

然后创建一个包含以下函数的文件:

private const val REQUEST_CODE_LOCATION_SOURCE_SETTINGS = 200

fun getLocationManager(context: Context): LocationManager =
    context.getSystemService(Context.LOCATION_SERVICE) as LocationManager

fun isLocEnable(context: Context): Boolean {
    val locationManager = getLocationManager(context)
    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
}

@Composable
fun IsLocationEnable(context: Context) {
    if (!isLocEnable(context)) {
        SimpleAlertDialog(
            title = stringResource(id = R.string.title),
            text = stringResource(id = R.string.dialog_gps_setting),
            singleButton = false,
            confirmText = stringResource(R.string.settings),
            dismissText = stringResource(R.string.cancel),
            onConfirm = {
                if (it) {
                    Intent(
                        Settings.ACTION_LOCATION_SOURCE_SETTINGS,
                        Uri.fromParts(
                            "package",
                            context.packageName,
                            null
                        )
                    ).also { intent ->
                        try {
                            context.startActivity(
                                intent
                            )
                        } catch (e: ActivityNotFoundException) {
                            Intent(
                                Settings.ACTION_LOCATION_SOURCE_SETTINGS
                            ).also { intentCatch ->
                                context.startActivity(
                                    intentCatch
                                )
                            }
                        }

                    }
                }
            })
    }
}

@Composable
fun LocationState(context: Activity) {
    IsLocationEnable(context)
}

最后,我使用了MainActivity中的代码:

Box(modifier = Modifier.fillMaxSize()) {
                        Column(modifier = Modifier.fillMaxSize()) {
                            ConnectivityStatus()
                            ClientScaffold(clientNavigator)
                        }
                        val gpsEnable by locationUtil.gpsProviderState
                        if (!gpsEnable) {
                            IsLocationEnable(this@MainActivity)
                        }
                    }
fumotvh3

fumotvh32#

让数据层LocationRepository具有如下gpsStatus流如何

class LocationRepository(/** inject context **/) {

    val gpsStatus = flow {
        val manager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        while (currentCoroutineContext().isActive) {
            emit(
                manager.isProviderEnabled(LocationManager.GPS_PROVIDER)
            )
            delay(3000)
        }
    }
}

然后在UI层观察,以隐藏/显示对话框。

相关问题