final changes
added apk downloading and installing features, bottomshit wrapper with mirroring
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -75,6 +75,7 @@
|
||||
<meta-data android:name="com.facebook.sdk.CodelessDebugLogEnabled" android:value="false"/>
|
||||
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
|
||||
<meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/cornflower_blue"/>
|
||||
<activity android:name="ru.vtosters.lite.ui.activities.APKInstallActivity" />
|
||||
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize" android:label="@string/app_name" android:launchMode="singleTask" android:name="com.vtosters.lite.MainActivity" android:theme="@style/SplashTheme">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.MULTIWINDOW_LAUNCHER"/>
|
||||
|
||||
Reference in New Issue
Block a user