Fix: Add missing permissions and runtime permission handling for auto-sync
Critical fixes for SSID detection on Android 12+: - Add CHANGE_WIFI_STATE permission (NetworkCallback registration) - Add ACCESS_BACKGROUND_LOCATION permission (SSID access) - Add FOREGROUND_SERVICE_DATA_SYNC permission SettingsActivity improvements: - Add checkBackgroundLocationPermission() method - Show dialog explaining need for 'Always allow' location - Request permission with proper callbacks - Better user feedback for permission grants/denials NetworkMonitor improvements: - Add initial WiFi check in startMonitoring() - Add NET_CAPABILITY_INTERNET to NetworkRequest - Better error handling for '<unknown ssid>' cases - Log warning about missing BACKGROUND_LOCATION permission This should fix the root cause: SSID was showing as '<unknown ssid>' because app lacked background location permission on Android 16. User must select 'Always allow' when prompted for location permission.
This commit is contained in:
@@ -5,9 +5,13 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".SimpleNotesApplication"
|
android:name=".SimpleNotesApplication"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val REQUEST_LOCATION_PERMISSION = 1002
|
private const val REQUEST_LOCATION_PERMISSION = 1002
|
||||||
|
private const val REQUEST_BACKGROUND_LOCATION_PERMISSION = 1003
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@@ -182,26 +183,6 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(
|
|
||||||
requestCode: Int,
|
|
||||||
permissions: Array<out String>,
|
|
||||||
grantResults: IntArray
|
|
||||||
) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
|
||||||
|
|
||||||
when (requestCode) {
|
|
||||||
REQUEST_LOCATION_PERMISSION -> {
|
|
||||||
if (grantResults.isNotEmpty() &&
|
|
||||||
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
// Permission granted, try again
|
|
||||||
detectCurrentSSID()
|
|
||||||
} else {
|
|
||||||
showToast("Standort-Berechtigung benötigt um WLAN-Name zu erkennen")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onAutoSyncToggled(enabled: Boolean) {
|
private fun onAutoSyncToggled(enabled: Boolean) {
|
||||||
prefs.edit().putBoolean(Constants.KEY_AUTO_SYNC, enabled).apply()
|
prefs.edit().putBoolean(Constants.KEY_AUTO_SYNC, enabled).apply()
|
||||||
|
|
||||||
@@ -209,6 +190,8 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
showToast("Auto-Sync aktiviert")
|
showToast("Auto-Sync aktiviert")
|
||||||
// Check battery optimization when enabling
|
// Check battery optimization when enabling
|
||||||
checkBatteryOptimization()
|
checkBatteryOptimization()
|
||||||
|
// Check background location permission (needed for SSID on Android 12+)
|
||||||
|
checkBackgroundLocationPermission()
|
||||||
} else {
|
} else {
|
||||||
showToast("Auto-Sync deaktiviert")
|
showToast("Auto-Sync deaktiviert")
|
||||||
}
|
}
|
||||||
@@ -257,6 +240,102 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkBackgroundLocationPermission() {
|
||||||
|
// Background location permission only needed on Android 10+
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// First check if we have foreground location
|
||||||
|
if (ContextCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
// Request foreground location first
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
this,
|
||||||
|
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
|
||||||
|
REQUEST_LOCATION_PERMISSION
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check background location (Android 10+)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
if (ContextCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
||||||
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
showBackgroundLocationDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showBackgroundLocationDialog() {
|
||||||
|
AlertDialog.Builder(this)
|
||||||
|
.setTitle("Hintergrund-Standort")
|
||||||
|
.setMessage(
|
||||||
|
"Damit die App dein WLAN-Netzwerk erkennen kann, " +
|
||||||
|
"wird Zugriff auf den Standort im Hintergrund benötigt.\n\n" +
|
||||||
|
"Dies ist eine Android-Einschränkung ab Version 10.\n\n" +
|
||||||
|
"Bitte wähle im nächsten Dialog 'Immer zulassen'."
|
||||||
|
)
|
||||||
|
.setPositiveButton("Fortfahren") { _, _ ->
|
||||||
|
requestBackgroundLocationPermission()
|
||||||
|
}
|
||||||
|
.setNegativeButton("Später") { dialog, _ ->
|
||||||
|
dialog.dismiss()
|
||||||
|
showToast("Auto-Sync funktioniert ohne diese Berechtigung nicht")
|
||||||
|
}
|
||||||
|
.setCancelable(false)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requestBackgroundLocationPermission() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
this,
|
||||||
|
arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION),
|
||||||
|
REQUEST_BACKGROUND_LOCATION_PERMISSION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<out String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
|
||||||
|
when (requestCode) {
|
||||||
|
REQUEST_LOCATION_PERMISSION -> {
|
||||||
|
if (grantResults.isNotEmpty() &&
|
||||||
|
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// Foreground location granted, now request background
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
checkBackgroundLocationPermission()
|
||||||
|
} else {
|
||||||
|
// For detectCurrentSSID
|
||||||
|
detectCurrentSSID()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showToast("Standort-Berechtigung benötigt um WLAN-Name zu erkennen")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
REQUEST_BACKGROUND_LOCATION_PERMISSION -> {
|
||||||
|
if (grantResults.isNotEmpty() &&
|
||||||
|
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
showToast("✅ Hintergrund-Standort erlaubt - Auto-Sync sollte jetzt funktionieren!")
|
||||||
|
} else {
|
||||||
|
showToast("⚠️ Ohne Hintergrund-Standort kann WLAN nicht erkannt werden")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
return when (item.itemId) {
|
return when (item.itemId) {
|
||||||
android.R.id.home -> {
|
android.R.id.home -> {
|
||||||
|
|||||||
@@ -66,11 +66,17 @@ class NetworkMonitor(private val context: Context) {
|
|||||||
|
|
||||||
val request = NetworkRequest.Builder()
|
val request = NetworkRequest.Builder()
|
||||||
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||||
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
connectivityManager.registerNetworkCallback(request, networkCallback)
|
connectivityManager.registerNetworkCallback(request, networkCallback)
|
||||||
Log.d(TAG, "✅ NetworkCallback registered successfully")
|
Log.d(TAG, "✅ NetworkCallback registered successfully")
|
||||||
|
|
||||||
|
// *** FIX #3: Check if already connected to WiFi ***
|
||||||
|
Log.d(TAG, "🔍 Performing initial WiFi check...")
|
||||||
|
checkAndTriggerSync()
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "❌ Failed to register NetworkCallback: ${e.message}", e)
|
Log.e(TAG, "❌ Failed to register NetworkCallback: ${e.message}", e)
|
||||||
}
|
}
|
||||||
@@ -134,6 +140,13 @@ class NetworkMonitor(private val context: Context) {
|
|||||||
|
|
||||||
Log.d(TAG, "Current SSID: '$currentSSID', Home SSID: '$homeSSID'")
|
Log.d(TAG, "Current SSID: '$currentSSID', Home SSID: '$homeSSID'")
|
||||||
|
|
||||||
|
// *** FIX #4: Better error handling for missing SSID ***
|
||||||
|
if (currentSSID.isEmpty() || currentSSID == "<unknown ssid>") {
|
||||||
|
Log.w(TAG, "⚠️ Cannot get SSID - likely missing ACCESS_BACKGROUND_LOCATION permission!")
|
||||||
|
Log.w(TAG, "⚠️ On Android 12+, apps need 'Allow all the time' location permission")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
val isHome = currentSSID == homeSSID
|
val isHome = currentSSID == homeSSID
|
||||||
Log.d(TAG, "Is home WiFi: $isHome")
|
Log.d(TAG, "Is home WiFi: $isHome")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user