From 57b18b98f17076a5db04eef91a450ad8fb681182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 21 Sep 2023 11:45:38 +0200 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=8C=AD=20swap:=20external=20storage?= =?UTF-8?q?=20support=20for=20sdk=2030+?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fdroid/views/main/NearbyViewBinder.java | 72 ++++++++++++++----- app/src/main/AndroidManifest.xml | 1 + .../fdroid/views/main/MainActivity.java | 2 + app/src/main/res/values/strings.xml | 4 +- 4 files changed, 60 insertions(+), 19 deletions(-) diff --git a/app/src/full/java/org/fdroid/fdroid/views/main/NearbyViewBinder.java b/app/src/full/java/org/fdroid/fdroid/views/main/NearbyViewBinder.java index e31bf809f..cf7245ea5 100644 --- a/app/src/full/java/org/fdroid/fdroid/views/main/NearbyViewBinder.java +++ b/app/src/full/java/org/fdroid/fdroid/views/main/NearbyViewBinder.java @@ -13,6 +13,7 @@ import android.os.Environment; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.provider.DocumentsContract; +import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.view.View; @@ -73,8 +74,6 @@ public class NearbyViewBinder { subtext.setText(activity.getString(R.string.nearby_splash__both_parties_need_fdroid, activity.getString(R.string.app_name))); - ImageView nearbySplash = swapView.findViewById(R.id.image); - Button startButton = swapView.findViewById(R.id.find_people_button); startButton.setOnClickListener(v -> { final String coarseLocation = Manifest.permission.ACCESS_COARSE_LOCATION; @@ -86,6 +85,23 @@ public class NearbyViewBinder { } }); + updateExternalStorageViews(activity); + updateUsbOtg(activity); + } + + public static void updateExternalStorageViews(final AppCompatActivity activity) { + if (swapView == null || activity == null) { + return; + } + + ImageView nearbySplash = swapView.findViewById(R.id.image); + TextView explainer = swapView.findViewById(R.id.read_external_storage_text); + Button button = swapView.findViewById(R.id.request_read_external_storage_button); + + if (nearbySplash == null || explainer == null || button == null) { + return; + } + File[] dirs = activity.getExternalFilesDirs(""); if (dirs != null) { for (File dir : dirs) { @@ -102,28 +118,48 @@ public class NearbyViewBinder { } final String readExternalStorage = Manifest.permission.READ_EXTERNAL_STORAGE; + if (externalStorage != null) { nearbySplash.setVisibility(View.GONE); - TextView readExternalStorageText = swapView.findViewById(R.id.read_external_storage_text); - readExternalStorageText.setVisibility(View.VISIBLE); - Button requestReadExternalStorage = swapView.findViewById(R.id.request_read_external_storage_button); - requestReadExternalStorage.setVisibility(View.VISIBLE); - requestReadExternalStorage.setOnClickListener(v -> { - if ((externalStorage == null || !externalStorage.canRead()) - && PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(activity, - readExternalStorage)) { - ActivityCompat.requestPermissions(activity, new String[]{readExternalStorage}, - MainActivity.REQUEST_STORAGE_PERMISSIONS); + explainer.setVisibility(View.VISIBLE); + button.setVisibility(View.VISIBLE); + if (Build.VERSION.SDK_INT >= 30) { + if (!Environment.isExternalStorageManager()) { + // we don't have permission to access files yet, so ask for it + explainer.setText(R.string.nearby_splach__external_storage_permission_explainer); + button.setText(R.string.nearby_splace__external_storage_permission_button); + button.setOnClickListener(view -> activity.startActivity( + new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, + Uri.parse(String.format("package:%s", + activity.getPackageName()))))); } else { - Toast.makeText(activity, - activity.getString(R.string.scan_removable_storage_toast, externalStorage), - Toast.LENGTH_SHORT).show(); - SDCardScannerService.scan(activity); + explainer.setText(R.string.nearby_splash__read_external_storage); + button.setText(R.string.nearby_splash__request_permission); + button.setOnClickListener(view -> scanExternalStorageNow(activity)); } - }); + } else { + if ((externalStorage == null || !externalStorage.canRead()) + && PackageManager.PERMISSION_GRANTED + != ContextCompat.checkSelfPermission(activity, readExternalStorage)) { + explainer.setText(R.string.nearby_splach__external_storage_permission_explainer); + button.setText(R.string.nearby_splace__external_storage_permission_button); + button.setOnClickListener(v -> { + ActivityCompat.requestPermissions(activity, new String[]{readExternalStorage}, + MainActivity.REQUEST_STORAGE_PERMISSIONS); + }); + } else { + explainer.setText(R.string.nearby_splash__read_external_storage); + button.setText(R.string.nearby_splash__request_permission); + button.setOnClickListener(view -> scanExternalStorageNow(activity)); + } + } } + } - updateUsbOtg(activity); + private static void scanExternalStorageNow(final AppCompatActivity activity) { + Toast.makeText(activity, activity.getString(R.string.scan_removable_storage_toast, externalStorage), + Toast.LENGTH_SHORT).show(); + SDCardScannerService.scan(activity); } public static void updateUsbOtg(final Context context) { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f436c2d16..f6f38e29d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -55,6 +55,7 @@ + Search SD Card for repos and mirrors. Search USB OTG for repos and mirrors. - Try it + Search now + F-Droid can search for repos and mirrors on your SD Card, but needs your permission to do so. + Try it Touch to swap From 4fe154351bf0d7a54784b2226b2e1d72a828f25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 21 Sep 2023 12:58:34 +0200 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=91=B4=20swap:=20add=20stub=20for=20s?= =?UTF-8?q?tatic=20notification=20passing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we're using static methods (with static references to views) a (IMHO likely error prone) hack to pass events from MainActivity to NearbyViewBinder we have high coupling betweens those two classes. In nearby buildflavor spaw is removed. So we need stubs because of coupling. --- .../java/org/fdroid/fdroid/views/main/NearbyViewBinder.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/basic/java/org/fdroid/fdroid/views/main/NearbyViewBinder.java b/app/src/basic/java/org/fdroid/fdroid/views/main/NearbyViewBinder.java index 0d2329980..8446e2255 100644 --- a/app/src/basic/java/org/fdroid/fdroid/views/main/NearbyViewBinder.java +++ b/app/src/basic/java/org/fdroid/fdroid/views/main/NearbyViewBinder.java @@ -6,4 +6,6 @@ class NearbyViewBinder { static void updateUsbOtg(Context context) { throw new IllegalStateException("unimplemented"); } + static void updateExternalStorageViews(Context context) { + } } From 210d30a8a497b0a919e8e5532d1442550f02bdb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Thu, 21 Sep 2023 14:12:45 +0200 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=A7=A9=20swap:=20requestLegacyExterna?= =?UTF-8?q?lStorage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Android SDK level 29 we need this exception to keep our code for scanning for repositories on scanning SD cards working. This exception is obsolete for sdk 30 and above. --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f6f38e29d..6395e7747 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -72,6 +72,7 @@ android:icon="@drawable/ic_launcher" android:label="${applicationLabel}" android:networkSecurityConfig="@xml/network_security_config" + android:requestLegacyExternalStorage="true" android:supportsRtl="true" android:theme="@style/Theme.App">