implements #1233
authortobiasKaminsky <tobias@kaminsky.me>
Sat, 31 Oct 2015 12:18:20 +0000 (13:18 +0100)
committertobiasKaminsky <tobias@kaminsky.me>
Sat, 31 Oct 2015 12:18:20 +0000 (13:18 +0100)
AndroidManifest.xml
res/layout/error_send.xml [new file with mode: 0644]
res/values/strings.xml
src/com/owncloud/android/MainApp.java
src/com/owncloud/android/ui/activity/ErrorReportActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/fragment/OCFileListFragment.java
src/com/owncloud/android/utils/ExceptionHandler.java [new file with mode: 0644]

index e426df4..b069594 100644 (file)
         <activity android:name=".ui.activity.ErrorsWhileCopyingHandlerActivity"/>
         
         <activity android:name=".ui.activity.LogHistoryActivity"/>
-        
+        <activity android:name=".ui.activity.ErrorReportActivity"/>
+
         <receiver android:name=".files.InstantUploadBroadcastReceiver">
             <intent-filter>
                 <!-- unofficially supported by many Android phones but not by HTC devices: -->
diff --git a/res/layout/error_send.xml b/res/layout/error_send.xml
new file mode 100644 (file)
index 0000000..7a80166
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ownCloud Android client application
+
+  Copyright (C) 2015 ownCloud Inc.
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License version 2,
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:weightSum="1" >
+
+    <ScrollView
+        android:id="@+id/scrollView1"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginBottom="@dimen/standard_margin"
+        android:layout_weight="1">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:paddingLeft="@dimen/standard_padding"
+            android:paddingRight="@dimen/standard_padding">
+
+            <TextView
+                android:id="@+id/logTV"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:text="@string/empty"
+                android:typeface="monospace"/>
+        </LinearLayout>
+    </ScrollView>
+
+    <LinearLayout
+        android:id="@+id/historyButtonBar"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginBottom="@dimen/standard_margin"
+        android:layout_marginLeft="@dimen/standard_margin"
+        android:layout_marginRight="@dimen/standard_margin">
+
+    <Button
+        android:id="@+id/cancelErrorLogButton"
+        android:theme="@style/Button"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:layout_weight="1"
+        android:text="@string/error_log_exit" />
+
+    <android.support.v7.widget.AppCompatButton
+        android:id="@+id/sendErrorLogButton"
+        android:theme="@style/Button.Primary"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:layout_weight="1"
+        android:text="@string/error_log_send" />
+
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
index b0ff1fe..9b9742b 100644 (file)
     <string name="confirmation_remove_files_alert">Do you really want to remove selected items?</string>
     <string name="confirmation_remove_folders_alert">Do you really want to remove a folder and its content?</string>
     <string name="confirmation_remove_files">selected items</string>
+    <string name="error_log_exit">Exit</string>
+    <string name="error_log_send">Send Log</string>
+    <string name="error_log_title">Error Log</string>
 
 </resources>
index 250b7ae..6bf385c 100644 (file)
@@ -23,6 +23,7 @@ package com.owncloud.android;
 import android.app.Activity;
 import android.app.Application;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Build;
@@ -33,6 +34,7 @@ import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.utils.ExceptionHandler;
 
 
 /**
@@ -60,6 +62,9 @@ public class MainApp extends Application {
     public void onCreate(){
         super.onCreate();
         MainApp.mContext = getApplicationContext();
+
+        // Setup handler for uncaught exceptions.
+        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
         
         boolean isSamlAuth = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
 
diff --git a/src/com/owncloud/android/ui/activity/ErrorReportActivity.java b/src/com/owncloud/android/ui/activity/ErrorReportActivity.java
new file mode 100644 (file)
index 0000000..5270049
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package com.owncloud.android.ui.activity;
+
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.AppCompatActivity;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.owncloud.android.R;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.ui.dialog.LoadingDialog;
+import com.owncloud.android.utils.FileStorageUtils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+
+
+public class ErrorReportActivity extends AppCompatActivity {
+
+    private static final String TAG = ErrorReportActivity.class.getSimpleName();
+
+    private String mLogText;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.error_send);
+        setTitle(getString(R.string.error_log_title));
+        Button cancelErrorLogButton = (Button) findViewById(R.id.cancelErrorLogButton);
+        Button sendErrorLogButton = (Button) findViewById(R.id.sendErrorLogButton);
+        TextView logTV = (TextView) findViewById(R.id.logTV);
+
+        Intent intent = getIntent();
+        String action = intent.getAction();
+        String type = intent.getType();
+
+        if (Intent.ACTION_SEND.equals(action) && type != null) {
+                mLogText = intent.getStringExtra(Intent.EXTRA_TEXT);
+        } else {
+            // Handle other intents, such as being started from the home screen
+            mLogText = "Error, nothing received!";
+        }
+
+        logTV.setText(mLogText);
+
+        // TODO add Cancel Button
+        cancelErrorLogButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                finishAffinity();
+
+            }
+        });
+
+        sendErrorLogButton.setOnClickListener(new OnClickListener() {
+
+            @Override
+            public void onClick(View v) {
+                sendMail();
+            }
+        });
+    }
+
+    /**
+     * Start activity for sending email with logs attached
+     */
+    private void sendMail() {
+        Intent sendIntent = new Intent();
+        sendIntent.setAction(Intent.ACTION_SEND);
+        sendIntent.putExtra(Intent.EXTRA_TEXT, mLogText);
+        sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        sendIntent.setType("text/plain");
+        startActivity(sendIntent);
+    }
+}
\ No newline at end of file
index 804d507..51a77a8 100644 (file)
@@ -65,6 +65,7 @@ import com.owncloud.android.ui.dialog.UploadSourceDialogFragment;
 import com.owncloud.android.ui.preview.PreviewImageFragment;
 import com.owncloud.android.ui.preview.PreviewMediaFragment;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ExceptionHandler;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.ui.preview.PreviewTextFragment;
 
