Skip to content

Commit

Permalink
Add device info and crash report share option
Browse files Browse the repository at this point in the history
  • Loading branch information
balsikandar committed Aug 15, 2017
1 parent f459600 commit 5cfdaa9
Show file tree
Hide file tree
Showing 35 changed files with 1,190 additions and 137 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package com.balsikandar.crashreporter.sample;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import com.balsikandar.crashreporter.CrashReporter;
import com.balsikandar.crashreporter.ui.CrashReporterActivity;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
Context context;
Context mContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand Down Expand Up @@ -62,11 +65,20 @@ public void run() {
context.getResources();
} catch (Exception e) {
//log caught Exception
CrashReporter.logException(e, MainActivity.class.getSimpleName());
CrashReporter.logException(e);
}

}
}).start();

mContext = this;
findViewById(R.id.crashLogActivity).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, CrashReporterActivity.class);
startActivity(intent);
}
});

}
}
38 changes: 8 additions & 30 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,47 +46,25 @@
android:textColor="@color/black"
android:textSize="14sp" />

<!--Add a crash here on a button and enjoy-->
<Button
android:id="@+id/crashLogActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="open crash list" />

</com.google.android.flexbox.FlexboxLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/addYourOwnCrash"
android:layout_below="@+id/crashContainers"
android:gravity="center">

<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/message"
android:textColor="@color/black"
android:textSize="17sp"
android:textStyle="bold" />

<TextView
android:id="@+id/crashReportDirectory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/message"
android:layout_marginTop="15dp"
android:gravity="center"
android:text="@string/crashesSaveDefaultPath"
android:textColor="@color/colorPrimary"
android:textSize="15sp" />
</RelativeLayout>
<!--Add a crash here on a button and enjoy-->

<TextView
android:id="@+id/addYourOwnCrash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:layout_marginBottom="10dp"
android:text="@string/add_your_crash"
android:textColor="@color/black"
android:textStyle="italic"
android:textSize="15sp" />
</RelativeLayout>
2 changes: 0 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@
<string name="index_out_of_bound_exception">IndexOutOfBound</string>
<string name="class_cast_exception">ClassCast Exeption</string>
<string name="array_store_exception">ArrayStoreException</string>
<string name="crashesSaveDefaultPath">/Android/data/your-app-package-name/files/crashReports</string>
<string name="message">Crash this app by clicking these buttons and check your logs at below location</string>
<string name="add_your_crash">Add your own crash and check if it gets logged</string>
</resources>
2 changes: 2 additions & 0 deletions crashreporter/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ dependencies {
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
testCompile 'junit:junit:4.12'
}

Expand Down
19 changes: 16 additions & 3 deletions crashreporter/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.balsikandar.crashreporter">

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">

<provider
android:name=".CrashReporterInitProvider"
android:authorities="${applicationId}.CrashReporterInitProvider"
android:enabled="true"
android:exported="false" />

<activity
android:name=".ui.CrashReporterActivity"
android:launchMode="singleTask"
android:taskAffinity="com.balsikandar.android.task"
android:theme="@style/CrashReporter.Theme" />

<activity
android:name=".ui.LogMessageActivity"
android:parentActivityName=".ui.CrashReporterActivity"
android:theme="@style/CrashReporter.Theme" />
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
package com.balsikandar.crashreporter;

import android.content.Context;
import android.content.Intent;

import com.balsikandar.crashreporter.custom.CrashReporterNotInitializedException;
import com.balsikandar.crashreporter.handler.CrashReporterExceptionHandler;
import com.balsikandar.crashreporter.ui.CrashReporterActivity;
import com.balsikandar.crashreporter.utils.CrashReporterNotInitializedException;
import com.balsikandar.crashreporter.utils.CrashReporterExceptionHandler;
import com.balsikandar.crashreporter.utils.CrashUtil;

public class CrashReporter {

private static Context applicationContext;

private static String crashReportPath;

private static boolean isNotificationEnabled = true;

private CrashReporter() {
// This class in not publicly instantiable
}

public static void initialize(Context context) {
applicationContext = context;
setUpExceptionHandler(null);
setUpExceptionHandler();
if (BuildConfig.DEBUG) {
CrashUtil.logD("CrashReporter", "your crash report files will be saved in \"android/data/your-app-pkg/crashReports/\" path");
}
}

public static void initialize(Context context, String crashReportPath) {
public static void initialize(Context context, String crashReportSavePath) {
applicationContext = context;
setUpExceptionHandler(crashReportPath);
crashReportPath = crashReportSavePath;
setUpExceptionHandler();
}

private static void setUpExceptionHandler() {
if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof CrashReporterExceptionHandler)) {
Thread.setDefaultUncaughtExceptionHandler(new CrashReporterExceptionHandler());
}
}

