add info box

This commit is contained in:
Christian Schabesberger 2016-02-25 22:02:42 +01:00
parent 64c423902a
commit 7caf7be97e
12 changed files with 291 additions and 157 deletions

View File

@ -108,7 +108,7 @@
android:name=".ExitActivity"
android:label="@string/general_error"
android:theme="@android:style/Theme.NoDisplay" />
<activity android:name=".errorhandling.ErrorActivity"></activity>
<activity android:name=".ErrorActivity"></activity>
</application>
</manifest>

View File

@ -45,4 +45,5 @@ public class ActivityCommunicator {
// Sent from any activity to ErrorActivity.
public volatile List<Exception> errorList;
public volatile Class returnActivity;
public volatile ErrorActivity.ErrorInfo errorInfo;
}

View File

@ -0,0 +1,210 @@
package org.schabi.newpipe;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.preference.PreferenceManager;
import android.support.design.widget.Snackbar;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import org.apache.commons.lang.exception.ExceptionUtils;
import java.util.List;
import java.util.Vector;
public class ErrorActivity extends AppCompatActivity {
public static class ErrorInfo {
public int userAction;
public String request;
public String serviceName;
public int message;
public static ErrorInfo make(int userAction, String serviceName, String request, int message) {
ErrorInfo info = new ErrorInfo();
info.userAction = userAction;
info.serviceName = serviceName;
info.request = request;
info.message = message;
return info;
}
}
public static final String TAG = ErrorActivity.class.toString();
public static final int SEARCHED = 0;
public static final int REQUESTED_STREAM = 1;
public static final String SEARCHED_STRING = "Searched";
public static final String REQUESTED_STREAM_STRING = "Requested Stream";
private List<Exception> errorList;
private ErrorInfo errorInfo;
private Class returnActivity;
// views
private TextView errorView;
public static void reportError(final Context context, final List<Exception> el,
final Class returnAcitivty, View rootView, final ErrorInfo errorInfo) {
if(rootView != null) {
Snackbar.make(rootView, R.string.error_snackbar_message, Snackbar.LENGTH_LONG)
.setAction(R.string.error_snackbar_action, new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCommunicator ac = ActivityCommunicator.getCommunicator();
ac.errorList = el;
ac.returnActivity = returnAcitivty;
ac.errorInfo = errorInfo;
Intent intent = new Intent(context, ErrorActivity.class);
context.startActivity(intent);
}
}).show();
} else {
ActivityCommunicator ac = ActivityCommunicator.getCommunicator();
ac.errorList = el;
ac.returnActivity = returnAcitivty;
Intent intent = new Intent(context, ErrorActivity.class);
context.startActivity(intent);
}
}
public static void reportError(final Context context, final Exception e,
final Class returnAcitivty, View rootView, final ErrorInfo errorInfo) {
List<Exception> el = new Vector<>();
el.add(e);
reportError(context, el, returnAcitivty, rootView, errorInfo);
}
// async call
public static void reportError(Handler handler, final Context context, final Exception e,
final Class returnAcitivty, final View rootView, final ErrorInfo errorInfo) {
List<Exception> el = new Vector<>();
el.add(e);
reportError(handler, context, el, returnAcitivty, rootView, errorInfo);
}
// async call
public static void reportError(Handler handler, final Context context, final List<Exception> el,
final Class returnAcitivty, final View rootView, final ErrorInfo errorInfo) {
handler.post(new Runnable() {
@Override
public void run() {
reportError(context, el, returnAcitivty, rootView, errorInfo);
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_error);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ActivityCommunicator ac = ActivityCommunicator.getCommunicator();
errorList = ac.errorList;
returnActivity = ac.returnActivity;
errorInfo = ac.errorInfo;
errorView = (TextView) findViewById(R.id.errorView);
errorView.setText(formErrorText(errorList));
//importand add gurumeditaion
addGuruMeditaion();
buildInfo(errorInfo);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
goToReturnActivity();
return true;
}
return false;
}
private String formErrorText(List<Exception> el) {
String text = "";
for(Exception e : el) {
text += "-------------------------------------\n"
+ ExceptionUtils.getStackTrace(e);
}
text += "-------------------------------------";
return text;
}
private void goToReturnActivity() {
if(returnActivity == null) {
super.onBackPressed();
} else {
Intent intent;
if (returnActivity != null &&
returnActivity.isAssignableFrom(Activity.class)) {
intent = new Intent(this, returnActivity);
} else {
intent = new Intent(this, VideoItemListActivity.class);
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
NavUtils.navigateUpTo(this, intent);
}
}
private void buildInfo(ErrorInfo info) {
TextView infoLabelView = (TextView) findViewById(R.id.errorInfoLabelsView);
TextView infoView = (TextView) findViewById(R.id.errorInfosView);
String text = "";
infoLabelView.setText(getString(R.string.info_labels).replace("\\n", "\n"));
String whatString = "";
switch (info.userAction) {
case REQUESTED_STREAM:
whatString = REQUESTED_STREAM_STRING;
break;
case SEARCHED:
whatString = SEARCHED_STRING;
break;
default:
whatString = "Your description is in another castle.";
}
String contentLang = PreferenceManager.getDefaultSharedPreferences(this)
.getString(this.getString(R.string.search_language_key), "none");
String osBase = Build.VERSION.SDK_INT >= 23 ? Build.VERSION.BASE_OS : "Android";
String osString = (osBase.isEmpty() ? "Android" : osBase)
+ " " + Build.VERSION.RELEASE;
text += whatString
+ "\n" + info.request
+ "\n" + contentLang
+ "\n" + info.serviceName
+ "\n" + BuildConfig.VERSION_NAME
+ "\n" + osString;
infoView.setText(text);
}
private void addGuruMeditaion() {
//just an easter egg
TextView sorryView = (TextView) findViewById(R.id.errorSorryView);
String text = sorryView.getText().toString();
text += "\n" + getString(R.string.guru_meditation);
sorryView.setText(text);
}
@Override
public void onBackPressed() {
//super.onBackPressed();
goToReturnActivity();
}
}

View File

@ -46,7 +46,6 @@ import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import java.util.ArrayList;
import java.util.Vector;
import org.schabi.newpipe.errorhandling.ErrorActivity;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.ParsingException;
import org.schabi.newpipe.extractor.ServiceList;
@ -167,23 +166,26 @@ public class VideoItemDetailFragment extends Fragment {
});
e.printStackTrace();
} catch (ParsingException e) {
ErrorActivity.reportError(h, getActivity(), e, 0, VideoItemListActivity.class);
h.post(new Runnable() {
@Override
public void run() {
getActivity().finish();
}
});
ErrorActivity.reportError(h, getActivity(), e, VideoItemListActivity.class, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
service.getServiceInfo().name, videoUrl, R.string.parsing_error));
h.post(new Runnable() {
@Override
public void run() {
getActivity().finish();
}
});
e.printStackTrace();
} catch(Exception e) {
ErrorActivity.reportError(h, getActivity(), e,
R.string.general_error, VideoItemListActivity.class);
h.post(new Runnable() {
@Override
public void run() {
getActivity().finish();
}
});
ErrorActivity.reportError(h, getActivity(), e, VideoItemListActivity.class, null,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
service.getServiceInfo().name, videoUrl, R.string.general_error));
h.post(new Runnable() {
@Override
public void run() {
getActivity().finish();
}
});
e.printStackTrace();
} finally {
if(videoInfo != null &&
@ -192,9 +194,13 @@ public class VideoItemDetailFragment extends Fragment {
for(Exception e : videoInfo.errors) {
e.printStackTrace();
}
//todo: do not call directly ask the user if it should be reported
Activity a = getActivity();
View rootView = a != null ? a.findViewById(R.id.videoitem_detail) : null;
ErrorActivity.reportError(h, getActivity(),
videoInfo.errors, 0, VideoItemDetailActivity.class);
videoInfo.errors, null, rootView,
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
service.getServiceInfo().name, videoUrl, 0 /* no message for the user */));
}
}
}

