From 564fc408740440ffd7043cee53c5a032558eb12b Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Mon, 26 Nov 2018 10:23:01 -0800 Subject: [PATCH 01/10] Bump tools --- app/build.gradle | 2 +- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 240904ce..3f6c6e5d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ sonarqube { android { compileSdkVersion 27 - buildToolsVersion '27.0.2' + buildToolsVersion '28.0.3' defaultConfig { minSdkVersion 14 diff --git a/build.gradle b/build.gradle index 197b6f29..d568a72b 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.2.1' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.4' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d47e3bac..9e2e115c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Oct 17 17:47:38 EDT 2017 +#Mon Nov 26 10:17:51 PST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip From 669a38cc828bfa81e73d462ed368b1fd595365f0 Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Mon, 26 Nov 2018 11:30:36 -0800 Subject: [PATCH 02/10] Bump deps --- .travis.yml | 2 +- app/build.gradle | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 52c7ec63..81864d7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ jdk: android: components: - tools - - build-tools-27.0.2 + - build-tools-28.0.3 - android-27 - extra-android-m2repository diff --git a/app/build.gradle b/app/build.gradle index 3f6c6e5d..517c28d3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -65,9 +65,9 @@ android { } dependencies { - compile 'com.android.support:support-v4:27.0.2' - compile 'com.android.support:appcompat-v7:27.0.2' - compile 'com.squareup.okhttp3:okhttp:3.9.1' + compile 'com.android.support:support-v4:27.1.1' + compile 'com.android.support:appcompat-v7:27.1.1' + compile 'com.squareup.okhttp3:okhttp:3.10.0' compile 'jcifs:jcifs:1.3.17' compile 'dnsjava:dnsjava:2.1.7' //This does absolutely nothing From 8a6bb4739b5fa6eeb7fa0e30cd866c7fe652a489 Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Mon, 14 Jan 2019 23:44:26 -0800 Subject: [PATCH 03/10] Some cleanup and regex fixes, bump gradle to newer version --- .../com/aaronjwood/portauthority/activity/HostActivity.java | 2 +- .../com/aaronjwood/portauthority/activity/MainActivity.java | 2 +- .../java/com/aaronjwood/portauthority/async/WolAsyncTask.java | 2 +- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/aaronjwood/portauthority/activity/HostActivity.java b/app/src/main/java/com/aaronjwood/portauthority/activity/HostActivity.java index be9f7b44..cb9efd83 100644 --- a/app/src/main/java/com/aaronjwood/portauthority/activity/HostActivity.java +++ b/app/src/main/java/com/aaronjwood/portauthority/activity/HostActivity.java @@ -40,7 +40,7 @@ public abstract class HostActivity extends AppCompatActivity implements HostAsyn protected int layout; protected ArrayAdapter adapter; protected ListView portList; - protected final List ports = Collections.synchronizedList(new ArrayList()); + protected final List ports = Collections.synchronizedList(new ArrayList<>()); protected ProgressDialog scanProgressDialog; protected Dialog portRangeDialog; protected Handler handler; diff --git a/app/src/main/java/com/aaronjwood/portauthority/activity/MainActivity.java b/app/src/main/java/com/aaronjwood/portauthority/activity/MainActivity.java index 5283ebc1..78013f15 100644 --- a/app/src/main/java/com/aaronjwood/portauthority/activity/MainActivity.java +++ b/app/src/main/java/com/aaronjwood/portauthority/activity/MainActivity.java @@ -78,7 +78,7 @@ public final class MainActivity extends AppCompatActivity implements MainAsyncRe private Handler scanHandler; private IntentFilter intentFilter = new IntentFilter(); private HostAdapter hostAdapter; - private List hosts = Collections.synchronizedList(new ArrayList()); + private List hosts = Collections.synchronizedList(new ArrayList<>()); private Database db; private DownloadAsyncTask ouiTask; private DownloadAsyncTask portTask; diff --git a/app/src/main/java/com/aaronjwood/portauthority/async/WolAsyncTask.java b/app/src/main/java/com/aaronjwood/portauthority/async/WolAsyncTask.java index 2e5e34de..ad24b639 100644 --- a/app/src/main/java/com/aaronjwood/portauthority/async/WolAsyncTask.java +++ b/app/src/main/java/com/aaronjwood/portauthority/async/WolAsyncTask.java @@ -21,7 +21,7 @@ protected Void doInBackground(String... params) { String ip = params[1]; byte[] macBytes = new byte[6]; - String[] macHex = mac.split("(:|-)"); + String[] macHex = mac.split("([:\\-])"); for (int i = 0; i < 6; i++) { macBytes[i] = (byte) Integer.parseInt(macHex[i], 16); } diff --git a/build.gradle b/build.gradle index d568a72b..e8a837e8 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.3.0' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.4' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9e2e115c..7f8c65e6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Nov 26 10:17:51 PST 2018 +#Mon Jan 14 23:33:13 PST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip From 1699fdcfce1907b456fde74dd0b4936f122040da Mon Sep 17 00:00:00 2001 From: PanderMusubi Date: Thu, 26 Sep 2019 17:55:15 +0200 Subject: [PATCH 04/10] Added Dutch translation --- app/src/main/res/values-nl/strings.xml | 59 ++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 app/src/main/res/values-nl/strings.xml diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml new file mode 100644 index 00000000..6f7a6111 --- /dev/null +++ b/app/src/main/res/values-nl/strings.xml @@ -0,0 +1,59 @@ + + + + Port Authority + Instellingen + MAC + Leverancier + LAN IP + WAN IP + Ophalen… + Signaal/Snelheid + Ontdek hosts + SSID + BSSID + Scan welbekende poorten + Scan poortbereik + Reset poortbereik + Open poorten + Beginpoort + Eindpoort + Wifi is niet ingeschakeld + Geen wifiverbinding + URL/IP + WAARSCHUWING + Domeinnaam + DNS-lookup + Wakker maken + Wakker aan het maken %1$s… + IP-adres + Ophalen van DNS-records… + Voer een domein in en selecteer een recordtype + Je bent niet verbonden met een lokaal netwerk + Je bent niet verbonden met een wifinetwerk! + %1$ddBm/%2$dMbps + Scannen naar hosts + %1$d hosts in je subnet + Sorteer + Op hostnaam + Op leverancier + Kopieer hostnaam + Kopieer IP + Kopieer MAC + Opvragen MAC-leverancier is mislukt + Openen database is mislukt + Gegevens aan het downloaden + Opgraven van aantal hosts in dit subnet is mislukt + Opvragen signaalsterkte is mislukt + Opvragen verbindingssnelheid is mislukt + Opvragen SSID is mislukt + Opvragen BSSID is mislukt + Opvragen WifiManager van dit apparaat is mislukt + Geen wifi-interface gevonden + + Houd er rekening mee dat het uitvoeren van poortscans tegen openbare servers normaal gesproken als kwaadaardig wordt beschouwd. + Bovendien zal het uitvoeren van dit soort scans over het netwerk van je provider in plaats van je eigen wifiverbinding trager verlopen en soms onnauwkeurige resultaten opleveren als gevolg van traffic shaping. + Je provider kan ook het verkeer dat door deze scan wordt gegenereerd als kwaadaardig beschouwen. + + + From e6210dd951d501aa5e89bfbca41dc0c1f464afef Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Wed, 1 Jan 2020 22:20:27 -0800 Subject: [PATCH 05/10] Bump deps and target SDK --- app/build.gradle | 9 ++++----- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 517c28d3..865d94dd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,12 +15,12 @@ sonarqube { } android { - compileSdkVersion 27 + compileSdkVersion 29 buildToolsVersion '28.0.3' defaultConfig { minSdkVersion 14 - targetSdkVersion 27 + targetSdkVersion 29 versionCode 55 versionName "2.2.8" applicationId "com.aaronjwood.portauthority" @@ -65,12 +65,11 @@ android { } dependencies { - compile 'com.android.support:support-v4:27.1.1' - compile 'com.android.support:appcompat-v7:27.1.1' + compile 'com.android.support:support-v4:28.0.0' + compile 'com.android.support:appcompat-v7:28.0.0' compile 'com.squareup.okhttp3:okhttp:3.10.0' compile 'jcifs:jcifs:1.3.17' compile 'dnsjava:dnsjava:2.1.7' - //This does absolutely nothing releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4' debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4' testCompile 'junit:junit:4.12' diff --git a/build.gradle b/build.gradle index e8a837e8..87039655 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.3.0' + classpath 'com.android.tools.build:gradle:3.5.3' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.4' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7f8c65e6..e52b72fa 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Jan 14 23:33:13 PST 2019 +#Wed Jan 01 19:13:52 PST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip From e1bcdaa25dda9529cc8d567817e83279967cabb1 Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Wed, 1 Jan 2020 22:20:34 -0800 Subject: [PATCH 06/10] Apply workaround for getting ARP entries for Android 10+ --- .../async/ScanHostsAsyncTask.java | 177 ++++++++++++------ 1 file changed, 124 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/com/aaronjwood/portauthority/async/ScanHostsAsyncTask.java b/app/src/main/java/com/aaronjwood/portauthority/async/ScanHostsAsyncTask.java index f648a11b..a348e65b 100644 --- a/app/src/main/java/com/aaronjwood/portauthority/async/ScanHostsAsyncTask.java +++ b/app/src/main/java/com/aaronjwood/portauthority/async/ScanHostsAsyncTask.java @@ -1,6 +1,8 @@ package com.aaronjwood.portauthority.async; import android.os.AsyncTask; +import android.os.Build; +import android.util.Pair; import com.aaronjwood.portauthority.db.Database; import com.aaronjwood.portauthority.network.Host; @@ -16,6 +18,8 @@ import java.lang.ref.WeakReference; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -27,6 +31,9 @@ public class ScanHostsAsyncTask extends AsyncTask { private final WeakReference delegate; private Database db; private static final String ARP_TABLE = "/proc/net/arp"; + private static final String IP_CMD = "ip neighbor"; + private static final String NEIGHBOR_INCOMPLETE = "INCOMPLETE"; + private static final String NEIGHBOR_FAILED = "FAILED"; private static final String ARP_INCOMPLETE = "0x0"; private static final String ARP_INACTIVE = "00:00:00:00:00:00"; private static final int NETBIOS_FILE_SERVER = 0x20; @@ -51,14 +58,38 @@ protected Void doInBackground(Integer... params) { int ipv4 = params[0]; int cidr = params[1]; int timeout = params[2]; - MainAsyncResponse activity = delegate.get(); - File file = new File(ARP_TABLE); - if (!file.exists() || !file.canRead()) { - activity.processFinish(new FileNotFoundException("Unable to access device ARP table")); - activity.processFinish(true); - return null; + // Android 10+ doesn't let us access the ARP table. + // Do an early check to see if we can get what we need from the system. + // https://developer.android.com/about/versions/10/privacy/changes#proc-net-filesystem + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + try { + Process ipProc = Runtime.getRuntime().exec(IP_CMD); + ipProc.waitFor(); + if (ipProc.exitValue() != 0) { + activity.processFinish(new IOException("Unable to access ARP entries")); + activity.processFinish(true); + + return null; + } + } catch (IOException | InterruptedException e) { + activity.processFinish(new IOException("Unable to parse ARP entries")); + activity.processFinish(true); + } + } else { + File file = new File(ARP_TABLE); + if (!file.exists()) { + activity.processFinish(new FileNotFoundException("Unable to find ARP table")); + activity.processFinish(true); + + return null; + } + + if (!file.canRead()) { + activity.processFinish(new IOException("Unable to read ARP table")); + activity.processFinish(true); + } } ExecutorService executor = Executors.newCachedThreadPool(); @@ -107,63 +138,103 @@ protected final void onProgressUpdate(Void... params) { final MainAsyncResponse activity = delegate.get(); ExecutorService executor = Executors.newCachedThreadPool(); final AtomicInteger numHosts = new AtomicInteger(0); + List> pairs = new ArrayList<>(); try { - reader = new BufferedReader(new InputStreamReader(new FileInputStream(ARP_TABLE), "UTF-8")); - reader.readLine(); // Skip header. - String line; - - while ((line = reader.readLine()) != null) { - String[] arpLine = line.split("\\s+"); - - final String ip = arpLine[0]; - final String flag = arpLine[2]; - final String macAddress = arpLine[3]; - - if (!ARP_INCOMPLETE.equals(flag) && !ARP_INACTIVE.equals(macAddress)) { - numHosts.incrementAndGet(); - executor.execute(new Runnable() { - - @Override - public void run() { - Host host; - try { - host = new Host(ip, macAddress, db); - } catch (IOException e) { - host = new Host(ip, macAddress); - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + Process ipProc = Runtime.getRuntime().exec(IP_CMD); + ipProc.waitFor(); + if (ipProc.exitValue() != 0) { + throw new Exception("Unable to access ARP entries"); + } - MainAsyncResponse activity = delegate.get(); - try { - InetAddress add = InetAddress.getByName(ip); - String hostname = add.getCanonicalHostName(); - host.setHostname(hostname); + reader = new BufferedReader(new InputStreamReader(ipProc.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + String[] neighborLine = line.split("\\s+"); - if (activity != null) { - activity.processFinish(host, numHosts); - } - } catch (UnknownHostException e) { - numHosts.decrementAndGet(); - activity.processFinish(e); - return; + // We don't have a validated ARP entry for this case. + if (neighborLine.length <= 4) { + continue; + } + + String ip = neighborLine[0]; + InetAddress addr = InetAddress.getByName(ip); + if (addr.isLinkLocalAddress() || addr.isLoopbackAddress()) { + continue; + } + + String macAddress = neighborLine[4]; + String state = neighborLine[neighborLine.length - 1]; + + // Determine if the ARP entry is valid. + // https://github.com/sivasankariit/iproute2/blob/master/ip/ipneigh.c + if (!NEIGHBOR_FAILED.equals(state) && !NEIGHBOR_INCOMPLETE.equals(state)) { + pairs.add(new Pair<>(ip, macAddress)); + } + } + } else { + reader = new BufferedReader(new InputStreamReader(new FileInputStream(ARP_TABLE), "UTF-8")); + reader.readLine(); // Skip header. + String line; + + while ((line = reader.readLine()) != null) { + String[] arpLine = line.split("\\s+"); + String ip = arpLine[0]; + String flag = arpLine[2]; + String macAddress = arpLine[3]; + + if (!ARP_INCOMPLETE.equals(flag) && !ARP_INACTIVE.equals(macAddress)) { + pairs.add(new Pair<>(ip, macAddress)); + } + } + } + + numHosts.addAndGet(pairs.size()); + for (Pair pair : pairs) { + String ip = pair.first; + String macAddress = pair.second; + executor.execute(new Runnable() { + + @Override + public void run() { + Host host; + try { + host = new Host(ip, macAddress, db); + } catch (IOException e) { + host = new Host(ip, macAddress); + } + + MainAsyncResponse activity = delegate.get(); + try { + InetAddress add = InetAddress.getByName(ip); + String hostname = add.getCanonicalHostName(); + host.setHostname(hostname); + + if (activity != null) { + activity.processFinish(host, numHosts); } + } catch (UnknownHostException e) { + numHosts.decrementAndGet(); + activity.processFinish(e); + return; + } - try { - NbtAddress[] netbios = NbtAddress.getAllByAddress(ip); - for (NbtAddress addr : netbios) { - if (addr.getNameType() == NETBIOS_FILE_SERVER) { - host.setHostname(addr.getHostName()); - return; - } + try { + NbtAddress[] netbios = NbtAddress.getAllByAddress(ip); + for (NbtAddress addr : netbios) { + if (addr.getNameType() == NETBIOS_FILE_SERVER) { + host.setHostname(addr.getHostName()); + return; } - } catch (UnknownHostException e) { - // It's common that many discovered hosts won't have a NetBIOS entry. } + } catch (UnknownHostException e) { + // It's common that many discovered hosts won't have a NetBIOS entry. } - }); - } + } + }); } - } catch (IOException e) { + } catch (Exception e) { if (activity != null) { activity.processFinish(e); } From 5da6c237e22d67b43e176ae86f013d3ba1fc25a2 Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Wed, 1 Jan 2020 22:43:05 -0800 Subject: [PATCH 07/10] Bump SDK in for CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 81864d7d..0ac44119 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ android: components: - tools - build-tools-28.0.3 - - android-27 + - android-29 - extra-android-m2repository env: From 43bc9f207e0ccb40b085fd7080b98533ea7a4181 Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Wed, 1 Jan 2020 23:26:24 -0800 Subject: [PATCH 08/10] Support reading the SSID on Android 8+ --- app/src/main/AndroidManifest.xml | 1 + .../portauthority/activity/MainActivity.java | 36 +++++++++++++++++-- .../portauthority/utils/UserPreference.java | 17 +++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6f79851c..4b1238f9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ + = Build.VERSION_CODES.O) { + if (!UserPreference.getLocationPermDiag(context)) { + new AlertDialog.Builder(this, R.style.DialogTheme).setTitle("SSID Access") + .setMessage("Android 8+ now requires location permissions to read the SSID. " + + "If this is not something you're comfortable with just deny the request and go without the functionality.") + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + dialogInterface.dismiss(); + UserPreference.saveLocationPermDiag(context); + } + }) + .setIcon(android.R.drawable.ic_dialog_alert).show().setCanceledOnTouchOutside(false); + } + + if (ContextCompat.checkSelfPermission(context, + Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, + COARSE_LOCATION_REQUEST); + } + } + intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); } @@ -455,7 +485,7 @@ public void run() { Errors.showError(context, resources.getString(R.string.failedSignal)); return; } - + signalStrength.setText(String.format(resources.getString(R.string.signalLink), signal, speed)); signalHandler.postDelayed(this, TIMER_INTERVAL); } diff --git a/app/src/main/java/com/aaronjwood/portauthority/utils/UserPreference.java b/app/src/main/java/com/aaronjwood/portauthority/utils/UserPreference.java index e9f7a0b8..44dfdfd8 100644 --- a/app/src/main/java/com/aaronjwood/portauthority/utils/UserPreference.java +++ b/app/src/main/java/com/aaronjwood/portauthority/utils/UserPreference.java @@ -22,6 +22,7 @@ public class UserPreference { private static final String LAN_SOCKET_TIMEOUT = "lanTimeout"; private static final String WAN_SOCKET_TIMEOUT = "wanTimeout"; private static final String HOST_SOCKET_TIMEOUT = "hostTimeout"; + private static final String LOCATION_PERM_DIAG = "locationPermDiag"; /** * Saves the last used host address for later use. @@ -37,6 +38,22 @@ public static void saveLastUsedHostAddress(@NonNull Context context, @Nullable S } } + /** + * Saves the state of the location permission dialog. + */ + public static void saveLocationPermDiag(@NonNull Context context) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + preferences.edit().putBoolean(LOCATION_PERM_DIAG, true).apply(); + } + + /** + * Saves the state of the location permission dialog. + */ + public static boolean getLocationPermDiag(@NonNull Context context) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + return preferences.getBoolean(LOCATION_PERM_DIAG, false); + } + /** * Gets the last used host address or an empty string if there isn't one. */ From 7e424d56ef4f5c4c1f20e8915c1cddec7ccc61d4 Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Wed, 1 Jan 2020 23:35:40 -0800 Subject: [PATCH 09/10] Notify the user first about why we're requesting location permissions --- .../portauthority/activity/MainActivity.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/aaronjwood/portauthority/activity/MainActivity.java b/app/src/main/java/com/aaronjwood/portauthority/activity/MainActivity.java index 0686bb0a..c61915c0 100644 --- a/app/src/main/java/com/aaronjwood/portauthority/activity/MainActivity.java +++ b/app/src/main/java/com/aaronjwood/portauthority/activity/MainActivity.java @@ -1,6 +1,7 @@ package com.aaronjwood.portauthority.activity; import android.Manifest; +import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.BroadcastReceiver; @@ -143,7 +144,8 @@ protected void onCreate(Bundle savedInstanceState) { // Android 8+ now require this permission to read the SSID. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (!UserPreference.getLocationPermDiag(context)) { - new AlertDialog.Builder(this, R.style.DialogTheme).setTitle("SSID Access") + Activity activity = this; + new AlertDialog.Builder(activity, R.style.DialogTheme).setTitle("SSID Access") .setMessage("Android 8+ now requires location permissions to read the SSID. " + "If this is not something you're comfortable with just deny the request and go without the functionality.") .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @@ -151,16 +153,15 @@ protected void onCreate(Bundle savedInstanceState) { public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); UserPreference.saveLocationPermDiag(context); + if (ContextCompat.checkSelfPermission(context, + Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, + COARSE_LOCATION_REQUEST); + } } }) .setIcon(android.R.drawable.ic_dialog_alert).show().setCanceledOnTouchOutside(false); } - - if (ContextCompat.checkSelfPermission(context, - Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, - COARSE_LOCATION_REQUEST); - } } intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); From ae1c33f8183c18db539f86be9dbc6b686e66c003 Mon Sep 17 00:00:00 2001 From: Aaron Wood Date: Thu, 2 Jan 2020 00:17:21 -0800 Subject: [PATCH 10/10] Bump versions --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 865d94dd..f8375ead 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,8 +21,8 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 29 - versionCode 55 - versionName "2.2.8" + versionCode 56 + versionName "2.2.10" applicationId "com.aaronjwood.portauthority" setProperty("archivesBaseName", "PortAuthority-$versionName") }