Fix WIFI state permission again

This commit is contained in:
世界 2024-02-16 14:35:11 +08:00
parent 4504447a2c
commit f8ebfaabe2
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
5 changed files with 89 additions and 38 deletions

View file

@ -12,7 +12,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
@ -144,7 +144,7 @@
<service
android:name=".bg.VPNService"
android:exported="false"
android:foregroundServiceType="specialUse|location"
android:foregroundServiceType="specialUse"
android:permission="android.permission.BIND_VPN_SERVICE">
<intent-filter>
<action android:name="android.net.VpnService" />
@ -156,7 +156,7 @@
<service
android:name=".bg.ProxyService"
android:exported="false"
android:foregroundServiceType="specialUse|location">
android:foregroundServiceType="specialUse">
<property
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="proxy" />

View file

@ -5,6 +5,7 @@ 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
@ -169,6 +170,23 @@ class BoxService(
}
newService.start()
if (newService.needWIFIState()) {
val wifiPermission = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
android.Manifest.permission.ACCESS_FINE_LOCATION
} else {
android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
}
if (ContextCompat.checkSelfPermission(
service, wifiPermission
) != PackageManager.PERMISSION_GRANTED
) {
newService.close()
stopAndAlert(Alert.RequestLocationPermission)
return
}
}
boxService = newService
commandServer?.setService(boxService)
status.postValue(Status.Started)

View file

@ -3,6 +3,7 @@ package io.nekohasekai.sfa.constant
enum class Alert {
RequestVPNPermission,
RequestNotificationPermission,
RequestLocationPermission,
EmptyConfiguration,
StartCommandServer,
CreateService,

View file

@ -4,12 +4,13 @@ import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.net.VpnService
import android.os.Build
import android.os.Bundle
import android.os.Process
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
@ -188,38 +189,12 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
}
@SuppressLint("NewApi")
fun startService(skipRequestLocation: Boolean = false) {
fun startService() {
if (!ServiceNotification.checkPermission()) {
notificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
return
}
// MIUI always return false for shouldShowRequestPermissionRationale
if (!skipRequestLocation && ContextCompat.checkSelfPermission(
this, Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(
this, Manifest.permission.ACCESS_FINE_LOCATION
)
) {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.location_permission_title)
.setMessage(R.string.location_permission_description)
.setPositiveButton(R.string.ok) { _, _ ->
locationPermissionLauncher.launch(
arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
)
)
}
.setCancelable(false)
.show()
return
}
}
lifecycleScope.launch(Dispatchers.IO) {
if (Settings.rebuildServiceMode()) {
reconnect()
@ -246,11 +221,8 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
}
}
private val locationPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) {
startService(true)
}
private val locationPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) {}
private val prepareLauncher = registerForActivityResult(PrepareService()) {
if (it) {
@ -290,6 +262,14 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
}
override fun onServiceAlert(type: Alert, message: String?) {
when (type) {
Alert.RequestLocationPermission -> {
return requestLocationPermission()
}
else -> {}
}
val builder = MaterialAlertDialogBuilder(this)
builder.setPositiveButton(R.string.ok, null)
when (type) {
@ -320,10 +300,62 @@ class MainActivity : AbstractActivity(), ServiceConnection.Callback {
builder.setMessage(message)
}
else -> {}
}
builder.show()
}
private fun requestLocationPermission() {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.location_permission_title)
.setMessage(R.string.location_permission_description)
.setPositiveButton(R.string.ok) { _, _ ->
requestLocationPermission0()
}
.setCancelable(false)
.show()
}
private fun requestLocationPermission0() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
} else {
openPermissionSettings()
}
}
private fun openPermissionSettings() {
if (!getSystemProperty("ro.miui.ui.version.name").isNullOrBlank()) {
val intent = Intent("miui.intent.action.APP_PERM_EDITOR")
intent.putExtra("extra_package_uid", Process.myUid())
intent.putExtra("extra_pkgname", packageName)
try {
startActivity(intent)
return
} catch (ignored: Exception) {
}
}
try {
val intent = Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.parse("package:$packageName")
startActivity(intent)
} catch (e: Exception) {
errorDialogBuilder(e).show()
}
}
@SuppressLint("PrivateApi")
fun getSystemProperty(key: String?): String? {
try {
return Class.forName("android.os.SystemProperties").getMethod("get", String::class.java)
.invoke(null, key) as String
} catch (ignored: Exception) {
}
return null
}
private var paused = false
override fun onPause() {
super.onPause()

View file

@ -146,6 +146,6 @@
<string name="other_methods">Other methods</string>
<string name="action_start">Start</string>
<string name="location_permission_title">Location permission</string>
<string name="location_permission_description">sing-box uses the location permission to provide `wifi_ssid` and `wifi_bssid` routing rule entries, deny it if you don\'t need this feature.</string>
<string name="location_permission_description">sing-box uses the **background location** permission to implement the `wifi_ssid` and `wifi_bssid` routing rule items that **you are using**.</string>
</resources>