mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-09-03 17:03:37 -04:00
Add support for changing save location on Android (#1520)
- Enabled the Android UI path for changing the data folder - Added Android MANAGE_EXTERNAL_STORAGE permission - Added an Android flow to request “All files access” before opening the folder picker - Added code path to resume the folder selection flow after returning from Android settings - Improved the Android write-probe error message to point users at the required permission
This commit is contained in:
@@ -12,6 +12,7 @@ import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
@@ -27,10 +28,12 @@ import java.util.List;
|
||||
public class DuskActivity extends SDLActivity {
|
||||
private static final String TAG = "DuskActivity";
|
||||
private static final int FOLDER_DIALOG_REQUEST_CODE = 0x4455;
|
||||
private static final int MANAGE_STORAGE_REQUEST_CODE = 0x4456;
|
||||
private static final String EXTERNAL_STORAGE_AUTHORITY =
|
||||
"com.android.externalstorage.documents";
|
||||
|
||||
private long folderDialogUserdata = 0;
|
||||
private boolean awaitingManageStoragePermission = false;
|
||||
|
||||
private static native void nativeFolderDialogResult(long userdata, String path, String error);
|
||||
|
||||
@@ -89,6 +92,9 @@ public class DuskActivity extends SDLActivity {
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
hideSystemBars();
|
||||
if (awaitingManageStoragePermission) {
|
||||
resumeFolderDialogAfterPermissionGrant();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -171,6 +177,19 @@ public class DuskActivity extends SDLActivity {
|
||||
}
|
||||
|
||||
folderDialogUserdata = userdata;
|
||||
if (requiresManageStoragePermission() && !hasManageStoragePermission()) {
|
||||
if (!requestManageStoragePermission()) {
|
||||
finishFolderDialogWithError("Unable to request Android file access permission");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
openFolderDialog();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void openFolderDialog() {
|
||||
runOnUiThread(() -> {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |
|
||||
@@ -185,9 +204,71 @@ public class DuskActivity extends SDLActivity {
|
||||
finishFolderDialog(Activity.RESULT_CANCELED, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean requiresManageStoragePermission() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R;
|
||||
}
|
||||
|
||||
private boolean hasManageStoragePermission() {
|
||||
return !requiresManageStoragePermission() || Environment.isExternalStorageManager();
|
||||
}
|
||||
|
||||
private boolean requestManageStoragePermission() {
|
||||
if (!requiresManageStoragePermission()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
awaitingManageStoragePermission = true;
|
||||
runOnUiThread(() -> {
|
||||
if (tryStartManageStorageIntent(
|
||||
new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
|
||||
.setData(Uri.parse("package:" + getPackageName()))) ||
|
||||
tryStartManageStorageIntent(
|
||||
new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
finishFolderDialogWithError("Unable to request Android file access permission");
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean tryStartManageStorageIntent(Intent intent) {
|
||||
try {
|
||||
startActivityForResult(intent, MANAGE_STORAGE_REQUEST_CODE);
|
||||
return true;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.w(TAG, "Unable to open all-files access settings.", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void resumeFolderDialogAfterPermissionGrant() {
|
||||
awaitingManageStoragePermission = false;
|
||||
if (folderDialogUserdata == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasManageStoragePermission()) {
|
||||
openFolderDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
finishFolderDialogWithError(
|
||||
"Allow \"All files access\" for Dusklight before choosing a custom data folder");
|
||||
}
|
||||
|
||||
private void finishFolderDialogWithError(String error) {
|
||||
long userdata = folderDialogUserdata;
|
||||
folderDialogUserdata = 0;
|
||||
awaitingManageStoragePermission = false;
|
||||
if (userdata != 0) {
|
||||
nativeFolderDialogResult(userdata, null, error);
|
||||
}
|
||||
}
|
||||
|
||||
private void finishFolderDialog(int resultCode, Intent data) {
|
||||
long userdata = folderDialogUserdata;
|
||||
folderDialogUserdata = 0;
|
||||
|
||||
Reference in New Issue
Block a user