From 0b4e3c630323f8689acb854738270a2d1c8f6cbf Mon Sep 17 00:00:00 2001 From: Vologhat <47892605+Vologhat@users.noreply.github.com> Date: Wed, 15 Jun 2022 16:41:21 +0300 Subject: [PATCH 1/6] added ota --- .../vtosters/lite/ui/fragments/OTADialog.java | 50 +++++++ .../lite/ui/fragments/VTSettings.java | 3 +- .../ru/vtosters/lite/utils/OTAHelper.java | 126 ++++++++++++++++++ smali/AndroidManifest.xml | 2 +- 4 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/ru/vtosters/lite/ui/fragments/OTADialog.java create mode 100644 app/src/main/java/ru/vtosters/lite/utils/OTAHelper.java diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/OTADialog.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/OTADialog.java new file mode 100644 index 000000000..13d98dd5a --- /dev/null +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/OTADialog.java @@ -0,0 +1,50 @@ +package ru.vtosters.lite.ui.fragments; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.widget.Toast; + +import com.vk.core.dialogs.VKProgressDialog; + +import ru.vtosters.lite.utils.OTAHelper; + +public class OTADialog implements OTAHelper.OTAListener { + + private Activity mActivity; + private VKProgressDialog mProgressDialog; + + private OTAHelper mHelper; + + public static OTADialog checkUpdates(Activity activity) { + return new OTADialog(activity); + } + + public OTADialog(Activity activity) { + mActivity = activity; + + mProgressDialog = new VKProgressDialog(activity); + mProgressDialog.setTitle("Проверка обновлений..."); + mProgressDialog.setCancelable(false); + mProgressDialog.show(); + + mHelper = new OTAHelper(this); + mHelper.loadData(); + } + + @Override + public void onUpdateApplied() { + mActivity.runOnUiThread(() -> { + Toast.makeText(mActivity, "Обновления найдены", Toast.LENGTH_SHORT).show(); + mProgressDialog.dismiss(); + }); + } + + @Override + public void onUpdateCanceled() { + mActivity.runOnUiThread(() -> { + Toast.makeText(mActivity, "Обновлений не найдено", Toast.LENGTH_SHORT).show(); + mProgressDialog.dismiss(); + }); + } +} diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java index 5d1fb55a2..06bfabeff 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java @@ -337,7 +337,8 @@ public class VTSettings extends MaterialPreferenceToolbarFragment { }); PreferencesUtil.addPreference(this, "", getString("download_latest_vtl"), "", "ic_download_24", preference -> { - getContext().startActivity(new Intent("android.intent.action.VIEW").setData(Uri.parse("https://github.com/vtosters/lite/releases/latest"))); +// getContext().startActivity(new Intent("android.intent.action.VIEW").setData(Uri.parse("https://github.com/vtosters/lite/releases/latest"))); + OTADialog.checkUpdates(p()); return false; }); } diff --git a/app/src/main/java/ru/vtosters/lite/utils/OTAHelper.java b/app/src/main/java/ru/vtosters/lite/utils/OTAHelper.java new file mode 100644 index 000000000..a876334da --- /dev/null +++ b/app/src/main/java/ru/vtosters/lite/utils/OTAHelper.java @@ -0,0 +1,126 @@ +package ru.vtosters.lite.utils; + +import android.util.Log; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class OTAHelper { + + private static final String LATEST_RELEASE_URL = "https://api.github.com/repositories/473685743/releases/latest"; + private static final String LATEST_RELEASE_COMMIT_URL = "https://api.github.com/repositories/473685743/git/ref/tags/%s"; + + private OTAListener mListener; + + private final OkHttpClient mClient = new OkHttpClient(); + + private JSONObject mReleaseJson; + private JSONObject mCommitJson; + + public OTAHelper(OTAListener listener) { + this.mListener = listener; + } + + public void loadData() { + Request release = new Request.Builder() + .url(LATEST_RELEASE_URL) + .build(); + mClient.newCall(release).a(new Callback() { + @Override + public void a(Call call, IOException e) { + Log.d("OTAHelper", "Error while getting latest release info: " + e); + mListener.onUpdateCanceled(); + } + + @Override + public void a(Call call, Response response) throws IOException { + try { + setData(response); + } catch (JSONException | NullPointerException e) { + e.printStackTrace(); + } + + } + }); + } + + void setData(Response response) throws IOException, JSONException { + mReleaseJson = new JSONObject(response.body().string()); + + String tag = mReleaseJson.getString("tag_name"); + Request commit = new Request.Builder() + .url(String.format(LATEST_RELEASE_COMMIT_URL, tag)) + .build(); + mClient.newCall(commit).a(new Callback() { + @Override + public void a(Call call, IOException e) { + Log.d("OTAHelper", "Error while getting latest commit info: " + e); + mListener.onUpdateCanceled(); + } + + @Override + public void a(Call call, Response response) throws IOException { + try { + mCommitJson = new JSONObject(response.body().string()); + if (isNewVersion()) + mListener.onUpdateApplied(); + else mListener.onUpdateCanceled(); + } catch (NullPointerException | JSONException e) { + e.printStackTrace(); + mListener.onUpdateCanceled(); + } + } + }); + } + + public boolean isNewVersion() { + try { + String commitSHA = mCommitJson.getJSONObject("object").getString("sha"); + return !commitSHA.startsWith(About.getBuildNumber()); + } catch (Exception e) { + return false; + } + } + + public String getNewVersionName() { + try { + return mReleaseJson.getString("name"); + } catch (JSONException e) { + return null; + } + } + + public String getUpdateDescription() { + try { + return mReleaseJson.getString("body"); + } catch (JSONException e) { + return null; + } + } + + public String getDownloadUrl() { + try { + return mReleaseJson.getJSONArray("assets") + .getJSONObject(0) + .getString("browser_download_url"); + } catch (JSONException e) { + return null; + } + } + + public interface OTAListener { + + void onUpdateApplied(); + + void onUpdateCanceled(); + + } +} diff --git a/smali/AndroidManifest.xml b/smali/AndroidManifest.xml index 8bd0404e5..f4a78b7f2 100644 --- a/smali/AndroidManifest.xml +++ b/smali/AndroidManifest.xml @@ -66,7 +66,7 @@ - + From c98609db5db24a8a08dae592f1e1ac42fee561d1 Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Wed, 15 Jun 2022 17:13:18 +0300 Subject: [PATCH 2/6] fixes --- app/src/main/java/com/vtosters/lite/R.java | 2 +- .../lite/ui/{fragments => dialogs}/OTADialog.java | 4 +--- .../ru/vtosters/lite/ui/fragments/VTSettings.java | 14 ++++++++++++-- .../main/java/ru/vtosters/lite/utils/Globals.java | 14 ++++++++++++++ .../java/ru/vtosters/lite/utils/Preferences.java | 4 ++++ smali/res/values-ru/strings.xml | 4 +++- smali/res/values/public.xml | 2 +- smali/res/values/strings.xml | 5 ++++- .../com/vtosters/lite/MainActivity.smali | 6 +----- 9 files changed, 41 insertions(+), 14 deletions(-) rename app/src/main/java/ru/vtosters/lite/ui/{fragments => dialogs}/OTADialog.java (92%) diff --git a/app/src/main/java/com/vtosters/lite/R.java b/app/src/main/java/com/vtosters/lite/R.java index b4c5e9c75..bcfc8f5aa 100644 --- a/app/src/main/java/com/vtosters/lite/R.java +++ b/app/src/main/java/com/vtosters/lite/R.java @@ -15007,7 +15007,7 @@ public final class R { public static final int dockbar_save = 0x7f11123b; public static final int dockbar_selected_items = 0x7f11123c; public static final int dockbar_unselected_items = 0x7f11123d; - public static final int download_latest_vtl = 0x7f11123e; + public static final int checkforupdates = 0x7f11123e; public static final int other_fix_dynamic_colors = 0x7f11123f; public static final int other_reset_settings = 0x7f111240; public static final int other_reset_settings_summary = 0x7f111241; diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/OTADialog.java b/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java similarity index 92% rename from app/src/main/java/ru/vtosters/lite/ui/fragments/OTADialog.java rename to app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java index 13d98dd5a..12aac90b9 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/OTADialog.java +++ b/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java @@ -1,8 +1,6 @@ -package ru.vtosters.lite.ui.fragments; +package ru.vtosters.lite.ui.dialogs; import android.app.Activity; -import android.app.ProgressDialog; -import android.content.Context; import android.widget.Toast; import com.vk.core.dialogs.VKProgressDialog; diff --git a/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java b/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java index 06bfabeff..722afcbbf 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java +++ b/app/src/main/java/ru/vtosters/lite/ui/fragments/VTSettings.java @@ -56,6 +56,7 @@ import com.vtosters.lite.fragments.k.BlacklistFragment; import com.vtosters.lite.fragments.money.music.control.subscription.MusicSubscriptionControlFragment; import ru.vtosters.lite.ui.PreferencesUtil; +import ru.vtosters.lite.ui.dialogs.OTADialog; import ru.vtosters.lite.ui.fragments.dockbar.DockBarFragment; import ru.vtosters.lite.ui.fragments.dockbar.DockBarManager; import ru.vtosters.lite.ui.fragments.multiaccount.MultiAccountFragment; @@ -336,11 +337,20 @@ public class VTSettings extends MaterialPreferenceToolbarFragment { return false; }); - PreferencesUtil.addPreference(this, "", getString("download_latest_vtl"), "", "ic_download_24", preference -> { -// getContext().startActivity(new Intent("android.intent.action.VIEW").setData(Uri.parse("https://github.com/vtosters/lite/releases/latest"))); + PreferencesUtil.addPreferenceCategory(this, getString("updates")); + + PreferencesUtil.addPreference(this, "", getString("checkforupdates"), "", "ic_download_24", preference -> { OTADialog.checkUpdates(p()); return false; }); + + PreferencesUtil.addMaterialSwitchPreference(this, "checkupdates", getString("checkupdates"), "", "ic_recent_24", true, (preference, o) -> { + boolean value = (boolean) o; + + edit().putBoolean("checkupdates", value).commit(); + + return true; + }); } public static String getValAsString(String stringid, Boolean value) { diff --git a/app/src/main/java/ru/vtosters/lite/utils/Globals.java b/app/src/main/java/ru/vtosters/lite/utils/Globals.java index 5cc38cb6b..8d53c81e5 100644 --- a/app/src/main/java/ru/vtosters/lite/utils/Globals.java +++ b/app/src/main/java/ru/vtosters/lite/utils/Globals.java @@ -1,6 +1,7 @@ package ru.vtosters.lite.utils; import static androidx.core.content.ContextCompat.getDrawable; +import static ru.vtosters.lite.utils.Preferences.checkupdates; import static ru.vtosters.lite.utils.Preferences.getLocale; import static ru.vtosters.lite.utils.Preferences.preferences; import static ru.vtosters.lite.utils.Themes.isDarkTheme; @@ -49,6 +50,11 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import ru.vtosters.lite.ui.dialogs.DisableBattery; +import ru.vtosters.lite.ui.dialogs.InstallGMS; +import ru.vtosters.lite.ui.dialogs.Start; +import ru.vtosters.lite.ui.dialogs.OTADialog; + public class Globals { private static final List activities = new ArrayList<>(); @@ -57,6 +63,14 @@ public class Globals { return preferences; } + public static void MainActivityInit(Activity activity) { + if(checkupdates()) + OTADialog.checkUpdates(activity); + Start.alert(activity); + InstallGMS.alert(activity); + DisableBattery.alert(activity); + } + public static void componentSwitcher(String component, Boolean enabled) { var packageManager = getContext().getPackageManager(); packageManager.setComponentEnabledSetting(new ComponentName(getPackageName(), getPackageName() + "." + component), enabled? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); diff --git a/app/src/main/java/ru/vtosters/lite/utils/Preferences.java b/app/src/main/java/ru/vtosters/lite/utils/Preferences.java index 3935887d4..d9481362e 100644 --- a/app/src/main/java/ru/vtosters/lite/utils/Preferences.java +++ b/app/src/main/java/ru/vtosters/lite/utils/Preferences.java @@ -361,6 +361,10 @@ public class Preferences { return getBoolValue("roundedmsgs", false); } + public static boolean checkupdates() { + return getBoolValue("checkupdates", true); + } + public static boolean disableanimstickers() { return getBoolValue("disableanimstickers", true); } diff --git a/smali/res/values-ru/strings.xml b/smali/res/values-ru/strings.xml index cdfbbf8ab..731a9eb8f 100644 --- a/smali/res/values-ru/strings.xml +++ b/smali/res/values-ru/strings.xml @@ -4337,7 +4337,7 @@ Добавить новый аккаунт - Скачать последнюю версию + Проверить обновления Внимание! Данное меню предназначено только для тестирования работоспособности приложения. Если вы являетесь рядовым юзером, то вам не следует ничего не трогать в данных настройках (пожалуйста) @@ -4474,6 +4474,8 @@ Скрыть подписи в настройках Есть доступ + Авто обновления + Обновления diff --git a/smali/res/values/public.xml b/smali/res/values/public.xml index 9d41ff2eb..98cebb92c 100644 --- a/smali/res/values/public.xml +++ b/smali/res/values/public.xml @@ -14953,7 +14953,7 @@ - + diff --git a/smali/res/values/strings.xml b/smali/res/values/strings.xml index 1422c9e5c..df4a31456 100644 --- a/smali/res/values/strings.xml +++ b/smali/res/values/strings.xml @@ -4463,7 +4463,7 @@ May look like a fake leaving the online" Add new account - Download latest version + Check for updates Warning! These options are for testing this app only. If you are a regular user, please, don\'t use them @@ -4608,6 +4608,9 @@ May look like a fake leaving the online" Hide settings summaries Have access + Auto updates + Updates + diff --git a/smali/smali_classes3/com/vtosters/lite/MainActivity.smali b/smali/smali_classes3/com/vtosters/lite/MainActivity.smali index 1916f7027..5ec417aa7 100644 --- a/smali/smali_classes3/com/vtosters/lite/MainActivity.smali +++ b/smali/smali_classes3/com/vtosters/lite/MainActivity.smali @@ -566,11 +566,7 @@ .line 65 :cond_0 - invoke-static {p0}, Lru/vtosters/lite/ui/dialogs/Start;->alert(Landroid/app/Activity;)V - - invoke-static {p0}, Lru/vtosters/lite/ui/dialogs/InstallGMS;->alert(Landroid/app/Activity;)V - - invoke-static {p0}, Lru/vtosters/lite/ui/dialogs/DisableBattery;->alert(Landroid/app/Activity;)V + invoke-static {p0}, Lru/vtosters/lite/utils/Globals;->MainActivityInit(Landroid/app/Activity;)V invoke-virtual {p0}, Lcom/vtosters/lite/MainActivity;->getWindow()Landroid/view/Window; From 986ec2987cf0e4f26151214cb9ebbc0692e100fe Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Wed, 15 Jun 2022 17:20:01 +0300 Subject: [PATCH 3/6] wtf debuggable must be false --- smali/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smali/AndroidManifest.xml b/smali/AndroidManifest.xml index f4a78b7f2..8bd0404e5 100644 --- a/smali/AndroidManifest.xml +++ b/smali/AndroidManifest.xml @@ -66,7 +66,7 @@ - + From 6e3716fe01ceb56568a3a8f1d18c8067b0ed4ee8 Mon Sep 17 00:00:00 2001 From: Vologhat <47892605+Vologhat@users.noreply.github.com> Date: Wed, 15 Jun 2022 21:29:09 +0300 Subject: [PATCH 4/6] final changes added apk downloading and installing features, bottomshit wrapper with mirroring --- .../lite/downloaders/OTADownloader.java | 56 +++++++++++ .../ui/activities/APKInstallActivity.java | 82 ++++++++++++++++ .../vtosters/lite/ui/dialogs/OTADialog.java | 18 ++-- .../lite/ui/vkui/ModalBottomSheetProxy.java | 50 ---------- .../lite/ui/vkui/ModalBottomSheetWrapper.java | 97 +++++++++++++++++++ smali/AndroidManifest.xml | 1 + 6 files changed, 246 insertions(+), 58 deletions(-) create mode 100644 app/src/main/java/ru/vtosters/lite/downloaders/OTADownloader.java create mode 100644 app/src/main/java/ru/vtosters/lite/ui/activities/APKInstallActivity.java delete mode 100644 app/src/main/java/ru/vtosters/lite/ui/vkui/ModalBottomSheetProxy.java create mode 100644 app/src/main/java/ru/vtosters/lite/ui/vkui/ModalBottomSheetWrapper.java diff --git a/app/src/main/java/ru/vtosters/lite/downloaders/OTADownloader.java b/app/src/main/java/ru/vtosters/lite/downloaders/OTADownloader.java new file mode 100644 index 000000000..e866e57f7 --- /dev/null +++ b/app/src/main/java/ru/vtosters/lite/downloaders/OTADownloader.java @@ -0,0 +1,56 @@ +package ru.vtosters.lite.downloaders; + +import android.app.DownloadManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.Uri; +import android.os.Environment; +import android.widget.HeaderViewListAdapter; + +import ru.vtosters.lite.ui.activities.APKInstallActivity; +import ru.vtosters.lite.ui.vkui.ModalBottomSheetWrapper; +import ru.vtosters.lite.utils.Globals; + +public class OTADownloader { + + private static BroadcastReceiver callback = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + var extras = intent.getExtras(); + if (extras == null + || !intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) return; + + var query = new DownloadManager.Query(); + long id = extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID); + query.setFilterById(id); + var manager = (DownloadManager) Globals.getContext().getSystemService(Context.DOWNLOAD_SERVICE); + var cursor = manager.query(query); + if (cursor.moveToFirst()) { + var status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); + if (status == DownloadManager.STATUS_SUCCESSFUL) { + var uri = Uri.parse(cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_URI))); + APKInstallActivity.installOta(Globals.getContext(), uri); + } else if (status == DownloadManager.STATUS_FAILED) { + + } + } + } + }; + + public static void downloadBuild(String url) { + var context = Globals.getContext(); + var uri = Uri.parse(url); + + context.registerReceiver(callback, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); + + var request = new DownloadManager.Request(uri); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + request.setTitle("VTLite.apk"); + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "VTLite.apk"); + + var manager = (DownloadManager) Globals.getContext().getSystemService(Context.DOWNLOAD_SERVICE); + manager.enqueue(request); + } +} diff --git a/app/src/main/java/ru/vtosters/lite/ui/activities/APKInstallActivity.java b/app/src/main/java/ru/vtosters/lite/ui/activities/APKInstallActivity.java new file mode 100644 index 000000000..3dd5f7987 --- /dev/null +++ b/app/src/main/java/ru/vtosters/lite/ui/activities/APKInstallActivity.java @@ -0,0 +1,82 @@ +package ru.vtosters.lite.ui.activities; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.provider.Settings; +import android.widget.Toast; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +public class APKInstallActivity extends AppCompatActivity { + public static final int REQUEST_INSTALL_PERMISSION = 1; + + public static final String EXTRA_APK_URI = "apk_uri"; + + private Uri mApkUri; + + public static void installOta(Context context, Uri apkUri) { + Intent intent = new Intent(context, APKInstallActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.putExtra(EXTRA_APK_URI, apkUri); + + context.startActivity(intent); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent intent = getIntent(); + if (intent == null) { + Toast.makeText(this, "No intent", Toast.LENGTH_SHORT).show(); + finish(); + return; + } + + mApkUri = intent.getParcelableExtra(EXTRA_APK_URI); + if (mApkUri == null) { + Toast.makeText(this, "No apk uri", Toast.LENGTH_SHORT).show(); + finish(); + return; + } + + installApk(); + } + + private void installApk() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (!getPackageManager().canRequestPackageInstalls()) { + Intent permIntent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + getPackageName())); + startActivityForResult(permIntent, REQUEST_INSTALL_PERMISSION); + return; + } + } + + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(mApkUri, "application/vnd.android.package-archive"); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + startActivity(intent); + } catch (Exception e) { + Toast.makeText(this, "Ошибка установки обновления " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); + } + + finish(); + } + + + @Override + public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == REQUEST_INSTALL_PERMISSION) + installApk(); + } +} diff --git a/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java b/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java index 12aac90b9..1d3c568c3 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java +++ b/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java @@ -1,16 +1,19 @@ package ru.vtosters.lite.ui.dialogs; import android.app.Activity; +import android.text.Html; import android.widget.Toast; import com.vk.core.dialogs.VKProgressDialog; +import ru.vtosters.lite.downloaders.OTADownloader; +import ru.vtosters.lite.ui.vkui.ModalBottomSheetWrapper; +import ru.vtosters.lite.utils.Globals; import ru.vtosters.lite.utils.OTAHelper; public class OTADialog implements OTAHelper.OTAListener { private Activity mActivity; - private VKProgressDialog mProgressDialog; private OTAHelper mHelper; @@ -21,11 +24,6 @@ public class OTADialog implements OTAHelper.OTAListener { public OTADialog(Activity activity) { mActivity = activity; - mProgressDialog = new VKProgressDialog(activity); - mProgressDialog.setTitle("Проверка обновлений..."); - mProgressDialog.setCancelable(false); - mProgressDialog.show(); - mHelper = new OTAHelper(this); mHelper.loadData(); } @@ -34,7 +32,12 @@ public class OTADialog implements OTAHelper.OTAListener { public void onUpdateApplied() { mActivity.runOnUiThread(() -> { Toast.makeText(mActivity, "Обновления найдены", Toast.LENGTH_SHORT).show(); - mProgressDialog.dismiss(); + new ModalBottomSheetWrapper(mActivity) + .setUpdateInfoView(mHelper.getNewVersionName(), mHelper.getUpdateDescription()) + .setPositiveButton("Обновить", () -> { + OTADownloader.downloadBuild(mHelper.getDownloadUrl()); + }) + .show(); }); } @@ -42,7 +45,6 @@ public class OTADialog implements OTAHelper.OTAListener { public void onUpdateCanceled() { mActivity.runOnUiThread(() -> { Toast.makeText(mActivity, "Обновлений не найдено", Toast.LENGTH_SHORT).show(); - mProgressDialog.dismiss(); }); } } diff --git a/app/src/main/java/ru/vtosters/lite/ui/vkui/ModalBottomSheetProxy.java b/app/src/main/java/ru/vtosters/lite/ui/vkui/ModalBottomSheetProxy.java deleted file mode 100644 index 44fee4e18..000000000 --- a/app/src/main/java/ru/vtosters/lite/ui/vkui/ModalBottomSheetProxy.java +++ /dev/null @@ -1,50 +0,0 @@ -package ru.vtosters.lite.ui.vkui; - -import android.app.Activity; -import android.view.View; - -import com.vk.core.dialogs.bottomsheet.ModalBottomSheet; - -public class ModalBottomSheetProxy { - public final ModalBottomSheet.a builder; - - public ModalBottomSheetProxy(Activity activity) { - builder = new ModalBottomSheet.a(activity); - } - - public void setTitle(String title) { - builder.b(title); - } - - - public void setClickableMessage(String text) { - builder.a(text, kostil -> { - }); - } - - public void setClickableMessage(String text, Runnable runnable) { - builder.a(text, listener -> runnable.run()); - } - - public void setPositiveButton(String text, Runnable runnable) { - builder.b(text, kostil -> runnable.run()); - } - - public void setSubtitle(String text) { - builder.b((CharSequence) text); - } - - public void setView(View view) { - builder.a(view); - } - - public ModalBottomSheet show() { - return builder.c(null); - } - - public ModalBottomSheet show(boolean isCancellable) { - var sheet = builder.c(null); - sheet.b(isCancellable); - return sheet; - } -} diff --git a/app/src/main/java/ru/vtosters/lite/ui/vkui/ModalBottomSheetWrapper.java b/app/src/main/java/ru/vtosters/lite/ui/vkui/ModalBottomSheetWrapper.java new file mode 100644 index 000000000..8fe60119b --- /dev/null +++ b/app/src/main/java/ru/vtosters/lite/ui/vkui/ModalBottomSheetWrapper.java @@ -0,0 +1,97 @@ +package ru.vtosters.lite.ui.vkui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Typeface; +import android.util.TypedValue; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.vk.core.dialogs.bottomsheet.ModalBottomSheet; + +import ru.vtosters.lite.utils.Globals; +import ru.vtosters.lite.utils.Themes; + +public class ModalBottomSheetWrapper { + public final ModalBottomSheet.a builder; + + public ModalBottomSheetWrapper(Activity activity) { + builder = new ModalBottomSheet.a(activity); + } + + public ModalBottomSheetWrapper setTitle(String title) { + builder.b(title); + return this; + } + + public ModalBottomSheetWrapper setUpdateInfoView(String version, String changelog) { + var context = Globals.getContext(); + var container = new LinearLayout(context); + var title = new TextView(context); + var changelogView = new TextView(context); + + container.setOrientation(LinearLayout.VERTICAL); + + title.setText("Новая версия " + version); + title.setTypeface(title.getTypeface(), Typeface.BOLD); + title.setSingleLine(true); + title.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + title.setTextColor(Themes.getTextAttr()); + title.setTextSize(24.0f); + container.addView(title, new LinearLayout.LayoutParams(-1, -2)); + + changelogView.setPadding(0, Globals.convertDpToPixel(8), 0, 0); + changelogView.setText("Изменения: \n" + changelog); + changelogView.setTextColor(Themes.getTextAttr()); + container.addView(changelogView, new LinearLayout.LayoutParams(-1, -2)); + + builder.a(container); + + return this; + } + + // try to call a true function and you will understand my pain + public ModalBottomSheetWrapper setMessage( + String text + ) { + builder.a(text, listener -> {}); + return this; + } + + public ModalBottomSheetWrapper setClickableMessage( + String text, + Runnable callback + ) { + builder.a(text, listener -> callback.run()); + return this; + } + + public ModalBottomSheetWrapper setPositiveButton( + String text, + Runnable callback + ) { + builder.b(text, kostil -> callback.run()); + return this; + } + + public ModalBottomSheetWrapper setSubtitle(String text) { + builder.b((CharSequence) text); + return this; + } + + public ModalBottomSheetWrapper setView(View view) { + builder.a(view); + return this; + } + + public ModalBottomSheet show() { + return builder.c(null); + } + + public ModalBottomSheet show(boolean isCancellable) { + var sheet = builder.c(null); + sheet.b(isCancellable); + return sheet; + } +} diff --git a/smali/AndroidManifest.xml b/smali/AndroidManifest.xml index 8bd0404e5..c11c15108 100644 --- a/smali/AndroidManifest.xml +++ b/smali/AndroidManifest.xml @@ -75,6 +75,7 @@ + From ce64296c01d91a58c586e10a086dbd4a9558e842 Mon Sep 17 00:00:00 2001 From: gdlbo <41114720+gdlbo@users.noreply.github.com> Date: Wed, 15 Jun 2022 21:47:21 +0300 Subject: [PATCH 5/6] kill androidx --- .../vtosters/lite/ui/activities/APKInstallActivity.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/ru/vtosters/lite/ui/activities/APKInstallActivity.java b/app/src/main/java/ru/vtosters/lite/ui/activities/APKInstallActivity.java index 3dd5f7987..5fddc903e 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/activities/APKInstallActivity.java +++ b/app/src/main/java/ru/vtosters/lite/ui/activities/APKInstallActivity.java @@ -6,11 +6,9 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.Settings; +import android.support.v7.app.AppCompatActivity; import android.widget.Toast; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; - public class APKInstallActivity extends AppCompatActivity { public static final int REQUEST_INSTALL_PERMISSION = 1; @@ -28,7 +26,7 @@ public class APKInstallActivity extends AppCompatActivity { } @Override - public void onCreate(@Nullable Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); @@ -73,7 +71,7 @@ public class APKInstallActivity extends AppCompatActivity { @Override - public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_INSTALL_PERMISSION) From 1b02e806f8475949e61cb94ef21380bdd9816702 Mon Sep 17 00:00:00 2001 From: Vologhat <47892605+Vologhat@users.noreply.github.com> Date: Thu, 16 Jun 2022 00:04:34 +0300 Subject: [PATCH 6/6] Final fixes --- .../lite/downloaders/OTADownloader.java | 28 ++++++++++++++----- .../vtosters/lite/ui/dialogs/OTADialog.java | 4 --- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/ru/vtosters/lite/downloaders/OTADownloader.java b/app/src/main/java/ru/vtosters/lite/downloaders/OTADownloader.java index e866e57f7..6171d2e61 100644 --- a/app/src/main/java/ru/vtosters/lite/downloaders/OTADownloader.java +++ b/app/src/main/java/ru/vtosters/lite/downloaders/OTADownloader.java @@ -7,15 +7,17 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Environment; -import android.widget.HeaderViewListAdapter; + +import com.vk.core.f.FileUtils; + +import java.io.File; import ru.vtosters.lite.ui.activities.APKInstallActivity; -import ru.vtosters.lite.ui.vkui.ModalBottomSheetWrapper; import ru.vtosters.lite.utils.Globals; public class OTADownloader { - private static BroadcastReceiver callback = new BroadcastReceiver() { + private static final BroadcastReceiver callback = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { var extras = intent.getExtras(); @@ -23,17 +25,28 @@ public class OTADownloader { || !intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) return; var query = new DownloadManager.Query(); - long id = extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID); + var id = extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID); query.setFilterById(id); var manager = (DownloadManager) Globals.getContext().getSystemService(Context.DOWNLOAD_SERVICE); var cursor = manager.query(query); if (cursor.moveToFirst()) { var status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); if (status == DownloadManager.STATUS_SUCCESSFUL) { - var uri = Uri.parse(cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_URI))); - APKInstallActivity.installOta(Globals.getContext(), uri); + var downloadDir = new File(Environment.getExternalStorageDirectory(), "Download"); + if (!downloadDir.exists()) return; + var list = downloadDir.listFiles(); + if (list == null || list.length == 0) return; + var maxIndex = -1; + for (File file : list) { + var name = file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf("/") + 1); + if (file.isFile() + && name.matches("VTLite-\\d+\\.apk")) + maxIndex = Math.max(maxIndex, Integer.parseInt(name.replaceFirst(".+-(\\d+).+", "$1"))); + } + File apk = maxIndex == -1 ? new File(downloadDir, "VTLite.apk") : new File(downloadDir, "VTLite-" + maxIndex + ".apk"); + APKInstallActivity.installOta(context, FileUtils.h(apk)); } else if (status == DownloadManager.STATUS_FAILED) { - + // do something } } } @@ -41,6 +54,7 @@ public class OTADownloader { public static void downloadBuild(String url) { var context = Globals.getContext(); + url = "https://github.com/vtosters/lite/releases/download/v0.2.9-beta2/VTLite.apk"; var uri = Uri.parse(url); context.registerReceiver(callback, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); diff --git a/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java b/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java index 1d3c568c3..75f4b51f2 100644 --- a/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java +++ b/app/src/main/java/ru/vtosters/lite/ui/dialogs/OTADialog.java @@ -1,14 +1,10 @@ package ru.vtosters.lite.ui.dialogs; import android.app.Activity; -import android.text.Html; import android.widget.Toast; -import com.vk.core.dialogs.VKProgressDialog; - import ru.vtosters.lite.downloaders.OTADownloader; import ru.vtosters.lite.ui.vkui.ModalBottomSheetWrapper; -import ru.vtosters.lite.utils.Globals; import ru.vtosters.lite.utils.OTAHelper; public class OTADialog implements OTAHelper.OTAListener {