Improve location permission request and description

This commit is contained in:
iKirby 2024-02-19 22:58:51 +08:00 committed by 世界
parent a35318ded2
commit a4dbcd344a
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
3 changed files with 93 additions and 10 deletions

View file

@ -5,7 +5,6 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.Build
import android.os.IBinder
import android.os.ParcelFileDescriptor
@ -27,6 +26,7 @@ import io.nekohasekai.sfa.constant.Alert
import io.nekohasekai.sfa.constant.Status
import io.nekohasekai.sfa.database.ProfileManager
import io.nekohasekai.sfa.database.Settings
import io.nekohasekai.sfa.ktx.hasPermission
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
@ -174,10 +174,7 @@ class BoxService(
} else {
android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
}
if (ContextCompat.checkSelfPermission(
service, wifiPermission
) != PackageManager.PERMISSION_GRANTED
) {
if (!service.hasPermission(wifiPermission)) {
newService.close()
stopAndAlert(Alert.RequestLocationPermission)
return

View file

@ -0,0 +1,9 @@
package io.nekohasekai.sfa.ktx
import android.content.Context
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
fun Context.hasPermission(permission: String): Boolean {
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}

View file

@ -9,8 +9,10 @@ import android.net.VpnService
import android.os.Build
import android.os.Bundle
import android.os.Process
import android.text.Html
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
@ -34,6 +36,7 @@ import io.nekohasekai.sfa.database.Settings
import io.nekohasekai.sfa.database.TypedProfile
import io.nekohasekai.sfa.databinding.ActivityMainBinding
import io.nekohasekai.sfa.ktx.errorDialogBuilder
import io.nekohasekai.sfa.ktx.hasPermission
import io.nekohasekai.sfa.ui.profile.NewProfileActivity
import io.nekohasekai.sfa.ui.shared.AbstractActivity
import io.nekohasekai.sfa.vendor.Vendor
@ -220,7 +223,26 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
}
private val locationPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {}
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (it) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
requestBackgroundLocationPermission()
} else {
startService()
}
} else {
showPermissionDeniedDescription()
}
}
private val backgroundLocationPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
if (it) {
startService()
} else {
showPermissionDeniedDescription()
}
}
private val prepareLauncher = registerForActivityResult(PrepareService()) {
if (it) {
@ -305,24 +327,58 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
}
private fun requestLocationPermission() {
if (!hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
requestFineLocationPermission()
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
requestBackgroundLocationPermission()
}
}
private fun requestFineLocationPermission() {
val message = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(
getString(R.string.location_permission_description),
Html.FROM_HTML_MODE_LEGACY
)
} else {
@Suppress("DEPRECATION")
Html.fromHtml(getString(R.string.location_permission_description))
}
MaterialAlertDialogBuilder(this)
.setTitle(R.string.location_permission_title)
.setMessage(R.string.location_permission_description)
.setMessage(message)
.setPositiveButton(R.string.ok) { _, _ ->
requestLocationPermission0()
requestFineLocationPermission0()
}
.setCancelable(false)
.show()
}
private fun requestLocationPermission0() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
private fun requestFineLocationPermission0() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
} else {
openPermissionSettings()
}
}
@RequiresApi(Build.VERSION_CODES.Q)
private fun requestBackgroundLocationPermission() {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.location_permission_title)
.setMessage(
Html.fromHtml(
getString(R.string.location_permission_background_description),
Html.FROM_HTML_MODE_LEGACY
)
)
.setPositiveButton(R.string.ok) { _, _ ->
backgroundLocationPermissionLauncher.launch(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
}
.setCancelable(false)
.show()
}
private fun openPermissionSettings() {
if (!getSystemProperty("ro.miui.ui.version.name").isNullOrBlank()) {
val intent = Intent("miui.intent.action.APP_PERM_EDITOR")
@ -344,6 +400,27 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
}
}
private fun showPermissionDeniedDescription() {
val message = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(
getString(R.string.location_permission_denied_description),
Html.FROM_HTML_MODE_LEGACY
)
} else {
@Suppress("DEPRECATION")
Html.fromHtml(getString(R.string.location_permission_denied_description))
}
MaterialAlertDialogBuilder(this)
.setTitle(R.string.location_permission_title)
.setMessage(message)
.setPositiveButton(R.string.ok, null)
.setNeutralButton(R.string.open_settings) { _, _ ->
openPermissionSettings()
}
.setCancelable(false)
.show()
}
@SuppressLint("PrivateApi")
fun getSystemProperty(key: String?): String? {
try {