@@ -469,6 +470,10 @@ public class OCFileListFragment extends ExtendedListFragment {
 
     @Override
     public void onItemClick(AdapterView<?> l, View v, int position, long id) {
+        // NPE
+        String string = null;
+        Log_OC.d(TAG, string.toString());
+
         OCFile file = (OCFile) mAdapter.getItem(position);
         if (file != null) {
             if (file.isFolder()) {
diff --git a/src/com/owncloud/android/utils/ExceptionHandler.java b/src/com/owncloud/android/utils/ExceptionHandler.java
new file mode 100644 (file)
index 0000000..b06ec70
--- /dev/null
@@ -0,0 +1,102 @@
+package com.owncloud.android.utils;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+
+import com.owncloud.android.MainApp;
+import com.owncloud.android.ui.activity.ErrorReportActivity;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+// from https://stackoverflow.com/questions/23486627/catching-error-and-user-information#answer-23486834
+public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
+
+    Context context;
+    private final String LINE_SEPARATOR = "\n";
+
+    public ExceptionHandler() {
+        // TODO Auto-generated constructor stub
+        context = MainApp.getAppContext();
+    }
+
+    @Override
+    public void uncaughtException(Thread arg0, Throwable arg1) {
+        // TODO Auto-generated method stub
+
+        StringWriter stackTrace = new StringWriter();
+        arg1.printStackTrace(new PrintWriter(stackTrace));
+        final StringBuilder errorReport = new StringBuilder();
+        errorReport.append("************ CAUSE OF ERROR ************\n\n");
+        errorReport.append(stackTrace.toString());
+
+        errorReport.append("\n************ DEVICE INFORMATION ***********\n");
+        errorReport.append("Brand: ");
+        errorReport.append(Build.BRAND);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Device: ");
+        errorReport.append(Build.DEVICE);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Model: ");
+        errorReport.append(Build.MODEL);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Id: ");
+        errorReport.append(Build.ID);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Product: ");
+        errorReport.append(Build.PRODUCT);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("\n************ FIRMWARE ************\n");
+        errorReport.append("SDK: ");
+        errorReport.append(Build.VERSION.SDK);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Release: ");
+        errorReport.append(Build.VERSION.RELEASE);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Incremental: ");
+        errorReport.append(Build.VERSION.INCREMENTAL);
+        errorReport.append(LINE_SEPARATOR);
+
+
+        //after this you can do whatever you want , like i start an activity and show error log there
+
+        if (isUIThread()) {
+            invokeLogActivity(errorReport);
+        } else {  //handle non UI thread throw uncaught exception
+
+            new Handler(Looper.getMainLooper()).post(new Runnable() {
+                @Override
+                public void run() {
+                    invokeLogActivity(errorReport);
+                }
+            });
+        }
+    }
+    private void invokeLogActivity(StringBuilder errorReport){
+//        Intent sendIntent = new Intent();
+//        sendIntent.setAction(Intent.ACTION_SEND);
+//        sendIntent.putExtra(Intent.EXTRA_TEXT, errorReport.toString());
+//        sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+//        sendIntent.setType("text/plain");
+//        context.startActivity(sendIntent);
+
+        Intent sendIntent = new Intent(context, ErrorReportActivity.class);
+        sendIntent.putExtra(Intent.EXTRA_TEXT, errorReport.toString());
+        sendIntent.setAction(Intent.ACTION_SEND);
+        sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        sendIntent.setType("text/plain");
+        context.startActivity(sendIntent);
+
+
+        System.exit(1);
+//        android.os.Process.killProcess(android.os.Process.myPid());
+
+        }
+
+    private boolean isUIThread(){
+        return Looper.getMainLooper().getThread() == Thread.currentThread();
+    }
+}
\ No newline at end of file