[app] Check update (#768)
This commit is contained in:
parent
1eebbca320
commit
612c39d325
|
|
@ -21,6 +21,7 @@ import com.android.build.api.variant.impl.ApplicationVariantImpl
|
|||
import com.android.build.api.component.analytics.AnalyticsEnabledApplicationVariant
|
||||
import com.android.build.gradle.internal.dsl.BuildType
|
||||
import java.nio.file.Paths
|
||||
import java.time.Instant
|
||||
|
||||
plugins {
|
||||
id("org.gradle.idea")
|
||||
|
|
@ -88,6 +89,7 @@ android {
|
|||
"pt",
|
||||
"es",
|
||||
)
|
||||
buildConfigField("long", "BUILD_TIME", Instant.now().epochSecond.toString())
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ import android.util.Log;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import org.lsposed.hiddenapibypass.HiddenApiBypass;
|
||||
import org.lsposed.manager.repo.RepoLoader;
|
||||
import org.lsposed.manager.ui.activity.CrashReportActivity;
|
||||
|
|
@ -37,13 +39,20 @@ import org.lsposed.manager.util.DoHDNS;
|
|||
import org.lsposed.manager.util.theme.ThemeUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Locale;
|
||||
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import rikka.material.app.DayNightDelegate;
|
||||
|
||||
|
|
@ -63,9 +72,6 @@ public class App extends Application {
|
|||
private static Cache okHttpCache;
|
||||
private SharedPreferences pref;
|
||||
|
||||
public static final MediaType JSON
|
||||
= MediaType.get("application/json; charset=utf-8");
|
||||
|
||||
|
||||
public static App getInstance() {
|
||||
return instance;
|
||||
|
|
@ -117,6 +123,7 @@ public class App extends Application {
|
|||
DayNightDelegate.setApplicationContext(this);
|
||||
DayNightDelegate.setDefaultNightMode(ThemeUtil.getDarkTheme());
|
||||
RepoLoader.getInstance().loadRemoteData();
|
||||
loadRemoteVersion();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
@ -144,4 +151,51 @@ public class App extends Application {
|
|||
}
|
||||
return okHttpCache;
|
||||
}
|
||||
|
||||
private void loadRemoteVersion() {
|
||||
var request = new Request.Builder()
|
||||
.url("https://api.github.com/repos/LSPosed/LSPosed/releases/latest")
|
||||
.addHeader("Accept", "application/vnd.github.v3+json")
|
||||
.build();
|
||||
var callback = new Callback() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call call, @NonNull Response response) {
|
||||
if (!response.isSuccessful()) return;
|
||||
var body = response.body();
|
||||
if (body == null) return;
|
||||
try {
|
||||
var info = JsonParser.parseReader(body.charStream()).getAsJsonObject();
|
||||
var published = info.get("published_at").getAsString();
|
||||
var time = LocalDateTime.parse(published).toInstant(ZoneOffset.UTC).getEpochSecond();
|
||||
var now = Instant.now().getEpochSecond();
|
||||
pref.edit().putLong("latest_release", time).putLong("latest_check", now).apply();
|
||||
} catch (Throwable t) {
|
||||
Log.e(App.TAG, t.getMessage(), t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
||||
Log.e(App.TAG, e.getMessage(), e);
|
||||
}
|
||||
};
|
||||
getOkHttpClient().newCall(request).enqueue(callback);
|
||||
}
|
||||
|
||||
public static boolean needUpdate() {
|
||||
var now = Instant.now();
|
||||
var buildTime = Instant.ofEpochSecond(BuildConfig.BUILD_TIME);
|
||||
var check = getPreferences().getLong("latest_check", 0);
|
||||
if (check > 0) {
|
||||
var checkTime = Instant.ofEpochSecond(check);
|
||||
if (checkTime.atOffset(ZoneOffset.UTC).plusDays(30).toInstant().isBefore(now))
|
||||
return true;
|
||||
var release = getPreferences().getLong("latest_release", 0);
|
||||
if (release > 0) {
|
||||
var releaseTime = Instant.ofEpochSecond(release);
|
||||
return releaseTime.atOffset(ZoneOffset.UTC).minusDays(1).toInstant().isAfter(buildTime);
|
||||
}
|
||||
}
|
||||
return buildTime.atOffset(ZoneOffset.UTC).plusDays(30).toInstant().isBefore(now);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,9 +178,11 @@ public class RepoLoader {
|
|||
}
|
||||
|
||||
public interface Listener {
|
||||
void repoLoaded();
|
||||
default void repoLoaded() {
|
||||
}
|
||||
|
||||
void moduleReleasesLoaded(OnlineModule module);
|
||||
default void moduleReleasesLoaded(OnlineModule module) {
|
||||
}
|
||||
|
||||
void onThrowable(Throwable t);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ package org.lsposed.manager.ui.activity;
|
|||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
|
@ -51,7 +50,7 @@ public class CrashReportActivity extends AppCompatActivity {
|
|||
binding = ActivityCrashReportBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
binding.copyLogs.setOnClickListener(v -> {
|
||||
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
var clipboard = getSystemService(ClipboardManager.class);
|
||||
//Are there any devices without clipboard...?
|
||||
if (clipboard != null) {
|
||||
ClipData clip = ClipData.newPlainText("LSPManagerCrashInfo", getAllErrorDetailsFromIntent(getIntent()));
|
||||
|
|
@ -66,26 +65,29 @@ public class CrashReportActivity extends AppCompatActivity {
|
|||
Date currentDate = new Date();
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
|
||||
|
||||
String versionName = getVersionName();
|
||||
String versionName = String.format("%s (%s)", BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE);
|
||||
|
||||
String errorDetails = "";
|
||||
|
||||
errorDetails += "Build version: " + versionName + " \n";
|
||||
errorDetails += "Current date: " + dateFormat.format(currentDate) + " \n";
|
||||
errorDetails += "Device: " + getDeviceModelName() + " \n \n";
|
||||
errorDetails += "Device: " + getDeviceModelName() + " \n";
|
||||
errorDetails += "Fingerprint: " + getFingerprint() + " \n \n";
|
||||
errorDetails += "SDK: " + Build.VERSION.SDK_INT + " \n \n";
|
||||
errorDetails += "Stack trace: \n";
|
||||
errorDetails += getStackTraceFromIntent(intent);
|
||||
return errorDetails;
|
||||
}
|
||||
|
||||
private String getVersionName() {
|
||||
try {
|
||||
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
|
||||
return String.format("%s (%s)", packageInfo.versionName, packageInfo.versionCode);
|
||||
} catch (Exception e) {
|
||||
return "Unknown";
|
||||
}
|
||||
private String getFingerprint() {
|
||||
return Build.BRAND + '/' +
|
||||
Build.PRODUCT + '/' +
|
||||
Build.DEVICE + ':' +
|
||||
Build.VERSION.RELEASE + '/' +
|
||||
Build.ID + '/' +
|
||||
Build.VERSION.INCREMENTAL + ':' +
|
||||
Build.TYPE + '/' +
|
||||
Build.TAGS;
|
||||
}
|
||||
|
||||
private String getDeviceModelName() {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import androidx.core.text.HtmlCompat;
|
|||
import com.bumptech.glide.Glide;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import org.lsposed.manager.App;
|
||||
import org.lsposed.manager.BuildConfig;
|
||||
import org.lsposed.manager.ConfigManager;
|
||||
import org.lsposed.manager.R;
|
||||
|
|
@ -118,6 +119,11 @@ public class HomeFragment extends BaseFragment {
|
|||
cardBackgroundColor = ResourcesKt.resolveColor(activity.getTheme(), R.attr.colorWarning);
|
||||
binding.statusIcon.setImageResource(R.drawable.ic_warning);
|
||||
binding.statusSummary.setText(R.string.system_prop_incorrect_summary);
|
||||
} else if (App.needUpdate()) {
|
||||
binding.statusTitle.setText(R.string.need_update);
|
||||
cardBackgroundColor = ResourcesKt.resolveColor(activity.getTheme(), R.attr.colorWarning);
|
||||
binding.statusIcon.setImageResource(R.drawable.ic_warning);
|
||||
binding.statusSummary.setText(R.string.please_update_summary);
|
||||
} else {
|
||||
binding.statusTitle.setText(R.string.activated);
|
||||
cardBackgroundColor = ResourcesKt.resolveColor(activity.getTheme(), R.attr.colorNormal);
|
||||
|
|
|
|||
|
|
@ -147,11 +147,6 @@ public class RepoFragment extends BaseFragment implements RepoLoader.Listener {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moduleReleasesLoaded(OnlineModule module) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThrowable(Throwable t) {
|
||||
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) {
|
||||
|
|
@ -202,9 +197,7 @@ public class RepoFragment extends BaseFragment implements RepoLoader.Listener {
|
|||
sb.append(summary);
|
||||
}
|
||||
holder.appDescription.setText(sb);
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
getNavController().navigate(RepoFragmentDirections.actionRepoFragmentToRepoItemFragment(module.getName(), module.getDescription()));
|
||||
});
|
||||
holder.itemView.setOnClickListener(v -> getNavController().navigate(RepoFragmentDirections.actionRepoFragmentToRepoItemFragment(module.getName(), module.getDescription())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -31,9 +31,7 @@ import android.view.LayoutInflater;
|
|||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.RenderProcessGoneDetail;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
|
@ -195,11 +193,6 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene
|
|||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repoLoaded() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moduleReleasesLoaded(OnlineModule module) {
|
||||
this.module = module;
|
||||
|
|
|
|||
|
|
@ -39,12 +39,14 @@
|
|||
<string name="activated">已激活</string>
|
||||
<string name="not_installed">未安装</string>
|
||||
<string name="partial_activated">部分激活</string>
|
||||
<string name="need_update">需要更新</string>
|
||||
<string name="selinux_policy_not_loaded_summary">SEPolicy 未被正确加载</string>
|
||||
<string name="selinux_policy_not_loaded"><![CDATA[<b>警告:</b>SEPolicy 未被正确加载,作用于系统框架的模块将不起作用。<br>请将此报告给 <a href="https://github.com/topjohnwu/Magisk/issues"><b>Magisk</b></a> 开发者。]]></string>
|
||||
<string name="system_inject_fail_summary">系统框架注入失败</string>
|
||||
<string name="system_inject_fail"><![CDATA[<b>警告:</b>系统注入失败。<br/>这是极罕见的情况,可能是由 <b>Magisk</b> 或低质 Magisk 模块导致。<br/>请尝试禁用除 Riru 和 LSPosed 外的 Magisk 模块,或向开发者提供完整日志。]]></string>
|
||||
<string name="system_prop_incorrect_summary">系统属性异常</string>
|
||||
<string name="system_prop_incorrect"><![CDATA[<b>警告:</b>系统属性异常。<br/>一些必须的系统属性被删除或被修改。<br/>模块可能会随机失效。]]></string>
|
||||
<string name="please_update_summary">请安装新版 LSPosed</string>
|
||||
<string name="info_api_version">API 版本</string>
|
||||
<string name="info_framework_version">框架版本</string>
|
||||
<string name="info_manager_version">管理器版本</string>
|
||||
|
|
|
|||
|
|
@ -39,12 +39,14 @@
|
|||
<string name="activated">Activated</string>
|
||||
<string name="not_installed">Not installed</string>
|
||||
<string name="partial_activated">Partially activated</string>
|
||||
<string name="need_update">Need to update</string>
|
||||
<string name="selinux_policy_not_loaded_summary">SEPolicy is not loaded properly</string>
|
||||
<string name="selinux_policy_not_loaded"><![CDATA[<b>WARNING:</b> SEPolicy is not loaded properly, modules that hook System Framework will not work.<br/>Please report this to <a href="https://github.com/topjohnwu/Magisk/issues"><b>Magisk</b></a> developer.]]></string>
|
||||
<string name="system_inject_fail_summary">System Framework injection failed</string>
|
||||
<string name="system_inject_fail"><![CDATA[<b>WARNING:</b> System Framework inject failed.<br/>This is rare and may be caused by <b>Magisk</b> or some low-quality Magisk modules.<br/>Please try to disable Magisk modules other than Riru and LSPosed or submit full log to developers.]]></string>
|
||||
<string name="system_prop_incorrect_summary">System prop incorrect</string>
|
||||
<string name="system_prop_incorrect"><![CDATA[<b>WARNING:</b> System prop incorrect.<br/>Some necessary system properties deleted or modified.<br/>Modules may invalidate occasionally.]]></string>
|
||||
<string name="please_update_summary">Please install the latest version of LSPosed</string>
|
||||
<string name="info_api_version">API version</string>
|
||||
<string name="info_framework_version">Framework version</string>
|
||||
<string name="info_manager_version">Manager version</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue