Resume pending APK install
This commit is contained in:
parent
fc1cf589a7
commit
67968654cb
@ -174,6 +174,9 @@ In the app:
|
||||
SHA-256, and open Android's installer.
|
||||
- If the same version APK was already downloaded and its SHA-256 still matches,
|
||||
the app reuses that file instead of downloading it again.
|
||||
- If Android sends you to the unknown-app install permission screen, return to
|
||||
the app after allowing it; the app continues installing the already downloaded
|
||||
APK without another update check or download.
|
||||
- Open `More` -> `Open APK download` to download the current public APK in a
|
||||
browser.
|
||||
- Open the `Update` page or `More` -> `Permissions / update status` to see the
|
||||
|
||||
@ -2019,6 +2019,14 @@ public final class MainActivity extends Activity {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (updateManager != null) {
|
||||
updateManager.resumePendingInstall();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
closeTerminalSocket();
|
||||
|
||||
@ -25,6 +25,8 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
final class UpdateManager {
|
||||
private static final String PREF_PENDING_INSTALL_APK = "pending_install_apk";
|
||||
|
||||
interface Callback {
|
||||
void onChecking(boolean checking);
|
||||
void onMessage(String message);
|
||||
@ -34,8 +36,9 @@ final class UpdateManager {
|
||||
private final SharedPreferences prefs;
|
||||
private final Callback callback;
|
||||
private final ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
private boolean checkInProgress;
|
||||
private boolean downloadInProgress;
|
||||
private volatile boolean checkInProgress;
|
||||
private volatile boolean downloadInProgress;
|
||||
private File pendingInstallApk;
|
||||
|
||||
UpdateManager(Activity activity, SharedPreferences prefs, Callback callback) {
|
||||
this.activity = activity;
|
||||
@ -226,15 +229,19 @@ final class UpdateManager {
|
||||
private void installApk(File apk) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||
&& !activity.getPackageManager().canRequestPackageInstalls()) {
|
||||
pendingInstallApk = apk;
|
||||
prefs.edit().putString(PREF_PENDING_INSTALL_APK, apk.getAbsolutePath()).apply();
|
||||
Intent settingsIntent = new Intent(
|
||||
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
|
||||
Uri.parse("package:" + activity.getPackageName())
|
||||
);
|
||||
activity.startActivity(settingsIntent);
|
||||
Toast.makeText(activity, "Allow installs, then run update again", Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(activity, "Allow installs, then return to continue", Toast.LENGTH_LONG).show();
|
||||
postMessage("Install permission required");
|
||||
return;
|
||||
}
|
||||
pendingInstallApk = null;
|
||||
prefs.edit().remove(PREF_PENDING_INSTALL_APK).apply();
|
||||
|
||||
Uri apkUri = UpdateFileProvider.getUriForFile(
|
||||
activity,
|
||||
@ -253,6 +260,32 @@ final class UpdateManager {
|
||||
}
|
||||
}
|
||||
|
||||
void resumePendingInstall() {
|
||||
File apk = pendingInstallApk;
|
||||
if (apk == null) {
|
||||
String path = prefs.getString(PREF_PENDING_INSTALL_APK, "");
|
||||
if (path != null && !path.isEmpty()) {
|
||||
apk = new File(path);
|
||||
pendingInstallApk = apk;
|
||||
}
|
||||
}
|
||||
if (apk == null) {
|
||||
return;
|
||||
}
|
||||
if (!apk.exists() || apk.length() <= 0) {
|
||||
pendingInstallApk = null;
|
||||
prefs.edit().remove(PREF_PENDING_INSTALL_APK).apply();
|
||||
postMessage("Downloaded APK is no longer available");
|
||||
return;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||
&& !activity.getPackageManager().canRequestPackageInstalls()) {
|
||||
return;
|
||||
}
|
||||
postMessage("Continuing APK install...");
|
||||
installApk(apk);
|
||||
}
|
||||
|
||||
private static byte[] readAllBytes(InputStream input) throws Exception {
|
||||
java.io.ByteArrayOutputStream output = new java.io.ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[16 * 1024];
|
||||
|
||||
@ -106,7 +106,9 @@ provider checks.
|
||||
Downloaded APKs are cached by `versionCode`. If a cached APK exists and its
|
||||
SHA-256 matches the manifest, the app reuses it instead of downloading the same
|
||||
version again. This matters when Android redirects the user to unknown-app
|
||||
install settings before the installer can run.
|
||||
install settings before the installer can run. After the user grants that
|
||||
permission and returns to the app, the app resumes installation of the pending
|
||||
APK instead of asking the user to run update again.
|
||||
|
||||
Only `v*` tags publish GitHub Releases. Main branch builds are for CI artifacts
|
||||
and should be used to validate grouped changes. Do not publish a new tag for
|
||||
|
||||
Loading…
Reference in New Issue
Block a user