View File

@ -17,12 +17,10 @@ import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import org.schabi.newpipe.errorhandling.ErrorActivity;
import org.schabi.newpipe.extractor.ExtractionException;
import org.schabi.newpipe.extractor.SearchEngine;
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.VideoPreviewInfo;
import java.io.IOException;
import java.util.ArrayList;

View File

@ -1,125 +0,0 @@
package org.schabi.newpipe.errorhandling;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.view.MenuItem;
import android.widget.TextView;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.schabi.newpipe.ActivityCommunicator;
import org.schabi.newpipe.R;
import org.schabi.newpipe.VideoItemListActivity;
import java.util.List;
import java.util.Vector;
public class ErrorActivity extends AppCompatActivity {
private List<Exception> errorList;
private Class returnActivity;
// views
private TextView errorView;
public static void reportError(Context context, List<Exception> el, int message, Class returnAcitivty) {
ActivityCommunicator ac = ActivityCommunicator.getCommunicator();
ac.errorList = el;
ac.returnActivity = returnAcitivty;
Intent intent = new Intent(context, ErrorActivity.class);
context.startActivity(intent);
}
public static void reportError(Context context, Exception e, int message, Class returnAcitivty) {
List<Exception> el = new Vector<>();
el.add(e);
reportError(context, el, message, returnAcitivty);
}
// async call
public static void reportError(Handler handler, final Context context,
final Exception e, final int message, final Class returnAcitivty) {
List<Exception> el = new Vector<>();
el.add(e);
reportError(handler, context, el, message, returnAcitivty);
}
// async call
public static void reportError(Handler handler, final Context context,
final List<Exception> el, final int message, final Class returnAcitivty) {
handler.post(new Runnable() {
@Override
public void run() {
reportError(context, el, message, returnAcitivty);
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_error);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ActivityCommunicator ac = ActivityCommunicator.getCommunicator();
errorList = ac.errorList;
returnActivity = ac.returnActivity;
errorView = (TextView) findViewById(R.id.errorView);
errorView.setText(formErrorText(errorList));
//importand add gurumeditaion
addGuruMeditaion();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
goToReturnActivity();
return true;
}
return false;
}
private String formErrorText(List<Exception> el) {
String text = "";
for(Exception e : el) {
text += "-------------------------------------\n"
+ ExceptionUtils.getStackTrace(e);
}
text += "-------------------------------------";
return text;
}
private void goToReturnActivity() {
Intent intent;
if(returnActivity != null &&
returnActivity.isAssignableFrom(Activity.class)) {
intent = new Intent(this, returnActivity);
} else {
intent = new Intent(this, VideoItemListActivity.class);
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
NavUtils.navigateUpTo(this, intent);
}
private void addGuruMeditaion() {
//just an easter egg
TextView sorryView = (TextView) findViewById(R.id.errorSorryView);
String text = sorryView.getText().toString();
text += "\n" + getString(R.string.guru_meditation);
sorryView.setText(text);
}
@Override
public void onBackPressed() {
super.onBackPressed();
goToReturnActivity();
}
}

View File

@ -21,8 +21,6 @@ package org.schabi.newpipe.extractor;
*/
public class ExtractionException extends Exception {
public ExtractionException() {}
public ExtractionException(String message) {
super(message);
}

View File

@ -22,7 +22,6 @@ package org.schabi.newpipe.extractor;
public class ParsingException extends ExtractionException {
public ParsingException() {}
public ParsingException(String message) {
super(message);
}

View File

@ -29,7 +29,6 @@ import java.util.List;
public interface StreamExtractor {
public class ExctractorInitException extends ExtractionException {
public ExctractorInitException() {}
public ExctractorInitException(String message) {
super(message);
}
@ -42,7 +41,6 @@ public interface StreamExtractor {
}
public class ContentNotAvailableException extends ParsingException {
public ContentNotAvailableException() {}
public ContentNotAvailableException(String message) {
super(message);
}

View File

@ -69,8 +69,8 @@ public class YoutubeStreamExtractor implements StreamExtractor {
}
public class LiveStreamException extends ContentNotAvailableException {
LiveStreamException() {
super();
LiveStreamException(String message) {
super(message);
}
}
@ -250,7 +250,7 @@ public class YoutubeStreamExtractor implements StreamExtractor {
throw new ParsingException("Could not parse yt player config", e);
}
if (isLiveStream) {
throw new LiveStreamException();
throw new LiveStreamException("This is a Life stream. Can't use those right now.");
}
return playerArgs;
@ -330,6 +330,8 @@ public class YoutubeStreamExtractor implements StreamExtractor {
@Override
public String getUploader() throws ParsingException {
throw new ParsingException("blabla");
/*
try {
if (playerArgs == null) {
return videoInfoPage.get("author");
@ -345,6 +347,7 @@ public class YoutubeStreamExtractor implements StreamExtractor {
} catch (Exception e) {
throw new ParsingException("failed permanently to load uploader name.", e);
}
*/
}
@Override

View File

@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.schabi.newpipe.errorhandling.ErrorActivity">
tools:context=".ErrorActivity">
<ScrollView
android:id="@+id/scrollView"
@ -17,7 +17,9 @@
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
android:paddingTop="@dimen/activity_vertical_margin"
android:focusable="true"
android:focusableInTouchMode="true">
<TextView
android:id="@+id/errorSorryView"
@ -28,13 +30,49 @@
android:text="@string/sorry_string"
android:textStyle="bold" />
<TextView
android:id="@+id/errorDeviceHeadlineView"
android:paddingTop="@dimen/activity_vertical_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/what_device_headline"/>
<LinearLayout
android:id="@+id/errorInfoLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/errorInfoLabelsView"
android:layout_weight="1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:text="@string/info_labels"/>
<HorizontalScrollView
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/errorInfosView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</HorizontalScrollView>
</LinearLayout>
<TextView
android:id="@+id/errorWhatHappenedView"
android:paddingTop="@dimen/activity_vertical_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="What happened:"/>
android:text="@string/what_happened_headline"/>
<HorizontalScrollView
android:layout_width="match_parent"

View File

@ -92,6 +92,14 @@
<string name="sorry_string">Sorry that should not happen.</string>
<string name="guru_meditation" translatable="false">Guru Meditation.</string>
<string name="error_report_button_text">Report error via mail</string>
<string name="error_snackbar_message">Sorry some errors occurred.</string>
<string name="error_snackbar_action">REPORT</string>
<string name="what_device_headline">Info:</string>
<string name="what_happened_headline">What happened:</string>
<string name="info_labels">What:\\nRequest:\\nContent Lang:\\nService:\\nVersion:\\nOS version:</string>
<string name="info_searched_lbl">Searched for:</string>
<string name="info_requested_stream_lbl">Requested stream:</string>
<string name="your_commend">Your commend:</string>
<!-- Content descriptions (for better accessibility) -->