From fac904009db2df6f77864ab22d6bec71f33e67ec Mon Sep 17 00:00:00 2001
From: NekoInverter <42698724+NekoInverter@users.noreply.github.com>
Date: Thu, 6 Feb 2020 17:24:23 +0800
Subject: [PATCH] Fix possible crash & add crash report activity
---
app/src/main/AndroidManifest.xml | 3 +
.../edxposed/manager/BaseActivity.java | 31 +--
.../edxposed/manager/CrashReportActivity.java | 120 ++++++++++
.../edxposed/manager/DownloadActivity.java | 11 +-
.../DownloadDetailsVersionsFragment.java | 3 +-
.../edxposed/manager/ModulesActivity.java | 215 +++++++-----------
.../meowcat/edxposed/manager/XposedApp.java | 27 +++
.../main/res/layout/activity_crash_report.xml | 70 ++++++
app/src/main/res/layout/activity_download.xml | 5 +-
app/src/main/res/menu/menu_app_list.xml | 44 ++++
app/src/main/res/menu/menu_installer.xml | 73 +++---
app/src/main/res/values-zh-rCN/strings.xml | 1 +
app/src/main/res/values-zh-rHK/strings.xml | 1 +
app/src/main/res/values-zh-rTW/strings.xml | 1 +
app/src/main/res/values/strings.xml | 1 +
15 files changed, 417 insertions(+), 189 deletions(-)
create mode 100644 app/src/main/java/org/meowcat/edxposed/manager/CrashReportActivity.java
create mode 100644 app/src/main/res/layout/activity_crash_report.xml
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8a76842c..512c456b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -21,6 +21,9 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
+
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/BaseActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/BaseActivity.java
index 26f45f6f..76e15382 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/BaseActivity.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/BaseActivity.java
@@ -13,13 +13,11 @@ import android.os.Looper;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
-import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
-import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.app.ActivityCompat;
@@ -119,8 +117,10 @@ public class BaseActivity extends AppCompatActivity {
}
void softReboot() {
- if (startShell())
+ if (!Shell.rootAccess()) {
+ showAlert(getString(R.string.root_failed));
return;
+ }
List messages = new LinkedList<>();
Shell.Result result = Shell.su("setprop ctl.restart surfaceflinger; setprop ctl.restart zygote").exec();
@@ -132,29 +132,16 @@ public class BaseActivity extends AppCompatActivity {
}
}
- private boolean startShell() {
- if (Shell.rootAccess())
- return false;
-
- showAlert(getString(R.string.root_failed));
- return true;
- }
-
void showAlert(final String result) {
if (Looper.myLooper() != Looper.getMainLooper()) {
runOnUiThread(() -> showAlert(result));
return;
}
- AlertDialog dialog = new MaterialAlertDialogBuilder(this).setMessage(result).setPositiveButton(android.R.string.ok, null).create();
- dialog.show();
-
- TextView txtMessage = dialog
- .findViewById(android.R.id.message);
- try {
- txtMessage.setTextSize(14);
- } catch (NullPointerException ignored) {
- }
+ new MaterialAlertDialogBuilder(this)
+ .setMessage(result)
+ .setPositiveButton(android.R.string.ok, null)
+ .show();
}
public boolean checkPermissions() {
@@ -168,8 +155,10 @@ public class BaseActivity extends AppCompatActivity {
}
void reboot(String mode) {
- if (startShell())
+ if (!Shell.rootAccess()) {
+ showAlert(getString(R.string.root_failed));
return;
+ }
List messages = new LinkedList<>();
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/CrashReportActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/CrashReportActivity.java
new file mode 100644
index 00000000..3456bd11
--- /dev/null
+++ b/app/src/main/java/org/meowcat/edxposed/manager/CrashReportActivity.java
@@ -0,0 +1,120 @@
+package org.meowcat.edxposed.manager;
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.os.Build;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.google.android.material.snackbar.Snackbar;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public class CrashReportActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_crash_report);
+ findViewById(R.id.copyLogs).setOnClickListener(v -> {
+ ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ //Are there any devices without clipboard...?
+ if (clipboard != null) {
+ ClipData clip = ClipData.newPlainText("edcrash", getAllErrorDetailsFromIntent(getIntent()));
+ clipboard.setPrimaryClip(clip);
+ Snackbar.make(findViewById(R.id.snackbar), R.string.copy_toast_msg, Snackbar.LENGTH_SHORT).show();
+ }
+ });
+
+ }
+
+ public String getAllErrorDetailsFromIntent(@NonNull Intent intent) {
+ Date currentDate = new Date();
+ DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
+
+ String buildDateAsString = getBuildDateAsString(dateFormat);
+
+ String versionName = getVersionName();
+
+ String errorDetails = "";
+
+ errorDetails += "Build version: " + versionName + " \n";
+ if (buildDateAsString != null) {
+ errorDetails += "Build date: " + buildDateAsString + " \n";
+ }
+ errorDetails += "Current date: " + dateFormat.format(currentDate) + " \n";
+ errorDetails += "Device: " + getDeviceModelName() + " \n \n";
+ errorDetails += "Stack trace: \n";
+ errorDetails += getStackTraceFromIntent(intent);
+ return errorDetails;
+ }
+
+ private String getBuildDateAsString(@NonNull DateFormat dateFormat) {
+ long buildDate;
+ try {
+ ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), 0);
+ ZipFile zf = new ZipFile(ai.sourceDir);
+
+ ZipEntry ze = zf.getEntry("classes.dex");
+ buildDate = ze.getTime();
+
+
+ zf.close();
+ } catch (Exception e) {
+ buildDate = 0;
+ }
+
+ if (buildDate > 312764400000L) {
+ return dateFormat.format(new Date(buildDate));
+ } else {
+ return null;
+ }
+ }
+
+ private String getVersionName() {
+ try {
+ PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
+ return packageInfo.versionName;
+ } catch (Exception e) {
+ return "Unknown";
+ }
+ }
+
+ private String getDeviceModelName() {
+ String manufacturer = Build.MANUFACTURER;
+ String model = Build.MODEL;
+ if (model.startsWith(manufacturer)) {
+ return capitalize(model);
+ } else {
+ return capitalize(manufacturer) + " " + model;
+ }
+ }
+
+ private String capitalize(@Nullable String s) {
+ if (s == null || s.length() == 0) {
+ return "";
+ }
+ char first = s.charAt(0);
+ if (Character.isUpperCase(first)) {
+ return s;
+ } else {
+ return Character.toUpperCase(first) + s.substring(1);
+ }
+ }
+
+ public String getStackTraceFromIntent(@NonNull Intent intent) {
+ return intent.getStringExtra(BuildConfig.APPLICATION_ID + ".EXTRA_STACK_TRACE");
+ }
+
+}
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/DownloadActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/DownloadActivity.java
index df1ce507..26efef52 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/DownloadActivity.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/DownloadActivity.java
@@ -102,7 +102,15 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
mListView.setAdapter(mAdapter);
mListView.setLayoutManager(new LinearLayoutManager(this));
- mListView.addItemDecoration(new StickyRecyclerHeadersDecoration(mAdapter));
+ StickyRecyclerHeadersDecoration headersDecor = new StickyRecyclerHeadersDecoration(mAdapter);
+ mListView.addItemDecoration(headersDecor);
+ mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
+ @Override
+ public void onChanged() {
+ headersDecor.invalidateHeaders();
+ }
+ });
+
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mListView.getContext(),
DividerItemDecoration.VERTICAL);
mListView.addItemDecoration(dividerItemDecoration);
@@ -171,7 +179,6 @@ public class DownloadActivity extends BaseActivity implements RepoLoader.RepoLis
private void reloadItems() {
mAdapter.swapCursor(RepoDb.queryModuleOverview(mSortingOrder, mFilterText));
mAdapter.notifyDataSetChanged();
- //mAdapter.getFilter().filter(mFilterText);
}
@Override
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/DownloadDetailsVersionsFragment.java b/app/src/main/java/org/meowcat/edxposed/manager/DownloadDetailsVersionsFragment.java
index debab8a7..2cee8761 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/DownloadDetailsVersionsFragment.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/DownloadDetailsVersionsFragment.java
@@ -1,7 +1,6 @@
package org.meowcat.edxposed.manager;
import android.annotation.SuppressLint;
-import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -41,8 +40,8 @@ import java.util.Date;
import static org.meowcat.edxposed.manager.XposedApp.WRITE_EXTERNAL_PERMISSION;
public class DownloadDetailsVersionsFragment extends ListFragment {
- private DownloadDetailsActivity mActivity;
private static View rootView;
+ private DownloadDetailsActivity mActivity;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java b/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java
index 76032fce..dcd172a5 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/ModulesActivity.java
@@ -1,15 +1,11 @@
package org.meowcat.edxposed.manager;
-import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
-import android.content.Context;
import android.content.Intent;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -27,9 +23,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.view.menu.MenuBuilder;
-import androidx.appcompat.view.menu.MenuPopupHelper;
-import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.DividerItemDecoration;
@@ -108,6 +101,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
mSwipeRefreshLayout.setRefreshing(false);
}
};
+ private String selectedPackageName;
private void filter(String constraint) {
filter.filter(constraint);
@@ -129,15 +123,12 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
mModuleUtil = ModuleUtil.getInstance();
mPm = getPackageManager();
installedXposedVersion = XposedApp.getXposedVersion();
- if (Build.VERSION.SDK_INT >= 21) {
- if (installedXposedVersion <= 0) {
- addHeader();
- }
- } else {
- //if (StatusInstallerFragment.DISABLE_FILE.exists()) installedXposedVersion = -1;
- if (installedXposedVersion <= 0) {
- addHeader();
- }
+ if (installedXposedVersion <= 0) {
+ Snackbar.make(findViewById(R.id.snackbar), R.string.xposed_not_active, Snackbar.LENGTH_LONG).setAction(R.string.Settings, v -> {
+ Intent intent = new Intent();
+ intent.setClass(ModulesActivity.this, SettingsActivity.class);
+ startActivity(intent);
+ }).show();
}
mAdapter = new ModuleAdapter();
mModuleUtil.addListener(this);
@@ -166,12 +157,6 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
}
- private void addHeader() {
- //View notActiveNote = getLayoutInflater().inflate(R.layout.xposed_not_active_note, mListView, false);
- //notActiveNote.setTag(NOT_ACTIVE_NOTE_TAG);
- //mListView.addHeaderView(notActiveNote);
- }
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_modules, menu);
@@ -277,7 +262,6 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
return super.onOptionsItemSelected(item);
}
-
private boolean importModules(File path) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Snackbar.make(findViewById(R.id.snackbar), R.string.sdcard_not_writable, Snackbar.LENGTH_LONG).show();
@@ -362,78 +346,56 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
runOnUiThread(reloadModules);
}
- @SuppressLint("RestrictedApi")
- private void showMenu(@NonNull Context context,
- @NonNull View anchor,
- @NonNull ApplicationInfo info) {
- PopupMenu appMenu = new PopupMenu(context, anchor);
- appMenu.inflate(R.menu.context_menu_modules);
- ModuleUtil.InstalledModule installedModule = ModuleUtil.getInstance().getModule(info.packageName);
- if (installedModule == null) {
- return;
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ ModuleUtil.InstalledModule module = ModuleUtil.getInstance().getModule(selectedPackageName);
+ if (module == null) {
+ return false;
}
- try {
- String support = RepoDb
- .getModuleSupport(installedModule.packageName);
- if (NavUtil.parseURL(support) == null)
- appMenu.getMenu().removeItem(R.id.menu_support);
- } catch (RepoDb.RowNotFoundException e) {
- appMenu.getMenu().removeItem(R.id.menu_download_updates);
- appMenu.getMenu().removeItem(R.id.menu_support);
+ switch (item.getItemId()) {
+ case R.id.menu_launch:
+ String packageName = module.packageName;
+ if (packageName == null) {
+ return false;
+ }
+ Intent launchIntent = getSettingsIntent(packageName);
+ if (launchIntent != null) {
+ startActivity(launchIntent);
+ } else {
+ Snackbar.make(findViewById(R.id.snackbar), R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
+ }
+ return true;
+
+ case R.id.menu_download_updates:
+ Intent detailsIntent = new Intent(this, DownloadDetailsActivity.class);
+ detailsIntent.setData(Uri.fromParts("package", module.packageName, null));
+ startActivity(detailsIntent);
+ return true;
+
+ case R.id.menu_support:
+ NavUtil.startURL(this, Uri.parse(RepoDb.getModuleSupport(module.packageName)));
+ return true;
+
+ case R.id.menu_app_store:
+ Uri uri = Uri.parse("market://details?id=" + module.packageName);
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ startActivity(intent);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return true;
+
+ case R.id.menu_app_info:
+ startActivity(new Intent(ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", module.packageName, null)));
+ return true;
+
+ case R.id.menu_uninstall:
+ startActivity(new Intent(Intent.ACTION_UNINSTALL_PACKAGE, Uri.fromParts("package", module.packageName, null)));
+ return true;
}
- appMenu.setOnMenuItemClickListener(menuItem -> {
- ModuleUtil.InstalledModule module = ModuleUtil.getInstance().getModule(info.packageName);
- if (module == null) {
- return false;
- }
- switch (menuItem.getItemId()) {
- case R.id.menu_launch:
- String packageName = module.packageName;
- if (packageName == null) {
- return false;
- }
- Intent launchIntent = getSettingsIntent(packageName);
- if (launchIntent != null) {
- startActivity(launchIntent);
- } else {
- Snackbar.make(findViewById(R.id.snackbar), R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
- }
- return true;
-
- case R.id.menu_download_updates:
- Intent detailsIntent = new Intent(this, DownloadDetailsActivity.class);
- detailsIntent.setData(Uri.fromParts("package", module.packageName, null));
- startActivity(detailsIntent);
- return true;
-
- case R.id.menu_support:
- NavUtil.startURL(this, Uri.parse(RepoDb.getModuleSupport(module.packageName)));
- return true;
-
- case R.id.menu_app_store:
- Uri uri = Uri.parse("market://details?id=" + module.packageName);
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- startActivity(intent);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- return true;
-
- case R.id.menu_app_info:
- startActivity(new Intent(ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", module.packageName, null)));
- return true;
-
- case R.id.menu_uninstall:
- startActivity(new Intent(Intent.ACTION_UNINSTALL_PACKAGE, Uri.fromParts("package", module.packageName, null)));
- return true;
- }
- return true;
- });
- MenuPopupHelper menuHelper = new MenuPopupHelper(context, (MenuBuilder) appMenu.getMenu(), anchor);
- menuHelper.setForceShowIcon(true);
- menuHelper.show();
+ return super.onContextItemSelected(item);
}
private Intent getSettingsIntent(String packageName) {
@@ -458,37 +420,6 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
return intent;
}
- public void onItemClick(View view) {
- if (getFragmentManager() != null) {
- try {
- showMenu(this, view, Objects.requireNonNull(this).getPackageManager().getApplicationInfo((String) view.getTag(), 0));
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- String packageName = (String) view.getTag();
- if (packageName == null)
- return;
-
- Intent launchIntent = getSettingsIntent(packageName);
- if (launchIntent != null) {
- startActivity(launchIntent);
- } else {
- Snackbar.make(findViewById(R.id.snackbar), R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
- }
- }
- } else {
- String packageName = (String) view.getTag();
- if (packageName == null) {
- return;
- }
- Intent launchIntent = getSettingsIntent(packageName);
- if (launchIntent != null) {
- startActivity(launchIntent);
- } else {
- Snackbar.make(findViewById(R.id.snackbar), R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
- }
- }
- }
-
private boolean lowercaseContains(String s, CharSequence filter) {
return !TextUtils.isEmpty(s) && s.toLowerCase().contains(filter);
}
@@ -514,11 +445,41 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
- //View view = holder.itemView;
ModuleUtil.InstalledModule item = (ModuleUtil.InstalledModule) items.toArray()[position];
- holder.itemView.setOnClickListener(v -> ModulesActivity.this.onItemClick(holder.itemView));
- holder.itemView.setTag(item.packageName);
+ holder.itemView.setOnClickListener(v -> {
+ String packageName = item.packageName;
+ if (packageName == null) {
+ return;
+ }
+ Intent launchIntent = getSettingsIntent(packageName);
+ if (launchIntent != null) {
+ startActivity(launchIntent);
+ } else {
+ Snackbar.make(findViewById(R.id.snackbar), R.string.module_no_ui, Snackbar.LENGTH_LONG).show();
+ }
+ });
+ holder.itemView.setOnLongClickListener(v -> {
+ selectedPackageName = item.packageName;
+ return false;
+ });
+
+ holder.itemView.setOnCreateContextMenuListener((menu, v, menuInfo) -> {
+ getMenuInflater().inflate(R.menu.context_menu_modules, menu);
+ ModuleUtil.InstalledModule installedModule = ModuleUtil.getInstance().getModule(item.packageName);
+ if (installedModule == null) {
+ return;
+ }
+ try {
+ String support = RepoDb.getModuleSupport(installedModule.packageName);
+ if (NavUtil.parseURL(support) == null) {
+ menu.removeItem(R.id.menu_support);
+ }
+ } catch (RepoDb.RowNotFoundException e) {
+ menu.removeItem(R.id.menu_download_updates);
+ menu.removeItem(R.id.menu_support);
+ }
+ });
holder.appName.setText(item.getAppName());
TextView version = holder.appVersion;
diff --git a/app/src/main/java/org/meowcat/edxposed/manager/XposedApp.java b/app/src/main/java/org/meowcat/edxposed/manager/XposedApp.java
index 20cd66ad..9ec10f5c 100644
--- a/app/src/main/java/org/meowcat/edxposed/manager/XposedApp.java
+++ b/app/src/main/java/org/meowcat/edxposed/manager/XposedApp.java
@@ -27,6 +27,8 @@ import org.meowcat.edxposed.manager.util.NotificationUtil;
import org.meowcat.edxposed.manager.util.RepoLoader;
import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@@ -102,6 +104,31 @@ public class XposedApp extends de.robv.android.xposed.installer.XposedApp implem
public void onCreate() {
super.onCreate();
+ try {
+ Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ throwable.printStackTrace(pw);
+ String stackTraceString = sw.toString();
+
+ //Reduce data to 128KB so we don't get a TransactionTooLargeException when sending the intent.
+ //The limit is 1MB on Android but some devices seem to have it lower.
+ //See: http://developer.android.com/reference/android/os/TransactionTooLargeException.html
+ //And: http://stackoverflow.com/questions/11451393/what-to-do-on-transactiontoolargeexception#comment46697371_12809171
+ if (stackTraceString.length() > 131071) {
+ String disclaimer = " [stack trace too large]";
+ stackTraceString = stackTraceString.substring(0, 131071 - disclaimer.length()) + disclaimer;
+ }
+ Intent intent = new Intent(XposedApp.this, CrashReportActivity.class);
+ intent.putExtra(BuildConfig.APPLICATION_ID + ".EXTRA_STACK_TRACE", stackTraceString);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ XposedApp.this.startActivity(intent);
+ android.os.Process.killProcess(android.os.Process.myPid());
+ System.exit(10);
+ });
+ } catch (Throwable t) {
+ }
mInstance = this;
mUiThread = Thread.currentThread();
mMainHandler = new Handler();
diff --git a/app/src/main/res/layout/activity_crash_report.xml b/app/src/main/res/layout/activity_crash_report.xml
new file mode 100644
index 00000000..f51a21e4
--- /dev/null
+++ b/app/src/main/res/layout/activity_crash_report.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_download.xml b/app/src/main/res/layout/activity_download.xml
index 5a7a47cf..3e124ffd 100644
--- a/app/src/main/res/layout/activity_download.xml
+++ b/app/src/main/res/layout/activity_download.xml
@@ -1,5 +1,6 @@
+ android:orientation="vertical"
+ app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
+
+
+
+ -
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_installer.xml b/app/src/main/res/menu/menu_installer.xml
index 322fa8c6..0c6197f4 100644
--- a/app/src/main/res/menu/menu_installer.xml
+++ b/app/src/main/res/menu/menu_installer.xml
@@ -2,48 +2,51 @@
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index b3a30173..fdee50f0 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -296,4 +296,5 @@
安装于 %1$s \u00b7 更新于 %2$s
兼容模式应用列表
兼容模式
+ EdXposed 框架未安装或未激活, 您可在设置中关闭状态检查
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 47dedd22..f8f879ab 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -296,4 +296,5 @@
安裝於 %1$s \u00b7 更新於 %2$s
兼容模式應用列表
兼容模式
+ EdXposed 框架未安裝或未啟用, 您可在設定中關閉狀態檢查
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 8b2ec986..94646a1b 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -296,4 +296,5 @@
安裝於 %1$s \u00b7 更新於 %2$s
相容模式應用列表
相容模式
+ EdXposed 框架未安裝或未啟用, 您可在設定中關閉狀態檢查
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6dbeefaa..90ab83cb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -330,4 +330,5 @@
Follow system
Compat List
Compat mode app list
+ EdXposed Framework is not currently installed or active\nYou can close status check in settings