Resolve manual update links from selected source
This commit is contained in:
parent
79fd148511
commit
0609c73d35
@ -177,8 +177,8 @@ In the app:
|
|||||||
- If Android sends you to the unknown-app install permission screen, return to
|
- 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
|
the app after allowing it; the app continues installing the already downloaded
|
||||||
APK without another update check or download.
|
APK without another update check or download.
|
||||||
- Open the `Update` page and tap `APK` to download the current public APK in a
|
- Open the `Update` page and tap `APK` to resolve the APK from the selected
|
||||||
browser.
|
update source and open it in a browser.
|
||||||
- Open the `Update` page and tap `Details` to see the installed version,
|
- Open the `Update` page and tap `Details` to see the installed version,
|
||||||
selected update source, APK URL, install permission state, and a `Check
|
selected update source, APK URL, install permission state, and a `Check
|
||||||
update` button.
|
update` button.
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package com.neatstudio.tmuxandroid;
|
|||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -296,7 +295,7 @@ public final class MainActivity extends Activity {
|
|||||||
content.addView(actionPanel(
|
content.addView(actionPanel(
|
||||||
actionButton("Check now", view -> updateManager.check(true)),
|
actionButton("Check now", view -> updateManager.check(true)),
|
||||||
actionButton("Source", view -> showUpdateSourcePicker()),
|
actionButton("Source", view -> showUpdateSourcePicker()),
|
||||||
actionButton("APK", view -> openExternalUrl(BuildConfig.DEFAULT_APK_URL))
|
actionButton("APK", view -> updateManager.openApkDownload())
|
||||||
));
|
));
|
||||||
content.addView(sectionTitle("Permissions"));
|
content.addView(sectionTitle("Permissions"));
|
||||||
content.addView(infoBlock("Android", permissionSummary()));
|
content.addView(infoBlock("Android", permissionSummary()));
|
||||||
@ -351,7 +350,7 @@ public final class MainActivity extends Activity {
|
|||||||
"The app checks only the selected update source. APK downloads are cached by version and reused after Android install permission is granted."
|
"The app checks only the selected update source. APK downloads are cached by version and reused after Android install permission is granted."
|
||||||
));
|
));
|
||||||
content.addView(actionPanel(
|
content.addView(actionPanel(
|
||||||
actionButton("Release page", view -> openExternalUrl(BuildConfig.DEFAULT_RELEASE_PAGE_URL)),
|
actionButton("Release page", view -> updateManager.openReleasePage()),
|
||||||
actionButton("Update source", view -> showUpdateSourcePicker()),
|
actionButton("Update source", view -> showUpdateSourcePicker()),
|
||||||
actionButton("Permissions", view -> showPermissionsAndUpdateStatus())
|
actionButton("Permissions", view -> showPermissionsAndUpdateStatus())
|
||||||
));
|
));
|
||||||
@ -429,7 +428,7 @@ public final class MainActivity extends Activity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (PAGE_ABOUT.equals(activeMainPage)) {
|
if (PAGE_ABOUT.equals(activeMainPage)) {
|
||||||
actionRow.addView(toolbarButton("Release", view -> openExternalUrl(BuildConfig.DEFAULT_RELEASE_PAGE_URL)));
|
actionRow.addView(toolbarButton("Release", view -> updateManager.openReleasePage()));
|
||||||
actionRow.addView(toolbarButton("Permissions", view -> showPermissionsAndUpdateStatus()));
|
actionRow.addView(toolbarButton("Permissions", view -> showPermissionsAndUpdateStatus()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1181,12 +1180,10 @@ public final class MainActivity extends Activity {
|
|||||||
.append(")\n");
|
.append(")\n");
|
||||||
text.append("Server: ").append(getServerUrl()).append('\n');
|
text.append("Server: ").append(getServerUrl()).append('\n');
|
||||||
text.append('\n');
|
text.append('\n');
|
||||||
text.append("Manual APK download:\n")
|
text.append("Manual APK download:\n");
|
||||||
.append(BuildConfig.DEFAULT_APK_URL)
|
text.append("Tap APK on the Update page. The app resolves the APK from the selected update source.\n");
|
||||||
.append('\n');
|
text.append("Release page:\n");
|
||||||
text.append("Release page:\n")
|
text.append("Tap Release on the About page. The app resolves the page from the selected update source.\n");
|
||||||
.append(BuildConfig.DEFAULT_RELEASE_PAGE_URL)
|
|
||||||
.append('\n');
|
|
||||||
text.append('\n');
|
text.append('\n');
|
||||||
text.append("In-app update:\n");
|
text.append("In-app update:\n");
|
||||||
text.append("Tap Update. The app checks only the selected source, downloads one APK per version, verifies SHA-256, then opens Android's installer.\n");
|
text.append("Tap Update. The app checks only the selected source, downloads one APK per version, verifies SHA-256, then opens Android's installer.\n");
|
||||||
@ -1229,14 +1226,6 @@ public final class MainActivity extends Activity {
|
|||||||
return text.toString();
|
return text.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openExternalUrl(String url) {
|
|
||||||
try {
|
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
|
||||||
} catch (ActivityNotFoundException error) {
|
|
||||||
showMessage("No app can open URL");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showUpdateSourcePicker() {
|
private void showUpdateSourcePicker() {
|
||||||
String[] items = {
|
String[] items = {
|
||||||
"GitHub: " + BuildConfig.DEFAULT_UPDATE_URL,
|
"GitHub: " + BuildConfig.DEFAULT_UPDATE_URL,
|
||||||
|
|||||||
@ -32,6 +32,10 @@ final class UpdateManager {
|
|||||||
void onMessage(String message);
|
void onMessage(String message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private interface ReleaseUrlPicker {
|
||||||
|
String pick(ReleaseInfo info);
|
||||||
|
}
|
||||||
|
|
||||||
private final Activity activity;
|
private final Activity activity;
|
||||||
private final SharedPreferences prefs;
|
private final SharedPreferences prefs;
|
||||||
private final Callback callback;
|
private final Callback callback;
|
||||||
@ -73,6 +77,40 @@ final class UpdateManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void openApkDownload() {
|
||||||
|
openSelectedReleaseUrl("APK", info -> info.apkUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void openReleasePage() {
|
||||||
|
openSelectedReleaseUrl("Release page", info -> info.releasePageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openSelectedReleaseUrl(String label, ReleaseUrlPicker picker) {
|
||||||
|
if (checkInProgress) {
|
||||||
|
postMessage("Update check already running");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String manifestUrl = getUpdateManifestUrl();
|
||||||
|
checkInProgress = true;
|
||||||
|
callback.onChecking(true);
|
||||||
|
postMessage("Resolving " + label + " from " + hostLabel(manifestUrl) + "...");
|
||||||
|
executor.execute(() -> {
|
||||||
|
try {
|
||||||
|
ReleaseInfo info = fetchReleaseInfo(manifestUrl);
|
||||||
|
String url = picker.pick(info);
|
||||||
|
if (url == null || url.trim().isEmpty()) {
|
||||||
|
throw new IllegalStateException(label + " URL is missing");
|
||||||
|
}
|
||||||
|
activity.runOnUiThread(() -> openExternalUrl(url.trim(), label));
|
||||||
|
} catch (Exception error) {
|
||||||
|
postMessage(label + " failed: " + error.getMessage());
|
||||||
|
} finally {
|
||||||
|
checkInProgress = false;
|
||||||
|
activity.runOnUiThread(() -> callback.onChecking(false));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private String getUpdateManifestUrl() {
|
private String getUpdateManifestUrl() {
|
||||||
String url = prefs.getString("update_url", BuildConfig.DEFAULT_UPDATE_URL);
|
String url = prefs.getString("update_url", BuildConfig.DEFAULT_UPDATE_URL);
|
||||||
if (url == null || url.trim().isEmpty()) {
|
if (url == null || url.trim().isEmpty()) {
|
||||||
@ -260,6 +298,15 @@ final class UpdateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openExternalUrl(String url, String label) {
|
||||||
|
try {
|
||||||
|
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
||||||
|
postMessage("Opened " + label);
|
||||||
|
} catch (ActivityNotFoundException error) {
|
||||||
|
postMessage("No app can open " + label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void resumePendingInstall() {
|
void resumePendingInstall() {
|
||||||
File apk = pendingInstallApk;
|
File apk = pendingInstallApk;
|
||||||
if (apk == null) {
|
if (apk == null) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user