diff --git a/app/src/main/java/com/quran/labs/androidquran/QuranDataActivity.kt b/app/src/main/java/com/quran/labs/androidquran/QuranDataActivity.kt
index 71d0d2c042..e84357c97c 100644
--- a/app/src/main/java/com/quran/labs/androidquran/QuranDataActivity.kt
+++ b/app/src/main/java/com/quran/labs/androidquran/QuranDataActivity.kt
@@ -194,8 +194,8 @@ class QuranDataActivity : Activity(), SimpleDownloadListener, OnRequestPermissio
runListView()
}
}
- } else if (needsPermission && Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
- // we need permission (i.e. are writing to the sdcard) on Android 10 (Q) and above
+ } else if (needsPermission && Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
+ // we need permission (i.e. are writing to the sdcard) on Android 11 and above
// we should migrate because when we are required to target Android 11 next year
// in sha' Allah, we may lose legacy permissions.
//
diff --git a/app/src/main/java/com/quran/labs/androidquran/ui/fragment/QuranAdvancedSettingsFragment.java b/app/src/main/java/com/quran/labs/androidquran/ui/fragment/QuranAdvancedSettingsFragment.java
index 0d6f2238aa..8b49858c67 100644
--- a/app/src/main/java/com/quran/labs/androidquran/ui/fragment/QuranAdvancedSettingsFragment.java
+++ b/app/src/main/java/com/quran/labs/androidquran/ui/fragment/QuranAdvancedSettingsFragment.java
@@ -5,6 +5,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
+import android.location.Location;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@@ -14,6 +15,7 @@
import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
import com.quran.labs.androidquran.BuildConfig;
import com.quran.labs.androidquran.QuranAdvancedPreferenceActivity;
import com.quran.labs.androidquran.QuranApplication;
@@ -270,15 +272,7 @@ private void loadStorageOptions(Context context) {
String current = settings.getAppCustomLocation();
if (appSize < destStorage.getFreeSpace()) {
if (current == null || !current.equals(newLocation)) {
- if (destStorage.doesRequirePermission()) {
- if (!PermissionUtil.haveWriteExternalStoragePermission(context1)) {
- requestExternalStoragePermission(newLocation);
- return false;
- }
-
- // we have the permission, so fall through and handle the move
- }
- handleMove(newLocation);
+ handleMove(newLocation, destStorage);
}
} else {
ToastCompat.makeText(context1,
@@ -305,36 +299,76 @@ private void requestExternalStoragePermission(String newLocation) {
}
- private void handleMove(String newLocation) {
+ private void handleMove(String newLocation, StorageUtils.Storage storageLocation) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT ||
newLocation.equals(internalSdcardLocation)) {
- moveFiles(newLocation);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ // on Android Q (not really "above" since we don't show the option above),
+ // warn if the person tries to use the /sdcard path.
+ showScopedStorageConfirmation(newLocation, storageLocation);
+ } else {
+ // otherwise just copy
+ moveFiles(newLocation, storageLocation);
+ }
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ // don't warn for using Android app directories on Q and above
+ moveFiles(newLocation, storageLocation);
} else {
- showKitKatConfirmation(newLocation);
+ // but on older versions, warn
+ showKitKatConfirmation(newLocation, storageLocation);
}
}
- private void showKitKatConfirmation(final String newLocation) {
+ private void showScopedStorageConfirmation(final String newLocation,
+ final StorageUtils.Storage storageLocation) {
+ showConfirmation(newLocation, storageLocation, R.string.scoped_storage_message);
+ }
+
+ private void showKitKatConfirmation(final String newLocation,
+ final StorageUtils.Storage storageLocation) {
+ showConfirmation(newLocation, storageLocation, R.string.kitkat_external_message);
+ }
+
+ private void showConfirmation(final String newLocation,
+ final StorageUtils.Storage storageLocation,
+ @StringRes int message) {
final Context context = getActivity();
- final AlertDialog.Builder b = new AlertDialog.Builder(context)
- .setTitle(R.string.warning)
- .setMessage(R.string.kitkat_external_message)
- .setPositiveButton(R.string.dialog_ok, (currentDialog, which) -> {
- moveFiles(newLocation);
- currentDialog.dismiss();
- QuranAdvancedSettingsFragment.this.dialog = null;
- })
- .setNegativeButton(R.string.cancel, (currentDialog, which) -> {
- currentDialog.dismiss();
- QuranAdvancedSettingsFragment.this.dialog = null;
- });
- dialog = b.create();
- dialog.show();
+ if (context != null) {
+ final AlertDialog.Builder b = new AlertDialog.Builder(context)
+ .setTitle(R.string.warning)
+ .setMessage(message)
+ .setPositiveButton(R.string.dialog_ok, (currentDialog, which) -> {
+ moveFiles(newLocation, storageLocation);
+ currentDialog.dismiss();
+ QuranAdvancedSettingsFragment.this.dialog = null;
+ })
+ .setNegativeButton(R.string.cancel, (currentDialog, which) -> {
+ currentDialog.dismiss();
+ QuranAdvancedSettingsFragment.this.dialog = null;
+ });
+ dialog = b.create();
+ dialog.show();
+ }
+ }
+
+ private void moveFiles(String newLocation, StorageUtils.Storage storageLocation) {
+ final Context context = getContext();
+ if (context != null) {
+ if (storageLocation.doesRequirePermission() &&
+ !PermissionUtil.haveWriteExternalStoragePermission(context)) {
+ requestExternalStoragePermission(newLocation);
+ } else {
+ moveFiles(newLocation);
+ }
+ }
}
public void moveFiles(String newLocation) {
- moveFilesAsyncTask = new MoveFilesAsyncTask(getActivity(), newLocation, quranFileUtils);
- moveFilesAsyncTask.execute();
+ final Context context = getContext();
+ if (context != null) {
+ moveFilesAsyncTask = new MoveFilesAsyncTask(context, newLocation, quranFileUtils);
+ moveFilesAsyncTask.execute();
+ }
}
@Override
diff --git a/app/src/main/java/com/quran/labs/androidquran/util/StorageUtils.java b/app/src/main/java/com/quran/labs/androidquran/util/StorageUtils.java
index 49d7564fb2..b484e92bce 100644
--- a/app/src/main/java/com/quran/labs/androidquran/util/StorageUtils.java
+++ b/app/src/main/java/com/quran/labs/androidquran/util/StorageUtils.java
@@ -70,9 +70,12 @@ a. not see any item (if there's only one entry returned by getExternalFilesDirs,
}
int number = 1;
- result.add(new Storage(context.getString(typeId, number),
- Environment.getExternalStorageDirectory().getAbsolutePath(),
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.M));
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
+ // don't show the /sdcard option for people on Android 11
+ result.add(new Storage(context.getString(typeId, number),
+ Environment.getExternalStorageDirectory().getAbsolutePath(),
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.M));
+ }
for (File mountPoint : mountPoints) {
result.add(new Storage(context.getString(typeId, number++),
mountPoint.getAbsolutePath()));
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 07979ff386..63ce80576d 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -332,7 +332,7 @@
الترجمات لعدد من اللغات
تنزيل
ترجمات لبعض اللغات
- الرجاء الانتظار...
+ الرجاء الانتظار…
صدرت البيانات إلى %1$s
حذف الملف الصوتي؟
سيتم حذف الملف الصوتي ل%1$s. متأكد؟
@@ -343,7 +343,10 @@
ملف النسخة الاحتياطية تالف (أو فشلت قراءة النسخة الاحتياطية)
فشلت قراءة ملف النسخة الاحتياطية بسبب فقدان الإذن
رجاء امنح الإذن في الإعدادات
- نور وهداية (Noorhidayat)
+ نور هداية (Noorhidayat)
بسبب قيود الأندرويد، إذا اخترت تخزين ملفات قرآن على الذاكرة الخارجية ثم مسحت التطبيق أو بيانات قرآن أندرويد، ستحذف جميع صفحات المصحف والصوت ولابد من تحميلها مجددا. هل ترغب في استعمال الذاكرة الخارجية؟
+
+ بسبب تغييرات في الاندرويد، إستخدام مكان غير مكان التطبيق قد يسبب في عدم تمكن التطبيق من الوصول للملفات في الاصدارات المستقبلية للاندرويد. هل ترغب في تكملة نقل البيانات ؟
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c5d76cd1d0..45fe2ce322 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -247,6 +247,9 @@
data on your external SD card and later uninstall or clear data for Quran Android, all Quran
Android pages and audio will be deleted and you will have to download them again. Are you
sure you want to use the external SD card?
+ Due to Android changes to increase user privacy, copying
+ files outside of the app directories might stop Quran from accessing its data in future versions
+ of Android. Are you sure you\'d like to use this path?
Please grant permission in application settings