Fix possible crash & add crash report activity
This commit is contained in:
parent
2e6f000cd6
commit
fac904009d
|
|
@ -21,6 +21,9 @@
|
|||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme"
|
||||
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
|
||||
<activity
|
||||
android:name=".CrashReportActivity"
|
||||
android:process=":error_activity" />
|
||||
<activity
|
||||
android:name=".CompatListActivity"
|
||||
android:label="@string/nav_title_compat_list" />
|
||||
|
|
|
|||
|
|
@ -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<String> 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<String> messages = new LinkedList<>();
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/snackbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_centerInParent="true">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/warning_crash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="horizontal"
|
||||
app:cardBackgroundColor="@color/amber_500">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/warning"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_margin="8dp"
|
||||
android:src="@drawable/ic_warning"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/warning"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="Manager crashed"
|
||||
android:textAlignment="center"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/copyLogs"
|
||||
style="@style/Widget.MaterialComponents.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="Copy logs"
|
||||
android:theme="@style/Widget.AppCompat.Button.Colored" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/snackbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
@ -12,10 +13,10 @@
|
|||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
|
|
|
|||
|
|
@ -7,5 +7,49 @@
|
|||
android:title="@string/menuSearch"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="always" />
|
||||
<item
|
||||
android:id="@+id/dexopt_all"
|
||||
android:title="@string/dexopt_now"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/speed_all"
|
||||
android:title="@string/speed_now"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:title="@string/reboot"
|
||||
app:showAsAction="never">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/soft_reboot"
|
||||
android:title="@string/soft_reboot"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot"
|
||||
android:title="@string/reboot_system"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot_recovery"
|
||||
android:title="@string/reboot_recovery"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot_bootloader"
|
||||
android:title="@string/reboot_bootloader"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot_download"
|
||||
android:title="@string/reboot_download"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot_edl"
|
||||
android:title="@string/reboot_edl"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
</item>
|
||||
</menu>
|
||||
|
|
@ -2,48 +2,51 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<group>
|
||||
<item
|
||||
android:id="@+id/dexopt_all"
|
||||
android:title="@string/dexopt_now"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/dexopt_all"
|
||||
android:title="@string/dexopt_now"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/speed_all"
|
||||
android:title="@string/speed_now"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/speed_all"
|
||||
android:title="@string/speed_now"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:title="@string/reboot"
|
||||
app:showAsAction="never">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/soft_reboot"
|
||||
android:title="@string/soft_reboot"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/soft_reboot"
|
||||
android:title="@string/soft_reboot"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/reboot"
|
||||
android:title="@string/reboot_system"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot"
|
||||
android:title="@string/reboot_system"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/reboot_recovery"
|
||||
android:title="@string/reboot_recovery"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot_recovery"
|
||||
android:title="@string/reboot_recovery"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/reboot_bootloader"
|
||||
android:title="@string/reboot_bootloader"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot_bootloader"
|
||||
android:title="@string/reboot_bootloader"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/reboot_download"
|
||||
android:title="@string/reboot_download"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot_download"
|
||||
android:title="@string/reboot_download"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/reboot_edl"
|
||||
android:title="@string/reboot_edl"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/reboot_edl"
|
||||
android:title="@string/reboot_edl"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</group>
|
||||
|
||||
</menu>
|
||||
|
|
@ -296,4 +296,5 @@
|
|||
<string name="install_timestamps">安装于 %1$s \u00b7 更新于 %2$s</string>
|
||||
<string name="pref_compat_mode_summary">兼容模式应用列表</string>
|
||||
<string name="pref_compat_mode_title">兼容模式</string>
|
||||
<string name="xposed_not_active">EdXposed 框架未安装或未激活, 您可在设置中关闭状态检查</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -296,4 +296,5 @@
|
|||
<string name="install_timestamps">安裝於 %1$s \u00b7 更新於 %2$s</string>
|
||||
<string name="pref_compat_mode_summary">兼容模式應用列表</string>
|
||||
<string name="pref_compat_mode_title">兼容模式</string>
|
||||
<string name="xposed_not_active">EdXposed 框架未安裝或未啟用, 您可在設定中關閉狀態檢查</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -296,4 +296,5 @@
|
|||
<string name="install_timestamps">安裝於 %1$s \u00b7 更新於 %2$s</string>
|
||||
<string name="pref_compat_mode_summary">相容模式應用列表</string>
|
||||
<string name="pref_compat_mode_title">相容模式</string>
|
||||
<string name="xposed_not_active">EdXposed 框架未安裝或未啟用, 您可在設定中關閉狀態檢查</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -330,4 +330,5 @@
|
|||
<string name="follow_system">Follow system</string>
|
||||
<string name="pref_compat_mode_title">Compat List</string>
|
||||
<string name="pref_compat_mode_summary">Compat mode app list</string>
|
||||
<string name="xposed_not_active">EdXposed Framework is not currently installed or active\nYou can close status check in settings</string>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Reference in New Issue