From 2d69a89d98f611bfb06c5e4268b8d989352fa68d Mon Sep 17 00:00:00 2001 From: Sergey Eremin Date: Fri, 28 Jul 2017 02:53:57 +0300 Subject: [PATCH] Self update check now goes through standard ui, not the about page --- .../yeriomin/yalpstore/AboutActivity.java | 20 --- .../yalpstore/FdroidLinkExtractor.java | 34 ----- .../yeriomin/yalpstore/SelfUpdateChecker.java | 124 +++++------------- .../yalpstore/UpdatableAppsActivity.java | 17 +++ .../fragment/details/ButtonDownload.java | 49 +++++-- .../main/res/layout/about_activity_layout.xml | 7 - 6 files changed, 84 insertions(+), 167 deletions(-) delete mode 100644 app/src/main/java/com/github/yeriomin/yalpstore/FdroidLinkExtractor.java diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/AboutActivity.java b/app/src/main/java/com/github/yeriomin/yalpstore/AboutActivity.java index 11de95f4f..565d442d7 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/AboutActivity.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/AboutActivity.java @@ -1,12 +1,9 @@ package com.github.yeriomin.yalpstore; -import android.Manifest; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.net.Uri; -import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.ClipboardManager; @@ -42,23 +39,6 @@ public class AboutActivity extends YalpStoreActivity { return "bitcoin:" + super.getUri(v) + "?label=YalpStore"; } }); - if (hasPermission()) { - checkForUpdate(); - } - } - - private void checkForUpdate() { - SelfUpdateChecker checker = new SelfUpdateChecker(this); - checker.setButton((TextView) findViewById(R.id.update)); - checker.execute(); - } - - private boolean hasPermission() { - if (Build.VERSION.SDK_INT >= 23) { - return checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) - == PackageManager.PERMISSION_GRANTED; - } - return true; } private class CopyToClipboardListener implements View.OnClickListener { diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/FdroidLinkExtractor.java b/app/src/main/java/com/github/yeriomin/yalpstore/FdroidLinkExtractor.java deleted file mode 100644 index b436f12c6..000000000 --- a/app/src/main/java/com/github/yeriomin/yalpstore/FdroidLinkExtractor.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.github.yeriomin.yalpstore; - -import org.xmlpull.v1.XmlPullParserException; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class FdroidLinkExtractor { - - static private final String LINK_PATTERN = "https://f-droid\\.org/repo/com\\.github\\.yeriomin\\.yalpstore_(\\d+)\\.apk"; - - private int latestVersionCode; - private String latestLink; - - public String getLatestLink() { - return latestLink; - } - - public int getLatestVersionCode() { - return latestVersionCode; - } - - public FdroidLinkExtractor(String html) throws XmlPullParserException { - Pattern pattern = Pattern.compile(LINK_PATTERN); - Matcher matcher = pattern.matcher(html); - while (matcher.find()) { - int versionCode = Integer.valueOf(matcher.group(1)); - if (versionCode > latestVersionCode) { - latestVersionCode = versionCode; - latestLink = html.substring(matcher.start(), matcher.end()); - } - } - } -} diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/SelfUpdateChecker.java b/app/src/main/java/com/github/yeriomin/yalpstore/SelfUpdateChecker.java index ad3763d13..795569638 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/SelfUpdateChecker.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/SelfUpdateChecker.java @@ -1,111 +1,47 @@ package com.github.yeriomin.yalpstore; -import android.content.Context; -import android.os.AsyncTask; -import android.util.Log; -import android.view.View; -import android.widget.TextView; - -import com.github.yeriomin.playstoreapi.AndroidAppDeliveryData; -import com.github.yeriomin.yalpstore.model.App; - -import org.xmlpull.v1.XmlPullParserException; - -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; +import java.net.MalformedURLException; import java.net.URL; +import java.net.URLConnection; -public class SelfUpdateChecker extends AsyncTask { +public class SelfUpdateChecker { - static private final String FDROID_APP_PAGE = "https://f-droid.org/repository/browse/?fdid=" + BuildConfig.APPLICATION_ID; - - private Context context; - private FdroidLinkExtractor parser; - private TextView button; - - public void setButton(TextView button) { - this.button = button; - } - - public SelfUpdateChecker(Context context) { - this.context = context; - } - - @Override - protected void onPreExecute() { - button.setText(R.string.about_self_update_checking); - button.setVisibility(View.VISIBLE); - } - - @Override - protected Void doInBackground(Void... params) { - String html; - try { - html = getHtml(); - } catch (IOException e) { - Log.w(getClass().getName(), "Could not download app page: " + e.getMessage()); - return null; + static public int getLatestVersionCode() { + int latestVersionCode = BuildConfig.VERSION_CODE; + while (isAvailable(latestVersionCode + 1)) { + latestVersionCode++; } + return latestVersionCode; + } + + static public String getUrlString(int versionCode) { + return "https://f-droid.org/repo/com.github.yeriomin.yalpstore_" + versionCode + ".apk"; + } + + static private URL getUrl(int versionCode) { try { - parser = new FdroidLinkExtractor(html); - } catch (XmlPullParserException e) { - Log.w(getClass().getName(), "HTML parsing error: " + e.getMessage()); + return new URL(getUrlString(versionCode)); + } catch (MalformedURLException e) { + // Unlikely } return null; } - @Override - protected void onPostExecute(Void aVoid) { - if (isVersionLatest()) { - button.setText(R.string.about_self_update_unavailable); - } else { - button.setText(context.getString(R.string.about_self_update_available, parser.getLatestVersionCode())); - button.setTextColor(0xFF5555FF); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - downloadLatest(); - } - }); + static private boolean isAvailable(int versionCode) { + try { + URLConnection connection = getUrl(versionCode).openConnection(); + if (connection instanceof HttpURLConnection) { + ((HttpURLConnection) connection).setRequestMethod("HEAD"); + return ((HttpURLConnection) connection).getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST; + } + InputStream in = connection.getInputStream(); + in.close(); + return true; + } catch (IOException x) { + return false; } } - - private boolean isVersionLatest() { - if (null != parser) { - return parser.getLatestVersionCode() <= BuildConfig.VERSION_CODE; - } - return true; - } - - private void downloadLatest() { - App app = new App(); - app.getPackageInfo().packageName = BuildConfig.APPLICATION_ID; - app.setDisplayName(context.getString(R.string.app_name)); - app.setVersionCode(parser.getLatestVersionCode()); - Downloader downloader = new Downloader(context); - - AndroidAppDeliveryData deliveryData = AndroidAppDeliveryData.newBuilder() - .setDownloadUrl(parser.getLatestLink()) - .build(); - - downloader.download(app, deliveryData, null); - } - - private String getHtml() throws IOException { - HttpURLConnection connection = (HttpURLConnection) new URL(FDROID_APP_PAGE).openConnection(); - InputStream in = connection.getInputStream(); - return new String(toByteArray(in)); - } - - private byte[] toByteArray(InputStream in) throws IOException { - byte[] buffer = new byte[2048]; - int bytesRead; - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - while ((bytesRead = in.read(buffer)) != -1) { - byteArrayOutputStream.write(buffer, 0, bytesRead); - } - return byteArrayOutputStream.toByteArray(); - } } diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/UpdatableAppsActivity.java b/app/src/main/java/com/github/yeriomin/yalpstore/UpdatableAppsActivity.java index e41049e8c..a1e5bba02 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/UpdatableAppsActivity.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/UpdatableAppsActivity.java @@ -153,6 +153,23 @@ public class UpdatableAppsActivity extends AppListActivity { this.activity = activity; } + @Override + protected Throwable doInBackground(String... params) { + Throwable result = super.doInBackground(params); + if (null != result || !explicitCheck) { + return result; + } + int latestVersionCode = SelfUpdateChecker.getLatestVersionCode(); + if (latestVersionCode > BuildConfig.VERSION_CODE) { + App yalp = installedApps.get(BuildConfig.APPLICATION_ID); + installedApps.remove(yalp); + yalp.setVersionCode(latestVersionCode); + yalp.setVersionName("0." + latestVersionCode); + updatableApps.add(yalp); + } + return result; + } + @Override protected void onPostExecute(Throwable e) { super.onPostExecute(e); diff --git a/app/src/main/java/com/github/yeriomin/yalpstore/fragment/details/ButtonDownload.java b/app/src/main/java/com/github/yeriomin/yalpstore/fragment/details/ButtonDownload.java index 5f68a596f..153cbdd0f 100644 --- a/app/src/main/java/com/github/yeriomin/yalpstore/fragment/details/ButtonDownload.java +++ b/app/src/main/java/com/github/yeriomin/yalpstore/fragment/details/ButtonDownload.java @@ -9,13 +9,17 @@ import android.widget.ImageButton; import android.widget.ProgressBar; import android.widget.Toast; +import com.github.yeriomin.playstoreapi.AndroidAppDeliveryData; +import com.github.yeriomin.yalpstore.BuildConfig; import com.github.yeriomin.yalpstore.DetailsActivity; import com.github.yeriomin.yalpstore.DownloadState; +import com.github.yeriomin.yalpstore.Downloader; import com.github.yeriomin.yalpstore.ManualDownloadActivity; import com.github.yeriomin.yalpstore.OnDownloadProgressListener; import com.github.yeriomin.yalpstore.Paths; import com.github.yeriomin.yalpstore.PurchaseTask; import com.github.yeriomin.yalpstore.R; +import com.github.yeriomin.yalpstore.SelfUpdateChecker; import com.github.yeriomin.yalpstore.model.App; import com.github.yeriomin.yalpstore.notification.CancelDownloadService; @@ -30,7 +34,7 @@ public class ButtonDownload extends Button { public ButtonDownload(final DetailsActivity activity, final App app) { super(activity, app); - cancelButton = (ImageButton) activity.findViewById(R.id.cancel); + cancelButton = activity.findViewById(R.id.cancel); cancelButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -52,7 +56,7 @@ public class ButtonDownload extends Button { return (!Paths.getApkPath(app.getPackageName(), app.getVersionCode()).exists() || !DownloadState.get(app.getPackageName()).isEverythingSuccessful() ) - && app.isInPlayStore() + && (app.isInPlayStore() || app.getPackageName().equals(BuildConfig.APPLICATION_ID)) && (getInstalledVersionCode() != app.getVersionCode() || activity instanceof ManualDownloadActivity) ; } @@ -80,7 +84,13 @@ public class ButtonDownload extends Button { } public void download() { - if (prepareDownloadsDir()) { + if (app.getPackageName().equals(BuildConfig.APPLICATION_ID)) { + new Downloader(button.getContext()).download( + app, + AndroidAppDeliveryData.newBuilder().setDownloadUrl(SelfUpdateChecker.getUrlString(app.getVersionCode())).build(), + getDownloadProgressListener() + ); + } else if (prepareDownloadsDir()) { getPurchaseTask().execute(); } else { Toast.makeText( @@ -99,16 +109,14 @@ public class ButtonDownload extends Button { return dir.exists() && dir.isDirectory() && dir.canWrite(); } + private OnDownloadProgressListener getDownloadProgressListener() { + ProgressBar progressBar = activity.findViewById(R.id.download_progress); + progressBar.setVisibility(View.VISIBLE); + return new OnDownloadProgressListener(progressBar, DownloadState.get(app.getPackageName())); + } + private PurchaseTask getPurchaseTask() { - PurchaseTask purchaseTask = new PurchaseTask() { - @Override - protected void onPostExecute(Throwable e) { - super.onPostExecute(e); - if (null == e) { - disableButton(R.id.download, R.string.details_downloading); - } - } - }; + PurchaseTask purchaseTask = new LocalPurchaseTask(this); ProgressBar progressBar = (ProgressBar) activity.findViewById(R.id.download_progress); progressBar.setVisibility(View.VISIBLE); purchaseTask.setOnDownloadProgressListener(new OnDownloadProgressListener(progressBar, DownloadState.get(app.getPackageName()))); @@ -146,4 +154,21 @@ public class ButtonDownload extends Button { return 0; } } + + static class LocalPurchaseTask extends PurchaseTask { + + private ButtonDownload fragment; + + public LocalPurchaseTask(ButtonDownload fragment) { + this.fragment = fragment; + } + + @Override + protected void onPostExecute(Throwable e) { + super.onPostExecute(e); + if (null == e) { + fragment.disableButton(R.id.download, R.string.details_downloading); + } + } + } } diff --git a/app/src/main/res/layout/about_activity_layout.xml b/app/src/main/res/layout/about_activity_layout.xml index 83fe68801..d42e40e9b 100644 --- a/app/src/main/res/layout/about_activity_layout.xml +++ b/app/src/main/res/layout/about_activity_layout.xml @@ -28,13 +28,6 @@ - -