Skip to content

Commit a4dbcd3

Browse files
iKirbynekohasekai
authored andcommitted
Improve location permission request and description
1 parent a35318d commit a4dbcd3

3 files changed

Lines changed: 93 additions & 10 deletions

File tree

app/src/main/java/io/nekohasekai/sfa/bg/BoxService.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import android.content.BroadcastReceiver
55
import android.content.Context
66
import android.content.Intent
77
import android.content.IntentFilter
8-
import android.content.pm.PackageManager
98
import android.os.Build
109
import android.os.IBinder
1110
import android.os.ParcelFileDescriptor
@@ -27,6 +26,7 @@ import io.nekohasekai.sfa.constant.Alert
2726
import io.nekohasekai.sfa.constant.Status
2827
import io.nekohasekai.sfa.database.ProfileManager
2928
import io.nekohasekai.sfa.database.Settings
29+
import io.nekohasekai.sfa.ktx.hasPermission
3030
import kotlinx.coroutines.Dispatchers
3131
import kotlinx.coroutines.GlobalScope
3232
import kotlinx.coroutines.delay
@@ -174,10 +174,7 @@ class BoxService(
174174
} else {
175175
android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
176176
}
177-
if (ContextCompat.checkSelfPermission(
178-
service, wifiPermission
179-
) != PackageManager.PERMISSION_GRANTED
180-
) {
177+
if (!service.hasPermission(wifiPermission)) {
181178
newService.close()
182179
stopAndAlert(Alert.RequestLocationPermission)
183180
return
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package io.nekohasekai.sfa.ktx
2+
3+
import android.content.Context
4+
import android.content.pm.PackageManager
5+
import androidx.core.content.ContextCompat
6+
7+
fun Context.hasPermission(permission: String): Boolean {
8+
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
9+
}

app/src/main/java/io/nekohasekai/sfa/ui/MainActivity.kt

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import android.net.VpnService
99
import android.os.Build
1010
import android.os.Bundle
1111
import android.os.Process
12+
import android.text.Html
1213
import androidx.activity.result.contract.ActivityResultContract
1314
import androidx.activity.result.contract.ActivityResultContracts
15+
import androidx.annotation.RequiresApi
1416
import androidx.core.content.ContextCompat
1517
import androidx.lifecycle.MutableLiveData
1618
import androidx.lifecycle.lifecycleScope
@@ -34,6 +36,7 @@ import io.nekohasekai.sfa.database.Settings
3436
import io.nekohasekai.sfa.database.TypedProfile
3537
import io.nekohasekai.sfa.databinding.ActivityMainBinding
3638
import io.nekohasekai.sfa.ktx.errorDialogBuilder
39+
import io.nekohasekai.sfa.ktx.hasPermission
3740
import io.nekohasekai.sfa.ui.profile.NewProfileActivity
3841
import io.nekohasekai.sfa.ui.shared.AbstractActivity
3942
import io.nekohasekai.sfa.vendor.Vendor
@@ -220,7 +223,26 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
220223
}
221224

222225
private val locationPermissionLauncher =
223-
registerForActivityResult(ActivityResultContracts.RequestPermission()) {}
226+
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
227+
if (it) {
228+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
229+
requestBackgroundLocationPermission()
230+
} else {
231+
startService()
232+
}
233+
} else {
234+
showPermissionDeniedDescription()
235+
}
236+
}
237+
238+
private val backgroundLocationPermissionLauncher =
239+
registerForActivityResult(ActivityResultContracts.RequestPermission()) {
240+
if (it) {
241+
startService()
242+
} else {
243+
showPermissionDeniedDescription()
244+
}
245+
}
224246

225247
private val prepareLauncher = registerForActivityResult(PrepareService()) {
226248
if (it) {
@@ -305,24 +327,58 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
305327
}
306328

307329
private fun requestLocationPermission() {
330+
if (!hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
331+
requestFineLocationPermission()
332+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
333+
requestBackgroundLocationPermission()
334+
}
335+
}
336+
337+
private fun requestFineLocationPermission() {
338+
val message = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
339+
Html.fromHtml(
340+
getString(R.string.location_permission_description),
341+
Html.FROM_HTML_MODE_LEGACY
342+
)
343+
} else {
344+
@Suppress("DEPRECATION")
345+
Html.fromHtml(getString(R.string.location_permission_description))
346+
}
308347
MaterialAlertDialogBuilder(this)
309348
.setTitle(R.string.location_permission_title)
310-
.setMessage(R.string.location_permission_description)
349+
.setMessage(message)
311350
.setPositiveButton(R.string.ok) { _, _ ->
312-
requestLocationPermission0()
351+
requestFineLocationPermission0()
313352
}
314353
.setCancelable(false)
315354
.show()
316355
}
317356

318-
private fun requestLocationPermission0() {
319-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
357+
private fun requestFineLocationPermission0() {
358+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
320359
locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
321360
} else {
322361
openPermissionSettings()
323362
}
324363
}
325364

365+
@RequiresApi(Build.VERSION_CODES.Q)
366+
private fun requestBackgroundLocationPermission() {
367+
MaterialAlertDialogBuilder(this)
368+
.setTitle(R.string.location_permission_title)
369+
.setMessage(
370+
Html.fromHtml(
371+
getString(R.string.location_permission_background_description),
372+
Html.FROM_HTML_MODE_LEGACY
373+
)
374+
)
375+
.setPositiveButton(R.string.ok) { _, _ ->
376+
backgroundLocationPermissionLauncher.launch(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
377+
}
378+
.setCancelable(false)
379+
.show()
380+
}
381+
326382
private fun openPermissionSettings() {
327383
if (!getSystemProperty("ro.miui.ui.version.name").isNullOrBlank()) {
328384
val intent = Intent("miui.intent.action.APP_PERM_EDITOR")
@@ -344,6 +400,27 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
344400
}
345401
}
346402

403+
private fun showPermissionDeniedDescription() {
404+
val message = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
405+
Html.fromHtml(
406+
getString(R.string.location_permission_denied_description),
407+
Html.FROM_HTML_MODE_LEGACY
408+
)
409+
} else {
410+
@Suppress("DEPRECATION")
411+
Html.fromHtml(getString(R.string.location_permission_denied_description))
412+
}
413+
MaterialAlertDialogBuilder(this)
414+
.setTitle(R.string.location_permission_title)
415+
.setMessage(message)
416+
.setPositiveButton(R.string.ok, null)
417+
.setNeutralButton(R.string.open_settings) { _, _ ->
418+
openPermissionSettings()
419+
}
420+
.setCancelable(false)
421+
.show()
422+
}
423+
347424
@SuppressLint("PrivateApi")
348425
fun getSystemProperty(key: String?): String? {
349426
try {

0 commit comments

Comments
 (0)