public static Context getContext() {
Expand All @@ -38,32 +51,25 @@ public static Context getContext() {
return applicationContext;
}

private static void setUpExceptionHandler(String crashReportPath) {
if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof CrashReporterExceptionHandler)) {
Thread.setDefaultUncaughtExceptionHandler(new CrashReporterExceptionHandler(
crashReportPath));
}
}

//LOG Exception APIs
public static void logException(Exception exception) {
CrashUtil.logException(null/*pass null for path*/, exception, null/*pass null for tag*/);
public static String getCrashReportPath() {
return crashReportPath;
}

public static void logException(Exception exception, String tag) {
CrashUtil.logException(null/*pass null for path*/, exception, tag);
public static boolean isNotificationEnabled() {
return isNotificationEnabled;
}

public static void logException(String exceptionMsg) {
CrashUtil.logException(null/*pass null for path*/, exceptionMsg);
//LOG Exception APIs
public static void logException(Exception exception) {
CrashUtil.logException(exception);
}

public static void logException(String exceptionSavePath, Exception exception) {
CrashUtil.logException(exceptionSavePath, exception, null/*pass null for tag*/);
public static Intent getLaunchIntent() {
return new Intent(applicationContext, CrashReporterActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}

public static void logException(String exceptionSavePath, String exceptionMsg) {
CrashUtil.logException(exceptionSavePath, exceptionMsg);
public static void disableNotification() {
isNotificationEnabled = false;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.balsikandar.crashreporter.adapter;

import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.balsikandar.crashreporter.R;
import com.balsikandar.crashreporter.ui.LogMessageActivity;
import com.balsikandar.crashreporter.utils.CrashUtil;
import com.balsikandar.crashreporter.utils.FileUtils;

import java.io.File;
import java.util.ArrayList;

/**
* Created by bali on 10/08/17.
*/

public class CrashLogAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private Context context;
private ArrayList<File> crashFileList;

public CrashLogAdapter(Context context, ArrayList<File> allCrashLogs) {
this.context = context;
crashFileList = allCrashLogs;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.custom_item, null);
return new CrashLogViewHolder(view);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((CrashLogViewHolder) holder).setUpViewHolder(context, crashFileList.get(position));
}

@Override
public int getItemCount() {
return crashFileList.size();
}


public void updateList(ArrayList<File> allCrashLogs) {
crashFileList = allCrashLogs;
notifyDataSetChanged();
}


private class CrashLogViewHolder extends RecyclerView.ViewHolder {
private TextView textViewMsg, messageLogTime;

CrashLogViewHolder(View itemView) {
super(itemView);
messageLogTime = (TextView) itemView.findViewById(R.id.messageLogTime);
textViewMsg = (TextView) itemView.findViewById(R.id.textViewMsg);
}

void setUpViewHolder(final Context context, final File file) {
final String filePath = file.getAbsolutePath();
messageLogTime.setText(file.getName().replaceAll("[a-zA-Z_.]", ""));
textViewMsg.setText(FileUtils.readFirstLineFromFile(new File(filePath)));

textViewMsg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, LogMessageActivity.class);
intent.putExtra("LogMessage", filePath);
context.startActivity(intent);
}
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.balsikandar.crashreporter.adapter;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import com.balsikandar.crashreporter.ui.CrashLogFragment;
import com.balsikandar.crashreporter.ui.ExceptionLogFragment;

/**
* Created by bali on 11/08/17.
*/

public class MainPagerAdapter extends FragmentPagerAdapter {

private CrashLogFragment crashLogFragment;
private ExceptionLogFragment exceptionLogFragment;
private String[] titles;

public MainPagerAdapter(FragmentManager fm, String[] titles) {
super(fm);
this.titles = titles;
}

@Override
public Fragment getItem(int position) {
if (position == 0) {
return crashLogFragment = new CrashLogFragment();
} else if (position == 1) {
return exceptionLogFragment = new ExceptionLogFragment();
} else {
return new CrashLogFragment();
}
}

@Override
public int getCount() {
return 2;
}

@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}

public void clearLogs() {
crashLogFragment.clearLog();
exceptionLogFragment.clearLog();
}
}
Loading

0 comments on commit 5cfdaa9

Please sign in to comment.