From 5dd98d480b8cb17310057062f688a77d73314baa Mon Sep 17 00:00:00 2001 From: androidacy-user Date: Mon, 22 May 2023 16:30:07 -0400 Subject: [PATCH] optimizations Signed-off-by: androidacy-user --- app/build.gradle.kts | 4 +- app/src/main/AndroidManifest.xml | 8 +- .../java/com/fox2code/mmm/CrashHandler.kt | 257 ++++++++++-------- .../res/layout/activity_crash_handler.xml | 10 +- app/src/main/res/values/strings.xml | 1 + 5 files changed, 155 insertions(+), 125 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 53f56be..ef15aa4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -38,8 +38,8 @@ android { applicationId = "com.fox2code.mmm" minSdk = 24 targetSdk = 33 - versionCode = 74 - versionName = "2.1.1" + versionCode = 75 + versionName = "2.1.2" vectorDrawables { useSupportLibrary = true } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 95a54bf..e932676 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -195,11 +195,13 @@ android:value="false" /> + android:value="https://e199c2a54a1f49b1b5beb3244f2c2358@sentry.androidacy.com/77" /> + + + android:value="0.2" /> + android:value="0.2" /> diff --git a/app/src/main/java/com/fox2code/mmm/CrashHandler.kt b/app/src/main/java/com/fox2code/mmm/CrashHandler.kt index 649829c..1677ac2 100644 --- a/app/src/main/java/com/fox2code/mmm/CrashHandler.kt +++ b/app/src/main/java/com/fox2code/mmm/CrashHandler.kt @@ -1,174 +1,199 @@ -package com.fox2code.mmm; +package com.fox2code.mmm -import android.annotation.SuppressLint; -import android.content.ClipboardManager; -import android.os.Bundle; -import android.view.View; -import android.widget.EditText; -import android.widget.Toast; - -import com.fox2code.foxcompat.app.FoxActivity; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.textview.MaterialTextView; - -import java.io.PrintWriter; -import java.io.StringWriter; - -import io.sentry.Sentry; -import io.sentry.UserFeedback; -import timber.log.Timber; - -public class CrashHandler extends FoxActivity { +import android.annotation.SuppressLint +import android.content.ClipData +import android.content.ClipboardManager +import android.content.DialogInterface +import android.os.Bundle +import android.view.View +import android.widget.EditText +import android.widget.Toast +import com.fox2code.foxcompat.app.FoxActivity +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.textview.MaterialTextView +import io.sentry.Sentry +import io.sentry.UserFeedback +import timber.log.Timber +import java.io.PrintWriter +import java.io.StringWriter +class CrashHandler : FoxActivity() { + @Suppress("DEPRECATION", "KotlinConstantConditions") @SuppressLint("RestrictedApi") - @Override - protected void onCreate(Bundle savedInstanceState) { - Timber.i("CrashHandler.onCreate(%s)", savedInstanceState); + override fun onCreate(savedInstanceState: Bundle?) { + Timber.i("CrashHandler.onCreate(%s)", savedInstanceState) // log intent with extras - Timber.d("CrashHandler.onCreate: intent=%s", getIntent()); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_crash_handler); - // unlock webview + Timber.d("CrashHandler.onCreate: intent=%s", intent) + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_crash_handler) // set crash_details MaterialTextView to the exception passed in the intent or unknown if null // convert stacktrace from array to string, and pretty print it (first line is the exception, the rest is the stacktrace, with each line indented by 4 spaces) - MaterialTextView crashDetails = findViewById(R.id.crash_details); - crashDetails.setText(""); + val crashDetails = findViewById(R.id.crash_details) + crashDetails.text = "" // get the exception from the intent - Throwable exception = (Throwable) getIntent().getSerializableExtra("exception"); + val exception = intent.getSerializableExtra("exception") as Throwable? // get the crashReportingEnabled from the intent - boolean crashReportingEnabled = getIntent().getBooleanExtra("crashReportingEnabled", false); + val crashReportingEnabled = intent.getBooleanExtra("crashReportingEnabled", false) // if the exception is null, set the crash details to "Unknown" if (exception == null) { - crashDetails.setText(R.string.crash_details); + crashDetails.setText(R.string.crash_details) } else { // if the exception is not null, set the crash details to the exception and stacktrace // stacktrace is an StacktraceElement, so convert it to a string and replace the commas with newlines - StringWriter stringWriter = new StringWriter(); - exception.printStackTrace(new PrintWriter(stringWriter)); - String stacktrace = stringWriter.toString(); - stacktrace = stacktrace.replace(",", "\n "); - crashDetails.setText(getString(R.string.crash_full_stacktrace, stacktrace)); + val stringWriter = StringWriter() + exception.printStackTrace(PrintWriter(stringWriter)) + var stacktrace = stringWriter.toString() + stacktrace = stacktrace.replace(",", "\n ") + crashDetails.text = getString(R.string.crash_full_stacktrace, stacktrace) } - String lastEventId = getIntent().getStringExtra("lastEventId"); - Timber.d("CrashHandler.onCreate: lastEventId=%s, crashReportingEnabled=%s", lastEventId, crashReportingEnabled); + val lastEventId = intent.getStringExtra("lastEventId") + Timber.d( + "CrashHandler.onCreate: lastEventId=%s, crashReportingEnabled=%s", + lastEventId, + crashReportingEnabled + ) if (lastEventId == null && crashReportingEnabled) { // if lastEventId is null, hide the feedback button - findViewById(R.id.feedback).setVisibility(View.GONE); - Timber.d("CrashHandler.onCreate: lastEventId is null but crash reporting is enabled. This may indicate a bug in the crash reporting system."); + findViewById(R.id.feedback).visibility = View.GONE + Timber.d("CrashHandler.onCreate: lastEventId is null but crash reporting is enabled. This may indicate a bug in the crash reporting system.") } else { // if lastEventId is not null, show the feedback button - findViewById(R.id.feedback).setVisibility(View.VISIBLE); + findViewById(R.id.feedback).visibility = View.VISIBLE } // disable feedback if sentry is disabled - //noinspection ConstantConditions if (crashReportingEnabled && lastEventId != null) { // get name, email, and message fields - EditText name = findViewById(R.id.feedback_name); - EditText email = findViewById(R.id.feedback_email); - EditText description = findViewById(R.id.feedback_message); + val name = findViewById(R.id.feedback_name) + val email = findViewById(R.id.feedback_email) + val description = findViewById(R.id.feedback_message) // get submit button - findViewById(R.id.feedback_submit).setOnClickListener(v -> { + findViewById(R.id.feedback_submit).setOnClickListener { _: View? -> // require the feedback_message, rest is optional - if (description.getText().toString().equals("")) { - Toast.makeText(this, R.string.sentry_dialogue_empty_message, Toast.LENGTH_LONG).show(); - return; + if (description.text.toString() == "") { + Toast.makeText(this, R.string.sentry_dialogue_empty_message, Toast.LENGTH_LONG) + .show() + return@setOnClickListener } // if email or name is empty, use "Anonymous" - final String[] nameString = {name.getText().toString().equals("") ? "Anonymous" : name.getText().toString()}; - final String[] emailString = {email.getText().toString().equals("") ? "Anonymous" : email.getText().toString()}; + val nameString = + arrayOf(if (name.text.toString() == "") "Anonymous" else name.text.toString()) + val emailString = + arrayOf(if (email.text.toString() == "") "Anonymous" else email.text.toString()) // get sentryException passed in intent - Throwable sentryException = (Throwable) getIntent().getSerializableExtra("sentryException"); - new Thread(() -> { + val sentryException = intent.getSerializableExtra("sentryException") as Throwable? + Thread { try { - UserFeedback userFeedback; + val userFeedback: UserFeedback if (sentryException != null) { - userFeedback = new UserFeedback(Sentry.captureException(sentryException)); + userFeedback = UserFeedback(Sentry.captureException(sentryException)) // Setups the JSON body - if (nameString[0].equals("")) nameString[0] = "Anonymous"; - if (emailString[0].equals("")) emailString[0] = "Anonymous"; - userFeedback.setName(nameString[0]); - userFeedback.setEmail(emailString[0]); - userFeedback.setComments(description.getText().toString()); - Sentry.captureUserFeedback(userFeedback); + if (nameString[0] == "") nameString[0] = "Anonymous" + if (emailString[0] == "") emailString[0] = "Anonymous" + userFeedback.name = nameString[0] + userFeedback.email = emailString[0] + userFeedback.comments = description.text.toString() + Sentry.captureUserFeedback(userFeedback) + } + Timber.i( + "Submitted user feedback: name %s email %s comment %s", + nameString[0], + emailString[0], + description.text.toString() + ) + runOnUiThread { + Toast.makeText( + this, + R.string.sentry_dialogue_success, + Toast.LENGTH_LONG + ).show() } - Timber.i("Submitted user feedback: name %s email %s comment %s", nameString[0], emailString[0], description.getText().toString()); - runOnUiThread(() -> Toast.makeText(this, R.string.sentry_dialogue_success, Toast.LENGTH_LONG).show()); // Close the activity - finish(); + finish() // start the main activity - startActivity(getPackageManager().getLaunchIntentForPackage(getPackageName())); - } catch (Exception e) { - Timber.e(e, "Failed to submit user feedback"); + startActivity(packageManager.getLaunchIntentForPackage(packageName)) + } catch (e: Exception) { + Timber.e(e, "Failed to submit user feedback") // Show a toast if the user feedback could not be submitted - runOnUiThread(() -> Toast.makeText(this, R.string.sentry_dialogue_failed_toast, Toast.LENGTH_LONG).show()); + runOnUiThread { + Toast.makeText( + this, + R.string.sentry_dialogue_failed_toast, + Toast.LENGTH_LONG + ).show() + } } - }).start(); - }); + }.start() + } // get restart button - findViewById(R.id.restart).setOnClickListener(v -> { + findViewById(R.id.restart).setOnClickListener { _: View? -> // Restart the app and submit sans feedback - Throwable sentryException = (Throwable) getIntent().getSerializableExtra("sentryException"); - if (crashReportingEnabled) Sentry.captureException(sentryException); - finish(); - startActivity(getPackageManager().getLaunchIntentForPackage(getPackageName())); - }); + val sentryException = intent.getSerializableExtra("sentryException") as Throwable? + if (crashReportingEnabled) Sentry.captureException(sentryException!!) + finish() + startActivity(packageManager.getLaunchIntentForPackage(packageName)) + } } else { // disable feedback if sentry is disabled - findViewById(R.id.feedback_name).setEnabled(false); - findViewById(R.id.feedback_email).setEnabled(false); - findViewById(R.id.feedback_message).setEnabled(false); + findViewById(R.id.feedback_name).isEnabled = false + findViewById(R.id.feedback_email).isEnabled = false + findViewById(R.id.feedback_message).isEnabled = false // fade out all the fields - findViewById(R.id.feedback_name).setAlpha(0.5f); - findViewById(R.id.feedback_email).setAlpha(0.5f); - findViewById(R.id.feedback_message).setAlpha(0.5f); + findViewById(R.id.feedback_name).alpha = 0.5f + findViewById(R.id.feedback_email).alpha = 0.5f + findViewById(R.id.feedback_message).alpha = 0.5f // fade out the submit button - findViewById(R.id.feedback_submit).setAlpha(0.5f); + findViewById(R.id.feedback_submit).alpha = 0.5f // set feedback_text to "Crash reporting is disabled" - ((MaterialTextView) findViewById(R.id.feedback_text)).setText(R.string.sentry_enable_nag); - findViewById(R.id.feedback_submit).setOnClickListener(v -> Toast.makeText(this, R.string.sentry_dialogue_disabled, Toast.LENGTH_LONG).show()); + (findViewById(R.id.feedback_text) as MaterialTextView).setText(R.string.sentry_enable_nag) + findViewById(R.id.feedback_submit).setOnClickListener { _: View? -> + Toast.makeText( + this, + R.string.sentry_dialogue_disabled, + Toast.LENGTH_LONG + ).show() + } // handle restart button // we have to explicitly enable it because it's disabled by default - findViewById(R.id.restart).setEnabled(true); - findViewById(R.id.restart).setOnClickListener(v -> { + findViewById(R.id.restart).isEnabled = true + findViewById(R.id.restart).setOnClickListener { _: View? -> // Restart the app - finish(); - startActivity(getPackageManager().getLaunchIntentForPackage(getPackageName())); - }); + finish() + startActivity(packageManager.getLaunchIntentForPackage(packageName)) + } } // handle reset button - findViewById(R.id.reset).setOnClickListener(v -> { + findViewById(R.id.reset).setOnClickListener { _: View? -> // show a confirmation material dialog - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); - builder.setTitle(R.string.reset_app); - builder.setMessage(R.string.reset_app_confirmation); - builder.setPositiveButton(R.string.reset, (dialog, which) -> { + val builder = MaterialAlertDialogBuilder(this) + builder.setTitle(R.string.reset_app) + builder.setMessage(R.string.reset_app_confirmation) + builder.setPositiveButton(R.string.reset) { _: DialogInterface?, _: Int -> // reset the app - MainApplication.getINSTANCE().resetApp(); - }); - builder.setNegativeButton(R.string.cancel, (dialog, which) -> { - // do nothing - }); - builder.show(); - }); + MainApplication.getINSTANCE().resetApp() + } + builder.setNegativeButton(R.string.cancel) { _: DialogInterface?, _: Int -> } + builder.show() + } } - public void copyCrashDetails(View view) { + fun copyCrashDetails(view: View) { // change view to a checkmark - view.setBackgroundResource(R.drawable.baseline_check_24); + view.setBackgroundResource(R.drawable.baseline_check_24) // copy crash_details to clipboard - ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); - String crashDetails = ((MaterialTextView) findViewById(R.id.crash_details)).getText().toString(); - clipboard.setPrimaryClip(android.content.ClipData.newPlainText("crash_details", crashDetails)); + val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager + val crashDetails = + (findViewById(R.id.crash_details) as MaterialTextView).text.toString() + clipboard.setPrimaryClip(ClipData.newPlainText("crash_details", crashDetails)) // show a toast - Toast.makeText(this, R.string.crash_details_copied, Toast.LENGTH_LONG).show(); + Toast.makeText(this, R.string.crash_details_copied, Toast.LENGTH_LONG).show() // after 1 second, change the view back to a copy button - new Thread(() -> { + Thread { try { - Thread.sleep(1000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + Thread.sleep(1000) + } catch (e: InterruptedException) { + Thread.currentThread().interrupt() } - runOnUiThread(() -> view.setBackgroundResource(R.drawable.baseline_copy_all_24)); - }).start(); + runOnUiThread { view.setBackgroundResource(R.drawable.baseline_copy_all_24) } + }.start() } -} +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_crash_handler.xml b/app/src/main/res/layout/activity_crash_handler.xml index cfb764e..5537e84 100644 --- a/app/src/main/res/layout/activity_crash_handler.xml +++ b/app/src/main/res/layout/activity_crash_handler.xml @@ -31,14 +31,16 @@ android:text="@string/crash_text" android:textSize="20sp" android:textStyle="bold" /> - + + + android:gravity="fill" + android:text="@string/crash_details_suggestion" + android:textSize="14sp" /> You\'ve already upgraded! Androidacy Premium offers faster downloads, an ad-free experience, and more! Upgrade + The stacktrace may be found below. However, we strongly recommend you to use the feedback form below to submit feedback instead. This way, instead of manually copying the stacktrace, it will send it to us automatically. It also is deobfuscated that way and additional details are reported automatically.