From b0fa3216069a3709431259ef3fdbf13ddc6d1d56 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] 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 @@ +