request access if needed to use backup and restore

This commit is contained in:
Anthony Calosa
2025-08-21 21:49:45 +08:00
parent fdf0c13a7f
commit 3b9ded8270
6 changed files with 78 additions and 47 deletions

View File

@@ -253,9 +253,7 @@ public class Main extends AndroidApplication {
text.setGravity(Gravity.LEFT);
text.setTypeface(Typeface.SERIF);
String SP = "Storage Permission";
if (needExternalFileAccess()) {
SP = "All File Access Permission";
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
SP = "Photos and Videos, Music and Audio Permissions";
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
SP = "Files & Media Permissions";
@@ -267,11 +265,8 @@ public class Main extends AndroidApplication {
" 2) Tap Permissions\n" +
" 3) Enable the " + SP + ".\n\n" +
"(You can tap anywhere to exit and restart the app)\n\n";
String allFileAccessSteps = " 1) Tap \"App Settings\" Button.\n" +
" 2) Enable the " + SP + ".\n\n" +
"(You can tap anywhere to exit and restart the app)\n\n";
if (ex) {
title = needExternalFileAccess() ? "All File Access Permission" : manageApp ? "Forge AutoUpdater Permission...\n" : "Forge didn't initialize!\n";
title = manageApp ? "Forge AutoUpdater Permission...\n" : "Forge didn't initialize!\n";
steps = manageApp ? " 1) Tap \"App Settings\" Button.\n" +
" 2) Enable \"Allow apps from this source\"\n" +
"(You can tap anywhere to exit and restart the app)\n\n" : msg + "\n\n";
@@ -280,7 +275,7 @@ public class Main extends AndroidApplication {
SpannableString ss1 = new SpannableString(title);
ss1.setSpan(new StyleSpan(Typeface.BOLD), 0, ss1.length(), 0);
text.append(ss1);
text.append(needExternalFileAccess() ? allFileAccessSteps : steps);
text.append(steps);
row.addView(text);
row.setGravity(Gravity.CENTER);
@@ -309,16 +304,7 @@ public class Main extends AndroidApplication {
button.setTextColor(Color.RED);
button.setOnClickListener(v -> {
if (needExternalFileAccess()) {
/*
This is needed for Android 11 and upwards to have access on external storage (direct file path)
ie adventure mode -> data -> restore. Though its not fast like the app-specific storage...
*/
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else if (manageApp) {
if (manageApp) {
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
.setData(Uri.parse(String.format("package:%s", getPackageName())))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -354,7 +340,7 @@ public class Main extends AndroidApplication {
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
handler.postDelayed(() -> {
if (needExternalFileAccess() || !permissiongranted || exception) {
if (!permissiongranted || exception) {
displayMessage(forgeLogo, adapter, exception, msg, false);
} else if (title.isEmpty() && steps.isEmpty()) {
if (isLandscape) {
@@ -678,6 +664,21 @@ public class Main extends AndroidApplication {
return new AndroidUpnpServiceConfiguration();
}
@Override
public boolean needFileAccess() {
return needExternalFileAccess();
}
@Override
public void requestFileAcces() {
/* This is needed for Android 11 and upwards to have access on external storage (direct file path)
ie adventure mode -> data -> restore. Though it's not fast like the app-specific storage...*/
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
@Override
public boolean isConnectedToInternet() {
//if it can't determine Internet connection within two seconds, assume not connected

View File

@@ -145,5 +145,15 @@ public class Main extends IOSApplication.Delegate {
// not used
return null;
}
@Override
public boolean needFileAccess() {
return false;
}
@Override
public void requestFileAcces() {
}
}
}

View File

@@ -153,5 +153,15 @@ public class Main {
// shouldn't be reached
return null;
}
@Override
public boolean needFileAccess() {
return false;
}
@Override
public void requestFileAcces() {
}
}
}

View File

@@ -126,6 +126,10 @@ public class StartScene extends UIScene {
}
public boolean backup() {
if (Forge.getDeviceAdapter().needFileAccess()) {
Forge.getDeviceAdapter().requestFileAcces();
return true;
}
if (backupDialog == null) {
backupDialog = createGenericDialog(Forge.getLocalizer().getMessage("lblData"),
null, Forge.getLocalizer().getMessage("lblBackup"),

View File

@@ -57,37 +57,41 @@ public class FilesPage extends TabPage<SettingsScreen> {
lstItems.addItem(new Extra(Forge.getLocalizer().getMessage("lblBackupRestore"), Forge.getLocalizer().getMessage("lblBackupRestoreDescription")) {
@Override
public void select() {
if (Forge.getDeviceAdapter().needFileAccess()) {
Forge.getDeviceAdapter().requestFileAcces();
return;
}
FOptionPane.showOptionDialog(Forge.getLocalizer().getMessage("lblPlsSelectActions"), "", FOptionPane.QUESTION_ICON, ImmutableList.of(Forge.getLocalizer().getMessage("lblBackup"), Forge.getLocalizer().getMessage("lblRestore"), Forge.getLocalizer().getMessage("lblCancel")), 2, new Callback<Integer>() {
@Override
public void run(Integer result) {
switch (result) {
case 0:
FThreads.invokeInEdtLater(() -> LoadingOverlay.show(Forge.getLocalizer().getMessage("lblBackupMsg"), true, () -> {
File source = new FileHandle(ForgeProfileProperties.getUserDir()).file();
File target = new FileHandle(Forge.getDeviceAdapter().getDownloadsDir()).file();
try {
ZipUtil.zip(source, target, ZipUtil.backupClsFile);
FOptionPane.showMessageDialog(Forge.getLocalizer().getMessage("lblSuccess") + "\n" + target.getAbsolutePath() + File.separator + ZipUtil.backupClsFile, Forge.getLocalizer().getMessage("lblBackup"), FOptionPane.INFORMATION_ICON);
} catch (IOException e) {
FOptionPane.showMessageDialog(e.toString(), Forge.getLocalizer().getMessage("lblError"), FOptionPane.ERROR_ICON);
}
}));
break;
case 1:
FThreads.invokeInEdtLater(() -> LoadingOverlay.show(Forge.getLocalizer().getMessage("lblRestoreMsg"), true, () -> {
File source = new FileHandle(Forge.getDeviceAdapter().getDownloadsDir() + ZipUtil.backupClsFile).file();
File target = new FileHandle(ForgeProfileProperties.getUserDir()).file().getParentFile();
try {
String msg = ZipUtil.unzip(source, target);
FOptionPane.showMessageDialog(Forge.getLocalizer().getMessage("lblSuccess") + "\n" + msg, Forge.getLocalizer().getMessage("lblRestore"), FOptionPane.INFORMATION_ICON);
} catch (IOException e) {
FOptionPane.showMessageDialog(e.toString(), Forge.getLocalizer().getMessage("lblError"), FOptionPane.ERROR_ICON);
}
}));
break;
default:
break;
}
switch (result) {
case 0:
FThreads.invokeInEdtLater(() -> LoadingOverlay.show(Forge.getLocalizer().getMessage("lblBackupMsg"), true, () -> {
File source = new FileHandle(ForgeProfileProperties.getUserDir()).file();
File target = new FileHandle(Forge.getDeviceAdapter().getDownloadsDir()).file();
try {
ZipUtil.zip(source, target, ZipUtil.backupClsFile);
FOptionPane.showMessageDialog(Forge.getLocalizer().getMessage("lblSuccess") + "\n" + target.getAbsolutePath() + File.separator + ZipUtil.backupClsFile, Forge.getLocalizer().getMessage("lblBackup"), FOptionPane.INFORMATION_ICON);
} catch (IOException e) {
FOptionPane.showMessageDialog(e.toString(), Forge.getLocalizer().getMessage("lblError"), FOptionPane.ERROR_ICON);
}
}));
break;
case 1:
FThreads.invokeInEdtLater(() -> LoadingOverlay.show(Forge.getLocalizer().getMessage("lblRestoreMsg"), true, () -> {
File source = new FileHandle(Forge.getDeviceAdapter().getDownloadsDir() + ZipUtil.backupClsFile).file();
File target = new FileHandle(ForgeProfileProperties.getUserDir()).file().getParentFile();
try {
String msg = ZipUtil.unzip(source, target);
FOptionPane.showMessageDialog(Forge.getLocalizer().getMessage("lblSuccess") + "\n" + msg, Forge.getLocalizer().getMessage("lblRestore"), FOptionPane.INFORMATION_ICON);
} catch (IOException e) {
FOptionPane.showMessageDialog(e.toString(), Forge.getLocalizer().getMessage("lblError"), FOptionPane.ERROR_ICON);
}
}));
break;
default:
break;
}
}
});
}

View File

@@ -27,4 +27,6 @@ public interface IDeviceAdapter {
Pair<Integer, Integer> getRealScreenSize(boolean real);
ArrayList<String> getGamepads();
UpnpServiceConfiguration getUpnpPlatformService();
boolean needFileAccess();
void requestFileAcces();
}