@@ -9,8 +9,10 @@ import android.net.VpnService
99import android.os.Build
1010import android.os.Bundle
1111import android.os.Process
12+ import android.text.Html
1213import androidx.activity.result.contract.ActivityResultContract
1314import androidx.activity.result.contract.ActivityResultContracts
15+ import androidx.annotation.RequiresApi
1416import androidx.core.content.ContextCompat
1517import androidx.lifecycle.MutableLiveData
1618import androidx.lifecycle.lifecycleScope
@@ -34,6 +36,7 @@ import io.nekohasekai.sfa.database.Settings
3436import io.nekohasekai.sfa.database.TypedProfile
3537import io.nekohasekai.sfa.databinding.ActivityMainBinding
3638import io.nekohasekai.sfa.ktx.errorDialogBuilder
39+ import io.nekohasekai.sfa.ktx.hasPermission
3740import io.nekohasekai.sfa.ui.profile.NewProfileActivity
3841import io.nekohasekai.sfa.ui.shared.AbstractActivity
3942import 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