mirror of
https://github.com/nix-community/nix-on-droid-app.git
synced 2025-11-30 14:11:07 +01:00
Changed|Fixed: Always request MANAGE_EXTERNAL_STORAGE if on Android >= 11 when running termux-setup-storage`
Requesting `MANAGE_EXTERNAL_STORAGE` should additionally grant access to unreliable/removable volumes like USB OTG devices under the `/mnt/media_rw/XXXX-XXXX` paths on `Android >= 12`, so request that if possible. Check https://github.com/termux/termux-app/issues/71#issuecomment-1869222653 for more info. Fixes issue on Android `14`, where using `targetSdkVersion=28`, that requests the legacy `WRITE_EXTERNAL_STORAGE` will actually request the `photos, music, video, and other files` permissions (`READ_MEDIA_AUDIO`/`READ_MEDIA_IMAGES`/`READ_MEDIA_VIDEO`) and apparently access to full external storage `/sdcard` is not available for some users, maybe because `READ_EXTERNAL_STORAGE` and `WRITE_EXTERNAL_STORAGE` permissions are not granted for those device automatically in addition to `READ_MEDIA_*` permission. The issue is not reproducible on Android `13-15` avd. To solve this, we request the singular `MANAGE_EXTERNAL_STORAGE` permission instead so that full access is always available. Related: https://github.com/termux/termux-app/issues/3647#issuecomment-2137266012 See also: - https://developer.android.com/training/data-storage/shared/media#access-other-apps-files - https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_IMAGES
This commit is contained in:
parent
3ae0d601db
commit
8cdeb55271
2 changed files with 41 additions and 10 deletions
|
|
@ -785,7 +785,7 @@ public final class TermuxActivity extends AppCompatActivity implements ServiceCo
|
|||
|
||||
// If permission is granted, then also setup storage symlinks.
|
||||
if(PermissionUtils.checkAndRequestLegacyOrManageExternalStoragePermission(
|
||||
TermuxActivity.this, requestCode, !isPermissionCallback)) {
|
||||
TermuxActivity.this, requestCode, true, !isPermissionCallback)) {
|
||||
if (isPermissionCallback)
|
||||
Logger.logInfoAndShowToast(TermuxActivity.this, LOG_TAG,
|
||||
getString(com.termux.shared.R.string.msg_storage_permission_granted_on_request));
|
||||
|
|
|
|||
|
|
@ -209,31 +209,44 @@ public class PermissionUtils {
|
|||
|
||||
/** If path is under primary external storage directory and storage permission is missing,
|
||||
* then legacy or manage external storage permission will be requested from the user via a call
|
||||
* to {@link #checkAndRequestLegacyOrManageExternalStoragePermission(Context, int, boolean)}.
|
||||
* to {@link #checkAndRequestLegacyOrManageExternalStoragePermission(Context, int, boolean, boolean)}.
|
||||
*
|
||||
* @param context The context for operations.
|
||||
* @param filePath The path to check.
|
||||
* @param requestCode The request code to use while asking for permission.
|
||||
* @param prioritizeManageExternalStoragePermission If {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE}
|
||||
* permission should be requested if on
|
||||
* Android `>= 11` instead of getting legacy
|
||||
* storage permission.
|
||||
* @param showErrorMessage If an error message toast should be shown if permission is not granted.
|
||||
* @return Returns {@code true} if permission is granted, otherwise {@code false}.
|
||||
*/
|
||||
@SuppressLint("SdCardPath")
|
||||
public static boolean checkAndRequestLegacyOrManageExternalStoragePermissionIfPathOnPrimaryExternalStorage(
|
||||
@NonNull Context context, String filePath, int requestCode, boolean showErrorMessage) {
|
||||
@NonNull Context context, String filePath, int requestCode,
|
||||
boolean prioritizeManageExternalStoragePermission, boolean showErrorMessage) {
|
||||
// If path is under primary external storage directory, then check for missing permissions.
|
||||
if (!FileUtils.isPathInDirPaths(filePath,
|
||||
Arrays.asList(Environment.getExternalStorageDirectory().getAbsolutePath(), "/sdcard"), true))
|
||||
return true;
|
||||
|
||||
return checkAndRequestLegacyOrManageExternalStoragePermission(context, requestCode, showErrorMessage);
|
||||
return checkAndRequestLegacyOrManageExternalStoragePermission(context, requestCode, prioritizeManageExternalStoragePermission, showErrorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if legacy or manage external storage permissions has been granted. If
|
||||
* {@link #isLegacyExternalStoragePossible(Context)} returns {@code true}, them it will be
|
||||
* checked if app has has been granted {@link Manifest.permission#READ_EXTERNAL_STORAGE} and
|
||||
* {@link Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions, otherwise it will be checked
|
||||
* if app has been granted the {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE} permission.
|
||||
* Check if legacy or manage external storage permissions has been granted.
|
||||
*
|
||||
* - If `prioritizeManageExternalStoragePermission` is `true and running on Android `>= 11`, then
|
||||
* it will be checked if app has been granted the
|
||||
* {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE}.
|
||||
* - If `prioritizeManageExternalStoragePermission` is `false` and running on Android `>= 11`, then
|
||||
* if {@link #isLegacyExternalStoragePossible(Context)} returns `true`, them it will be
|
||||
* checked if app has has been granted {@link Manifest.permission#READ_EXTERNAL_STORAGE} and
|
||||
* {@link Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions, otherwise it will be checked
|
||||
* if app has been granted the {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE} permission.
|
||||
* - If running on Android `< 11`, then it will only be checked if app has been granted
|
||||
* {@link Manifest.permission#READ_EXTERNAL_STORAGE} and
|
||||
* {@link Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions.
|
||||
*
|
||||
* If storage permission is missing, it will be requested from the user if {@code context} is an
|
||||
* instance of {@link Activity} or {@link AppCompatActivity} and {@code requestCode}
|
||||
|
|
@ -256,16 +269,34 @@ public class PermissionUtils {
|
|||
*}
|
||||
* @param context The context for operations.
|
||||
* @param requestCode The request code to use while asking for permission.
|
||||
* @param prioritizeManageExternalStoragePermission If {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE}
|
||||
* permission should be requested if on
|
||||
* Android `>= 11` instead of getting legacy
|
||||
* storage permission.
|
||||
* @param showErrorMessage If an error message toast should be shown if permission is not granted.
|
||||
* @return Returns {@code true} if permission is granted, otherwise {@code false}.
|
||||
*/
|
||||
public static boolean checkAndRequestLegacyOrManageExternalStoragePermission(@NonNull Context context,
|
||||
int requestCode,
|
||||
boolean prioritizeManageExternalStoragePermission,
|
||||
boolean showErrorMessage) {
|
||||
Logger.logVerbose(LOG_TAG, "Checking storage permission");
|
||||
|
||||
String errmsg;
|
||||
boolean requestLegacyStoragePermission = isLegacyExternalStoragePossible(context);
|
||||
Boolean requestLegacyStoragePermission = null;
|
||||
|
||||
if (prioritizeManageExternalStoragePermission && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
||||
requestLegacyStoragePermission = false;
|
||||
|
||||
if (requestLegacyStoragePermission == null)
|
||||
requestLegacyStoragePermission = isLegacyExternalStoragePossible(context);
|
||||
|
||||
boolean checkIfHasRequestedLegacyExternalStorage = checkIfHasRequestedLegacyExternalStorage(context);
|
||||
|
||||
Logger.logVerbose(LOG_TAG, "prioritizeManageExternalStoragePermission=" + prioritizeManageExternalStoragePermission +
|
||||
", requestLegacyStoragePermission=" + requestLegacyStoragePermission +
|
||||
", checkIfHasRequestedLegacyExternalStorage=" + checkIfHasRequestedLegacyExternalStorage);
|
||||
|
||||
if (requestLegacyStoragePermission && checkIfHasRequestedLegacyExternalStorage) {
|
||||
// Check if requestLegacyExternalStorage is set to true in app manifest
|
||||
if (!hasRequestedLegacyExternalStorage(context, showErrorMessage))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue