Create ErrorUtil class with three ways to report errors

Activity, snackbar and notification
This commit is contained in:
Stypox 2021-12-01 09:10:59 +01:00
parent 7dc85af5fb
commit 1d2642f1e3
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
4 changed files with 119 additions and 78 deletions

View File

@ -227,28 +227,35 @@ public class App extends MultiDexApplication {
// the main and update channels
final NotificationChannelCompat mainChannel = new NotificationChannelCompat
.Builder(getString(R.string.notification_channel_id),
NotificationManagerCompat.IMPORTANCE_LOW)
NotificationManagerCompat.IMPORTANCE_LOW)
.setName(getString(R.string.notification_channel_name))
.setDescription(getString(R.string.notification_channel_description))
.build();
final NotificationChannelCompat appUpdateChannel = new NotificationChannelCompat
.Builder(getString(R.string.app_update_notification_channel_id),
NotificationManagerCompat.IMPORTANCE_LOW)
NotificationManagerCompat.IMPORTANCE_LOW)
.setName(getString(R.string.app_update_notification_channel_name))
.setDescription(getString(R.string.app_update_notification_channel_description))
.build();
final NotificationChannelCompat hashChannel = new NotificationChannelCompat
.Builder(getString(R.string.hash_channel_id),
NotificationManagerCompat.IMPORTANCE_HIGH)
NotificationManagerCompat.IMPORTANCE_HIGH)
.setName(getString(R.string.hash_channel_name))
.setDescription(getString(R.string.hash_channel_description))
.build();
final NotificationChannelCompat errorReportChannel = new NotificationChannelCompat
.Builder(getString(R.string.error_report_channel_id),
NotificationManagerCompat.IMPORTANCE_LOW)
.setName(getString(R.string.error_report_channel_name))
.setDescription(getString(R.string.error_report_channel_description))
.build();
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.createNotificationChannelsCompat(Arrays.asList(mainChannel,
appUpdateChannel, hashChannel));
appUpdateChannel, hashChannel, errorReportChannel));
}
protected boolean isDisposedRxExceptionsReported() {

View File

@ -1,9 +1,10 @@
package org.schabi.newpipe.error;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -11,15 +12,12 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import com.google.android.material.snackbar.Snackbar;
import com.grack.nanojson.JsonWriter;
import org.schabi.newpipe.BuildConfig;
@ -27,15 +25,13 @@ import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.databinding.ActivityErrorBinding;
import org.schabi.newpipe.util.Localization;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.util.ThemeHelper;
import org.schabi.newpipe.util.external_communication.ShareUtils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
/*
* Created by Christian Schabesberger on 24.10.15.
*
@ -56,7 +52,7 @@ import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
public class ErrorActivity extends AppCompatActivity {
class ErrorActivity extends AppCompatActivity {
// LOG TAGS
public static final String TAG = ErrorActivity.class.toString();
// BUNDLE TAGS
@ -77,67 +73,6 @@ public class ErrorActivity extends AppCompatActivity {
private ActivityErrorBinding activityErrorBinding;
/**
* Reports a new error by starting a new activity.
* <br/>
* Ensure that the data within errorInfo is serializable otherwise
* an exception will be thrown!<br/>
* {@link EnsureExceptionSerializable} might help.
*
* @param context
* @param errorInfo
*/
public static void reportError(final Context context, final ErrorInfo errorInfo) {
final Intent intent = new Intent(context, ErrorActivity.class);
intent.putExtra(ERROR_INFO, errorInfo);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
public static void reportErrorInSnackbar(final Context context, final ErrorInfo errorInfo) {
final View rootView = context instanceof Activity
? ((Activity) context).findViewById(android.R.id.content) : null;
reportErrorInSnackbar(context, rootView, errorInfo);
}
public static void reportErrorInSnackbar(final Fragment fragment, final ErrorInfo errorInfo) {
View rootView = fragment.getView();
if (rootView == null && fragment.getActivity() != null) {
rootView = fragment.getActivity().findViewById(android.R.id.content);
}
reportErrorInSnackbar(fragment.requireContext(), rootView, errorInfo);
}
public static void reportUiErrorInSnackbar(final Context context,
final String request,
final Throwable throwable) {
reportErrorInSnackbar(context, new ErrorInfo(throwable, UserAction.UI_ERROR, request));
}
public static void reportUiErrorInSnackbar(final Fragment fragment,
final String request,
final Throwable throwable) {
reportErrorInSnackbar(fragment, new ErrorInfo(throwable, UserAction.UI_ERROR, request));
}
////////////////////////////////////////////////////////////////////////
// Utils
////////////////////////////////////////////////////////////////////////
private static void reportErrorInSnackbar(final Context context,
@Nullable final View rootView,
final ErrorInfo errorInfo) {
if (rootView != null) {
Snackbar.make(rootView, R.string.error_snackbar_message, Snackbar.LENGTH_LONG)
.setActionTextColor(Color.YELLOW)
.setAction(context.getString(R.string.error_snackbar_action).toUpperCase(), v ->
reportError(context, errorInfo)).show();
} else {
reportError(context, errorInfo);
}
}
////////////////////////////////////////////////////////////////////////
// Activity lifecycle

View File

@ -0,0 +1,96 @@
package org.schabi.newpipe.error
import android.app.Activity
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.view.View
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.google.android.material.snackbar.Snackbar
import org.schabi.newpipe.R
class ErrorUtil {
companion object {
private const val ERROR_REPORT_NOTIFICATION_ID = 5340681;
/**
* Reports a new error by starting a new activity.
* <br></br>
* Ensure that the data within errorInfo is serializable otherwise
* an exception will be thrown!<br></br>
* [EnsureExceptionSerializable] might help.
*
* @param context
* @param errorInfo
*/
@JvmStatic
fun openActivity(context: Context, errorInfo: ErrorInfo) {
val intent = Intent(context, ErrorActivity::class.java)
intent.putExtra(ErrorActivity.ERROR_INFO, errorInfo)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
@JvmStatic
fun showSnackbar(context: Context, errorInfo: ErrorInfo) {
val rootView = if (context is Activity) context.findViewById<View>(R.id.content) else null
showSnackbar(context, rootView, errorInfo)
}
@JvmStatic
fun showSnackbar(fragment: Fragment, errorInfo: ErrorInfo) {
var rootView = fragment.view
if (rootView == null && fragment.activity != null) {
rootView = fragment.requireActivity().findViewById(R.id.content)
}
showSnackbar(fragment.requireContext(), rootView, errorInfo)
}
@JvmStatic
fun showUiErrorSnackbar(context: Context, request: String, throwable: Throwable) {
showSnackbar(context, ErrorInfo(throwable, UserAction.UI_ERROR, request))
}
@JvmStatic
fun showUiErrorSnackbar(fragment: Fragment, request: String, throwable: Throwable) {
showSnackbar(fragment, ErrorInfo(throwable, UserAction.UI_ERROR, request))
}
@JvmStatic
fun createNotification(context: Context, errorInfo: ErrorInfo) {
val notificationManager =
ContextCompat.getSystemService(context, NotificationManager::class.java)
if (notificationManager == null) {
// this should never happen, but just in case open error activity
openActivity(context, errorInfo)
}
val notificationBuilder: NotificationCompat.Builder =
NotificationCompat.Builder(context,
context.getString(R.string.error_report_channel_id))
.setSmallIcon(R.drawable.ic_bug_report)
.setContentTitle(context.getString(R.string.error_report_title))
.setContentText(context.getString(errorInfo.messageStringId))
notificationManager!!.notify(ERROR_REPORT_NOTIFICATION_ID, notificationBuilder.build())
}
private fun showSnackbar(context: Context, rootView: View?, errorInfo: ErrorInfo) {
if (rootView == null) {
// fallback to showing a notification if no root view is available
createNotification(context, errorInfo)
} else {
Snackbar.make(rootView, R.string.error_snackbar_message, Snackbar.LENGTH_LONG)
.setActionTextColor(Color.YELLOW)
.setAction(context.getString(R.string.error_snackbar_action).uppercase()) {
openActivity(context, errorInfo)
}.show()
}
}
}
}

View File

@ -182,14 +182,17 @@
<string name="just_once">Just Once</string>
<string name="file">File</string>
<string name="notification_channel_id" translatable="false">newpipe</string>
<string name="notification_channel_name">NewPipe Notification</string>
<string name="notification_channel_description">Notifications for NewPipe background and popup players</string>
<string name="notification_channel_name">NewPipe notification</string>
<string name="notification_channel_description">Notifications for NewPipe\'s player</string>
<string name="app_update_notification_channel_id" translatable="false">newpipeAppUpdate</string>
<string name="app_update_notification_channel_name">App Update Notification</string>
<string name="app_update_notification_channel_description">Notifications for new NewPipe version</string>
<string name="app_update_notification_channel_name">App update notification</string>
<string name="app_update_notification_channel_description">Notifications for new NewPipe versions</string>
<string name="hash_channel_id" translatable="false">newpipeHash</string>
<string name="hash_channel_name">Video Hash Notification</string>
<string name="hash_channel_name">Video hash notification</string>
<string name="hash_channel_description">Notifications for video hashing progress</string>
<string name="error_report_channel_id" translatable="false">newpipeErrorReport</string>
<string name="error_report_channel_name">Error report notification</string>
<string name="error_report_channel_description">Notifications to report errors</string>
<string name="unknown_content">[Unknown]</string>
<string name="switch_to_background">Switch to Background</string>
<string name="switch_to_popup">Switch to Popup</string>