From 10ed90a0c6fbe95fc40d1941cdb3520f891d1642 Mon Sep 17 00:00:00 2001 From: andrekir Date: Tue, 14 Dec 2021 08:49:23 -0300 Subject: [PATCH 1/5] allow permission deny --- app/src/main/java/com/geeksville/mesh/MainActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index d2b85057a..0841c55fa 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -316,7 +316,7 @@ class MainActivity : AppCompatActivity(), Logging, .setTitle(getString(R.string.required_permissions)) .setMessage(getMissingMessage()) .setNeutralButton(R.string.cancel_no_radio) { _, _ -> - error("User bailed due to permissions") + warn("User bailed due to permissions") } .setPositiveButton(R.string.allow_will_show) { _, _ -> doRequest() From 3ba0b3030416ac19b2794d9c228d85e7b29de802 Mon Sep 17 00:00:00 2001 From: andrekir Date: Tue, 14 Dec 2021 16:43:22 -0300 Subject: [PATCH 2/5] update permission strings --- app/src/main/java/com/geeksville/mesh/MainActivity.kt | 4 ++-- .../main/java/com/geeksville/mesh/ui/SettingsFragment.kt | 2 +- app/src/main/res/values-pt-rBR/strings.xml | 6 +++--- app/src/main/res/values-pt/strings.xml | 6 +++--- app/src/main/res/values/strings.xml | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 0841c55fa..d980f692f 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -315,10 +315,10 @@ class MainActivity : AppCompatActivity(), Logging, MaterialAlertDialogBuilder(this) .setTitle(getString(R.string.required_permissions)) .setMessage(getMissingMessage()) - .setNeutralButton(R.string.cancel_no_radio) { _, _ -> + .setNeutralButton(R.string.cancel) { _, _ -> warn("User bailed due to permissions") } - .setPositiveButton(R.string.allow_will_show) { _, _ -> + .setPositiveButton(R.string.accept) { _, _ -> doRequest() } .show() diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index 29b98e8eb..8951a186d 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -665,7 +665,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { .setNeutralButton(R.string.cancel) { _, _ -> debug("Decided not to report a bug") } - .setPositiveButton(getString(R.string.show_system_settings)) { _, _ -> + .setPositiveButton(getString(R.string.accept)) { _, _ -> myActivity.requestBackgroundPermission() } .show() diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 815890b80..8ea7664dd 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -31,7 +31,7 @@ O Google Analytics está desativado. Infelizmente a plataforma de mapas utilizada (Mapbox) requer este recurso ativado para uso do plano \’gratuito\’ . Tivemos que desativar a visualização do mapa.\n\n Para poder visualizar o mapa será necessário ativar o Google Analytics na configuração do Android (pode ser necessário forçar o reinício do aplicativo).\n\n Se tiver interesse em que o Meshtastic use um plano pago do Mapbox (ou mude para uma plataforma de mapas diferente), por favor envie uma mensagem em meshtastic.discourse.group - Meshtastic precisa permissão de %s. Sem isso o Android não permite conexão com um rádio LoRa via bluetooth. + Meshtastic precisa da permissão de %s e da localização ativada para encontrar novos dispositivos via bluetooth. Você pode desativar novamente depois. Rádio estava em suspensão (sleep), não foi possível mudar de canal Informar Bug Informar um bug @@ -104,9 +104,9 @@ Escuro Padrão do sistema Escolher tema - Localização em segundo plano necessária + Localização em segundo plano Exibir configurações do sistema - Para usar esta função, você deve permitir acesso ao Local com a opção "localização em segundo plano".\n\nIsso permite acesso à localização enquanto o Meshtastic roda em segundo plano, possibilitando o envio da sua localização aos outros membros da mesh. + Para este recurso, você deve conceder permissão para acessar Local com a opção \"Permitir o tempo todo\".\nIsto permite ao Meshtastic ler a localização do seu smartphone e enviar aos membros da sua mesh, mesmo quando o aplicativo está fechado ou não em uso. Permissões necessárias localização Cancelar (sem acesso ao rádio) diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 5f20a9401..1bc24438d 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -30,7 +30,7 @@ Tem os dados analícos desativados. Infelizmente o fornecedor do mapa (mapbox) requer dos dados analíticos estejam activados para o seu plano \'gratuito\' . Por isso a visualização do mapa esta desativado.\n\n Se pretender visualizar o mapa, vai necessitar de ativar os dados anaíticos no painel Configurações (também pode ser necessário forçar o reinício do aplicativo). \n\n Se estiver interessado em pagarmos pelo mapbox (ou mudar para um provedor de mapas diferente), contacte através de meshtastic.discourse.group - Uma permissão necessária está a faltar, o Meshtastic não será capaz de funcionar corretamente. Ative nas configurações do aplicativo Android. + Meshtastic precisa da permissão de %s e da localização ativada para encontrar novos dispositivos via bluetooth. Você pode desativar novamente depois. O rádio estava a dormir, não conseguia mudar de canal Reportar Bug Reportar a bug @@ -104,9 +104,9 @@ Escuro Padrão do sistema Escolher tema - Localização em segundo plano necessária + Localização em segundo plano Exibir configurações do sistema - Para usar esta função, você deve permitir acesso ao Local com a opção "localização em segundo plano".\n\nIsso permite acesso à localização enquanto o Meshtastic roda em segundo plano, possibilitando o envio da sua localização aos outros membros da mesh. + Para este recurso, você deve conceder permissão para acessar Local com a opção \"Permitir o tempo todo\".\nIsto permite ao Meshtastic ler a localização do seu smartphone e enviar aos membros da sua mesh, mesmo quando o aplicativo está fechado ou não em uso. Permissões necessárias localização Cancelar (sem acesso ao rádio) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ff8518694..58fae92b1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -35,7 +35,7 @@ You have analytics disabled. Unfortunately our map provider (mapbox) requires analytics to be allowed for their \'free\' plan. So we have turned off the map view.\n\n If you would like to see the map, you\'ll need to turn on analytics in the Settings pane (also, for the time being you might need to force restart the application).\n\n If you are interested in us paying for mapbox (or switching to a different map provider), please post in meshtastic.discourse.group - Meshtastic needs %s permission granted. Without this Android will not allow connecting to the LoRa bluetooth radios. + Meshtastic needs %s permission and location must be turned on to find new devices via bluetooth. You can turn it off again afterwards. Radio was sleeping, could not change channel Report Bug Report a bug @@ -108,9 +108,9 @@ Dark System default Choose theme - Background location access required + Background location Show system settings - In order to enable this feature, you must grant "allow location access all the time" permission.\n\nThis allows meshtastic to read your location while the application is in the background, so that it can send your location to other members of your mesh. + For this feature, you must grant Location permission option \"Allow all the time\".\nThis allows Meshtastic to read your smartphone location and send it to other members of your mesh, even when the app is closed or not in use. Required permissions location Cancel (no radio access) From bb4067240150c237aa6d3ff073d40686de3f5214 Mon Sep 17 00:00:00 2001 From: andrekir Date: Tue, 14 Dec 2021 22:48:20 -0300 Subject: [PATCH 3/5] disable storage --- app/src/main/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 016006d7b..f5429969b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -35,8 +35,9 @@ --> - + From e21f3fdf93f85f7750fc4c0e4718b10ffe3741d5 Mon Sep 17 00:00:00 2001 From: andrekir Date: Wed, 15 Dec 2021 09:04:44 -0300 Subject: [PATCH 4/5] add location only logic --- .../main/java/com/geeksville/mesh/MainActivity.kt | 4 ++++ .../geeksville/mesh/android/ContextServices.kt | 12 ++++++++++++ .../com/geeksville/mesh/ui/SettingsFragment.kt | 15 +++++++++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index d980f692f..994db498d 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -41,6 +41,7 @@ import com.geeksville.android.GeeksvilleApplication import com.geeksville.android.Logging import com.geeksville.android.ServiceClient import com.geeksville.concurrent.handledLaunch +import com.geeksville.mesh.android.getLocationPermissions import com.geeksville.mesh.android.getBackgroundPermissions import com.geeksville.mesh.android.getCameraPermissions import com.geeksville.mesh.android.getMissingPermissions @@ -251,6 +252,9 @@ class MainActivity : AppCompatActivity(), Logging, /** Ask the user to grant camera permission */ fun requestCameraPermission() = requestPermission(getCameraPermissions(), false) + /** Ask the user to grant foreground location permission */ + fun requestLocationPermission() = requestPermission(getLocationPermissions(), false) + /** Ask the user to grant background location permission */ fun requestBackgroundPermission() = requestPermission(getBackgroundPermissions(), false) diff --git a/app/src/main/java/com/geeksville/mesh/android/ContextServices.kt b/app/src/main/java/com/geeksville/mesh/android/ContextServices.kt index 77fad486b..093d58f69 100644 --- a/app/src/main/java/com/geeksville/mesh/android/ContextServices.kt +++ b/app/src/main/java/com/geeksville/mesh/android/ContextServices.kt @@ -40,6 +40,18 @@ fun Context.getCameraPermissions(): List { /** @return true if the user already has camera permission */ fun Context.hasCameraPermission() = getCameraPermissions().isEmpty() +/** + * Camera permission (or empty if we already have what we need) + */ +fun Context.getLocationPermissions(): List { + val perms = mutableListOf(Manifest.permission.ACCESS_FINE_LOCATION) + + return getMissingPermissions(perms) +} + +/** @return true if the user already has camera permission */ +fun Context.hasLocationPermission() = getLocationPermissions().isEmpty() + /** * A list of missing background location permissions (or empty if we already have what we need) */ diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index 8951a186d..42a13e753 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -35,6 +35,7 @@ import com.geeksville.mesh.MainActivity import com.geeksville.mesh.R import com.geeksville.mesh.RadioConfigProtos import com.geeksville.mesh.android.bluetoothManager +import com.geeksville.mesh.android.hasLocationPermission import com.geeksville.mesh.android.hasBackgroundPermission import com.geeksville.mesh.android.usbManager import com.geeksville.mesh.databinding.SettingsFragmentBinding @@ -656,14 +657,20 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { if (view.isPressed && isChecked) { // We want to ignore changes caused by code (as opposed to the user) debug("User changed location tracking to $isChecked") - view.isChecked = - myActivity.hasBackgroundPermission() // Don't check the box until the system setting changes - if (!view.isChecked) + val hasLocationPermission = myActivity.hasLocationPermission() + val hasBackgroundPermission = myActivity.hasBackgroundPermission() + + // Don't check the box until the system setting changes + view.isChecked = hasLocationPermission && hasBackgroundPermission + + if (!hasLocationPermission) // Make sure we have location permission (prerequisite) + myActivity.requestLocationPermission() + if (hasLocationPermission && !hasBackgroundPermission) MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.background_required) .setMessage(R.string.why_background_required) .setNeutralButton(R.string.cancel) { _, _ -> - debug("Decided not to report a bug") + debug("User denied background permission") } .setPositiveButton(getString(R.string.accept)) { _, _ -> myActivity.requestBackgroundPermission() From c53179c09065a0917c49747cecdf98fe3eb8d4bf Mon Sep 17 00:00:00 2001 From: andrekir Date: Wed, 15 Dec 2021 12:02:01 -0300 Subject: [PATCH 5/5] add hasGpsSensor check --- .../main/java/com/geeksville/mesh/ui/SettingsFragment.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index 42a13e753..45e651d06 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -11,6 +11,7 @@ import android.companion.AssociationRequest import android.companion.BluetoothDeviceFilter import android.companion.CompanionDeviceManager import android.content.* +import android.content.pm.PackageManager import android.hardware.usb.UsbDevice import android.hardware.usb.UsbManager import android.os.Bundle @@ -908,8 +909,12 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { * If the user has not turned on location access throw up a toast warning */ private fun checkLocationEnabled() { + + fun hasGpsSensor(): Boolean = + myActivity.packageManager.hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS) + // If they don't have google play FIXME for now we don't check for location access - if (isGooglePlayAvailable(requireContext())) { + if (hasGpsSensor() && isGooglePlayAvailable(requireContext())) { // We do this painful process because LocationManager.isEnabled is only SDK28 or latet val builder = LocationSettingsRequest.Builder() builder.setNeedBle(true)