Cleaned Up code

Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
This commit is contained in:
2012-07-01 11:21:18 -04:00
parent c4980a8295
commit 42cb0b9f0e
9 changed files with 297 additions and 308 deletions

View File

@@ -1,11 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@@ -5,8 +5,8 @@
android:versionName="1.0" > android:versionName="1.0" >
<uses-sdk <uses-sdk
android:minSdkVersion="1" android:minSdkVersion="8"
android:targetSdkVersion="11" /> android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />

View File

@@ -35,84 +35,84 @@ import android.util.Log;
* @author ricky barrette * @author ricky barrette
*/ */
public class ExceptionHandler implements UncaughtExceptionHandler, Runnable { public class ExceptionHandler implements UncaughtExceptionHandler, Runnable {
private static final String MSG_SUBJECT_TAG = "Exception Report"; private static final String MSG_SUBJECT_TAG = "Exception Report";
private static final String MSG_BODY = "Just click send to help make this application better. "+ private static final String MSG_BODY = "Just click send to help make this application better. "+
"No personal information is being sent (you can check by reading the rest of the email)."; "No personal information is being sent (you can check by reading the rest of the email).";
protected static final int SIMPLE_NOTFICATION_ID = 45684645; protected static final int SIMPLE_NOTFICATION_ID = 45684645;
private Thread.UncaughtExceptionHandler mDefaultUEH; private final Thread.UncaughtExceptionHandler mDefaultUEH;
private Activity mApp= null; private Activity mApp= null;
private Service mService = null; private Service mService = null;
private BroadcastReceiver mBroadcastReceiver = null; private BroadcastReceiver mBroadcastReceiver = null;
private Context mContext; private final Context mContext;
private Report mReport; private Report mReport;
private static final String TAG = "ExceptionHandler"; private static final String TAG = "ExceptionHandler";
private String mURL = null; private String mURL = null;
private String mEmail; private String mEmail;
private String mAppName; private String mAppName;
private String mTracker; private String mTracker;
/** /**
* Creates a new ExceptionHandler * Creates a new ExceptionHandler
* @param app * @param app
* @author ricky barrette * @author ricky barrette
*/ */
public ExceptionHandler(Activity app) { public ExceptionHandler(final Activity app) {
this.mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler(); mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
this.mApp = app; mApp = app;
this.mContext = app; mContext = app;
parseProperties(); parseProperties();
} }
/** /**
* Creates a new ExceptionHandler * Creates a new ExceptionHandler
* @param broadcastReceiver * @param broadcastReceiver
* @author ricky barrette * @author ricky barrette
*/ */
public ExceptionHandler(BroadcastReceiver broadcastReceiver, Context context){ public ExceptionHandler(final BroadcastReceiver broadcastReceiver, final Context context){
this.mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler(); mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
this.mBroadcastReceiver = broadcastReceiver; mBroadcastReceiver = broadcastReceiver;
this.mContext = context; mContext = context;
parseProperties(); parseProperties();
} }
/** /**
* Creates a new ExceptionHandler * Creates a new ExceptionHandler
* @param service * @param service
* @author ricky barrette * @author ricky barrette
*/ */
public ExceptionHandler(Service service){ public ExceptionHandler(final Service service){
this.mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler(); mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
this.mService = service; mService = service;
this.mContext = service; mContext = service;
parseProperties(); parseProperties();
} }
/** /**
* Generates an email from the report * Generates an email from the report
* @author ricky barrette * @author ricky barrette
*/ */
private void displayEmailNotification(){ private void displayEmailNotification(){
Log.i(TAG, "displayEmailNotification"); Log.i(TAG, "displayEmailNotification");
CharSequence title = null; CharSequence title = null;
if(mApp != null) if(mApp != null)
title = mApp.getTitle(); title = mApp.getTitle();
if(mService != null) if(mService != null)
title = mService.getClass().getName(); title = mService.getClass().getName();
if(mBroadcastReceiver != null) if(mBroadcastReceiver != null)
title = mBroadcastReceiver.getClass().getName(); title = mBroadcastReceiver.getClass().getName();
Intent intent = new Intent(Intent.ACTION_SEND); final Intent intent = new Intent(Intent.ACTION_SEND);
String theSubject = title + " " + MSG_SUBJECT_TAG; final String theSubject = title + " " + MSG_SUBJECT_TAG;
String theBody = "\n\n"+MSG_BODY+this.mReport.toString(); final String theBody = "\n\n"+MSG_BODY+mReport.toString();
intent.putExtra(Intent.EXTRA_EMAIL,new String[] {this.mEmail}); intent.putExtra(Intent.EXTRA_EMAIL,new String[] {mEmail});
intent.putExtra(Intent.EXTRA_TEXT, theBody); intent.putExtra(Intent.EXTRA_TEXT, theBody);
intent.putExtra(Intent.EXTRA_SUBJECT, theSubject); intent.putExtra(Intent.EXTRA_SUBJECT, theSubject);
intent.setType("message/rfc822"); intent.setType("message/rfc822");
displayNotification(intent); displayNotification(intent);
} }
@@ -121,12 +121,12 @@ public class ExceptionHandler implements UncaughtExceptionHandler, Runnable {
* @param generatedReportIntent * @param generatedReportIntent
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void displayNotification(Intent generatedReportIntent) { private void displayNotification(final Intent generatedReportIntent) {
Log.i(TAG, "displayNotification"); Log.i(TAG, "displayNotification");
Context context = mContext.getApplicationContext(); final Context context = mContext.getApplicationContext();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notifyDetails = new Notification(android.R.drawable.stat_notify_error, context.getString(R.string.sorry), System.currentTimeMillis()); final Notification notifyDetails = new Notification(android.R.drawable.stat_notify_error, context.getString(R.string.sorry), System.currentTimeMillis());
PendingIntent intent = PendingIntent.getActivity(context, 0, generatedReportIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK); final PendingIntent intent = PendingIntent.getActivity(context, 0, generatedReportIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
notifyDetails.setLatestEventInfo(context, context.getString(R.string.crash), context.getString(R.string.sorry), intent); notifyDetails.setLatestEventInfo(context, context.getString(R.string.crash), context.getString(R.string.sorry), intent);
notifyDetails.flags |= Notification.FLAG_AUTO_CANCEL; notifyDetails.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails); notificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails);
@@ -137,30 +137,31 @@ public class ExceptionHandler implements UncaughtExceptionHandler, Runnable {
* @author ricky barrette * @author ricky barrette
*/ */
private void parseProperties() { private void parseProperties() {
Resources resources = this.mContext.getResources(); final Resources resources = mContext.getResources();
AssetManager assetManager = resources.getAssets(); final AssetManager assetManager = resources.getAssets();
// Read from the /assets directory // Read from the /assets directory
try { try {
InputStream inputStream = assetManager.open("exceptionhandler.properties"); final InputStream inputStream = assetManager.open("exceptionhandler.properties");
Properties properties = new Properties(); final Properties properties = new Properties();
properties.load(inputStream); properties.load(inputStream);
this.mURL = properties.getProperty("server"); mURL = properties.getProperty("server");
this.mEmail = properties.getProperty("email"); mEmail = properties.getProperty("email");
this.mAppName = properties.getProperty("app"); mAppName = properties.getProperty("app");
this.mTracker = properties.getProperty("tracker"); mTracker = properties.getProperty("tracker");
} catch (IOException e) { } catch (final IOException e) {
Log.e(TAG, "Failed to open exceptionhandler.properties"); Log.e(TAG, "Failed to open exceptionhandler.properties");
e.printStackTrace(); e.printStackTrace();
} }
} }
@Override
public void run() { public void run() {
if(this.mEmail == null) if(mEmail == null)
displayNotification(new Intent(this.mContext, ExceptionReportActivity.class).putExtra("report", this.mReport)); displayNotification(new Intent(mContext, ExceptionReportActivity.class).putExtra("report", mReport));
else else
displayEmailNotification(); displayEmailNotification();
} }
/** /**
* Called when there is an uncaught exception. * Called when there is an uncaught exception.
* (non-Javadoc) * (non-Javadoc)
@@ -168,62 +169,59 @@ public class ExceptionHandler implements UncaughtExceptionHandler, Runnable {
* @author ricky barrette * @author ricky barrette
*/ */
@Override @Override
public void uncaughtException(Thread t, Throwable e) { public void uncaughtException(final Thread t, final Throwable e) {
Log.d(TAG, "uncaughtException()"); Log.d(TAG, "uncaughtException()");
// Log.d(TAG,"mURL = "+ this.mURL);
// Log.d(TAG,"mEmail = "+ this.mEmail);
Date theDate = new Date(); // Log.d(TAG,"mURL = "+ this.mURL);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss_zzz"); // Log.d(TAG,"mEmail = "+ this.mEmail);
PackageManager pm = mContext.getPackageManager();
final Date theDate = new Date();
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss_zzz");
final PackageManager pm = mContext.getPackageManager();
//app environment; //app environment;
PackageInfo pi; PackageInfo pi;
try { try {
pi = pm.getPackageInfo(mContext.getPackageName(), 0); pi = pm.getPackageInfo(mContext.getPackageName(), 0);
} catch (NameNotFoundException eNnf) { } catch (final NameNotFoundException eNnf) {
//doubt this will ever run since we want info about our own package //doubt this will ever run since we want info about our own package
pi = new PackageInfo(); pi = new PackageInfo();
pi.versionName = "unknown"; pi.versionName = "unknown";
pi.versionCode = 69; pi.versionCode = 69;
} }
StringBuffer report = new StringBuffer(); final StringBuffer report = new StringBuffer();
for (StackTraceElement item : e.getStackTrace()) for (final StackTraceElement item : e.getStackTrace())
report.append("at "+item.toString() + "\n"); report.append("at "+item.toString() + "\n");
StringBuffer causereport = new StringBuffer(); final StringBuffer causereport = new StringBuffer();
Throwable cause = e.getCause(); final Throwable cause = e.getCause();
if (cause != null) { if (cause != null) {
causereport.append(cause.toString() + "\n \n"); causereport.append(cause.toString() + "\n \n");
for (StackTraceElement item : cause.getStackTrace()) for (final StackTraceElement item : cause.getStackTrace())
causereport.append("at "+item.toString() + "\n"); causereport.append("at "+item.toString() + "\n");
} }
//generate the report //generate the report
this.mReport = new Report(mURL).generateReport(e.toString(), report.toString(), causereport.toString(), sdf.format(theDate), Build.FINGERPRINT, pi.versionName+"b"+pi.versionCode, mAppName != null ? mAppName : mContext.getPackageName(), this.mTracker, mContext.getPackageName()); mReport = new Report(mURL).generateReport(e.toString(), report.toString(), causereport.toString(), sdf.format(theDate), Build.FINGERPRINT, pi.versionName+"b"+pi.versionCode, mAppName != null ? mAppName : mContext.getPackageName(), mTracker, mContext.getPackageName());
//try to send file contents via email (need to do so via the UI thread) //try to send file contents via email (need to do so via the UI thread)
if(this.mApp != null){ if(mApp != null)
this.mApp.runOnUiThread(this); mApp.runOnUiThread(this);
}
if(mService != null)
if(this.mService != null){ if(mEmail == null)
if(this.mEmail == null) displayNotification(new Intent(mContext, ExceptionReportActivity.class).putExtra("report", mReport));
displayNotification(new Intent(this.mContext, ExceptionReportActivity.class).putExtra("report", this.mReport));
else else
displayEmailNotification(); displayEmailNotification();
}
if(mBroadcastReceiver != null)
if(this.mBroadcastReceiver != null){ if(mEmail == null)
if(this.mEmail == null) displayNotification(new Intent(mContext, ExceptionReportActivity.class).putExtra("report", mReport));
displayNotification(new Intent(this.mContext, ExceptionReportActivity.class).putExtra("report", this.mReport));
else else
displayEmailNotification(); displayEmailNotification();
}
//do not forget to pass this exception through up the chain //do not forget to pass this exception through up the chain
mDefaultUEH.uncaughtException(t,e); mDefaultUEH.uncaughtException(t,e);
} }

View File

@@ -24,39 +24,39 @@ public class ExceptionReportActivity extends Activity implements OnClickListener
private static final String TAG = "ExceptionActivity"; private static final String TAG = "ExceptionActivity";
private Report mReport; private Report mReport;
/**
* (non-Javadoc)
* @see android.app.Activity#onCreate(android.os.Bundle)
* @author ricky barrette
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate()");
super.onCreate(savedInstanceState);
this.mReport = (Report) this.getIntent().getParcelableExtra("report");
if(this.getIntent().hasExtra("display"))
this.setContentView(R.layout.list);
else {
this.setContentView(R.layout.exception_activity);
this.findViewById(R.id.send).setOnClickListener(this);
}
ListView list = (ListView) this.findViewById(android.R.id.list);
list.setAdapter(new ReportAdapter(this, this.mReport.getReport()));
list.setClickable(false);
}
/** /**
* (non-Javadoc) * (non-Javadoc)
* @see android.view.View.OnClickListener#onClick(android.view.View) * @see android.view.View.OnClickListener#onClick(android.view.View)
* @author ricky barrette * @author ricky barrette
*/ */
@Override @Override
public void onClick(View v) { public void onClick(final View v) {
EditText description = (EditText) findViewById(R.id.description); final EditText description = (EditText) findViewById(R.id.description);
this.mReport.setDescription(description.getText().toString()); mReport.setDescription(description.getText().toString());
v.setEnabled(false); v.setEnabled(false);
this.startService(new Intent(this, ReportPostingService.class).putExtra("report", this.mReport)); startService(new Intent(this, ReportPostingService.class).putExtra("report", mReport));
this.finish(); finish();
}
/**
* (non-Javadoc)
* @see android.app.Activity#onCreate(android.os.Bundle)
* @author ricky barrette
*/
@Override
protected void onCreate(final Bundle savedInstanceState) {
Log.d(TAG, "onCreate()");
super.onCreate(savedInstanceState);
mReport = (Report) getIntent().getParcelableExtra("report");
if(getIntent().hasExtra("display"))
this.setContentView(R.layout.list);
else {
this.setContentView(R.layout.exception_activity);
findViewById(R.id.send).setOnClickListener(this);
}
final ListView list = (ListView) findViewById(android.R.id.list);
list.setAdapter(new ReportAdapter(this, mReport.getReport()));
list.setClickable(false);
} }
} }

View File

@@ -36,13 +36,15 @@ public class Report implements Parcelable{
private final String mUrl; private final String mUrl;
private ArrayList<ReportItem> mReport; private ArrayList<ReportItem> mReport;
public static final Parcelable.Creator<Report> CREATOR = new Parcelable.Creator<Report>() { public static final Parcelable.Creator<Report> CREATOR = new Parcelable.Creator<Report>() {
public Report createFromParcel(Parcel in) { @Override
public Report createFromParcel(final Parcel in) {
return new Report(in); return new Report(in);
} }
public Report[] newArray(int size) { @Override
public Report[] newArray(final int size) {
return new Report[size]; return new Report[size];
} }
}; };
@@ -52,71 +54,71 @@ public class Report implements Parcelable{
* @param in * @param in
* @author ricky barrette * @author ricky barrette
*/ */
public Report(Parcel in){ public Report(final Parcel in){
this.mUrl = in.readString(); mUrl = in.readString();
this.mReport = new ArrayList<ReportItem>(); mReport = new ArrayList<ReportItem>();
in.readTypedList(this.mReport, ReportItem.CREATOR); in.readTypedList(mReport, ReportItem.CREATOR);
} }
/** /**
* Creates a new Report * Creates a new Report
* @author ricky barrette * @author ricky barrette
*/ */
public Report(String url) { public Report(final String url) {
// Log.d(TAG, url); // Log.d(TAG, url);
this.mUrl = url; mUrl = url;
} }
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;
} }
/** /**
* Files the report with the remote database * Files the report with the remote database
* @author ricky barrette * @author ricky barrette
* @throws IOException * @throws IOException
* @throws ClientProtocolException * @throws ClientProtocolException
* @return String result * @return String result
*/ */
public String file() throws ClientProtocolException, IOException{ public String file() throws ClientProtocolException, IOException{
HttpClient httpclient = new DefaultHttpClient(); final HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(mUrl); final HttpPost httppost = new HttpPost(mUrl);
httppost.setEntity(new UrlEncodedFormEntity(getNameValuePairs())); httppost.setEntity(new UrlEncodedFormEntity(getNameValuePairs()));
//return the results //return the results
HttpResponse response = httpclient.execute(httppost); final HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity(); final HttpEntity entity = response.getEntity();
InputStream is = entity.getContent(); final InputStream is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8); final BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append(reader.readLine() + "\n"); sb.append(reader.readLine() + "\n");
String line="0"; String line="0";
while ((line = reader.readLine()) != null) while ((line = reader.readLine()) != null)
sb.append(line + "\n"); sb.append(line + "\n");
is.close(); is.close();
reader.close(); reader.close();
return sb.toString(); return sb.toString();
} }
/** /**
* Generates a report to be displayed form a downloaded JSON object * Generates a report to be displayed form a downloaded JSON object
* @param report * @param report
* @return * @return
* @author ricky barrette * @author ricky barrette
* @throws JSONException * @throws JSONException
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public Report generateReport(JSONObject report) throws JSONException{ public Report generateReport(final JSONObject report) throws JSONException{
this.mReport = new ArrayList<ReportItem>(); mReport = new ArrayList<ReportItem>();
Iterator iter = report.keys(); final Iterator iter = report.keys();
while(iter.hasNext()){ while(iter.hasNext()){
String key = (String)iter.next(); final String key = (String)iter.next();
this.mReport.add(new ReportItem(key , report.getString(key))); mReport.add(new ReportItem(key , report.getString(key)));
} }
return this; return this;
} }
/** /**
* Generates a report to be sent. * Generates a report to be sent.
* @param msg * @param msg
@@ -128,17 +130,17 @@ public class Report implements Parcelable{
* @return this * @return this
* @author ricky barrette * @author ricky barrette
*/ */
public Report generateReport(String msg, String stackTrace, String cause, String date, String device, String appVersion, String app, String tracker, String packageName){ public Report generateReport(final String msg, final String stackTrace, final String cause, final String date, final String device, final String appVersion, final String app, final String tracker, final String packageName){
this.mReport = new ArrayList<ReportItem>(); mReport = new ArrayList<ReportItem>();
this.mReport.add(new ReportItem("app",app)); mReport.add(new ReportItem("app",app));
this.mReport.add(new ReportItem("version",appVersion)); mReport.add(new ReportItem("version",appVersion));
this.mReport.add(new ReportItem("date",date)); mReport.add(new ReportItem("date",date));
this.mReport.add(new ReportItem("msg",msg)); mReport.add(new ReportItem("msg",msg));
this.mReport.add(new ReportItem("stackTrace",stackTrace)); mReport.add(new ReportItem("stackTrace",stackTrace));
this.mReport.add(new ReportItem("cause",cause)); mReport.add(new ReportItem("cause",cause));
this.mReport.add(new ReportItem("device",device)); mReport.add(new ReportItem("device",device));
this.mReport.add(new ReportItem("tracker",tracker)); mReport.add(new ReportItem("tracker",tracker));
this.mReport.add(new ReportItem("package",packageName)); mReport.add(new ReportItem("package",packageName));
return this; return this;
} }
@@ -148,9 +150,9 @@ public class Report implements Parcelable{
* @author ricky barrette * @author ricky barrette
*/ */
private ArrayList<NameValuePair> getNameValuePairs() { private ArrayList<NameValuePair> getNameValuePairs() {
ArrayList<NameValuePair> list = new ArrayList<NameValuePair>(); final ArrayList<NameValuePair> list = new ArrayList<NameValuePair>();
for(ReportItem entry : this.mReport) for(final ReportItem entry : mReport)
list.add(new BasicNameValuePair(entry.getKey(), (String) entry.getValue())); list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
return list; return list;
} }
@@ -167,8 +169,8 @@ public class Report implements Parcelable{
* @param string * @param string
* @author ricky barrette * @author ricky barrette
*/ */
public Report setDescription(String description) { public Report setDescription(final String description) {
this.mReport.add(new ReportItem("description", description)); mReport.add(new ReportItem("description", description));
return this; return this;
} }
@@ -178,17 +180,17 @@ public class Report implements Parcelable{
*/ */
@Override @Override
public String toString(){ public String toString(){
StringBuilder s = new StringBuilder(); final StringBuilder s = new StringBuilder();
for(ReportItem item : this.mReport){ for(final ReportItem item : mReport){
s.append("\n\n-----"+ item.getKey()+"-----"); s.append("\n\n-----"+ item.getKey()+"-----");
s.append("\n"+item.getValue()); s.append("\n"+item.getValue());
} }
return s.toString(); return s.toString();
} }
@Override @Override
public void writeToParcel(Parcel out, int flags) { public void writeToParcel(final Parcel out, final int flags) {
out.writeString(this.mUrl); out.writeString(mUrl);
out.writeTypedList(this.mReport); out.writeTypedList(mReport);
} }
} }

View File

@@ -17,26 +17,29 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.TextView; import android.widget.TextView;
import com.TwentyCodes.android.exception.R;
/** /**
* This class will be used to populate a custom Listview used to display the Generated exception report * This class will be used to populate a custom Listview used to display the Generated exception report
* @author ricky barrette * @author ricky barrette
*/ */
public class ReportAdapter extends BaseAdapter { public class ReportAdapter extends BaseAdapter {
private ArrayList<NameValuePair> mReport; class ViewHolder {
private LayoutInflater mInflater; TextView title;
TextView body;
}
private final ArrayList<NameValuePair> mReport;
private final LayoutInflater mInflater;
/** /**
* Creates a new ReportAdapter * Creates a new ReportAdapter
* @author ricky barrette * @author ricky barrette
*/ */
public ReportAdapter(Context context, ArrayList<NameValuePair> report) { public ReportAdapter(final Context context, final ArrayList<NameValuePair> report) {
super(); super();
// Cache the LayoutInflate to avoid asking for a new one each time. // Cache the LayoutInflate to avoid asking for a new one each time.
this.mInflater = LayoutInflater.from(context); mInflater = LayoutInflater.from(context);
this.mReport = report; mReport = report;
} }
/** /**
@@ -46,7 +49,7 @@ public class ReportAdapter extends BaseAdapter {
*/ */
@Override @Override
public int getCount() { public int getCount() {
return this.mReport.size(); return mReport.size();
} }
/** /**
@@ -55,8 +58,8 @@ public class ReportAdapter extends BaseAdapter {
* @author ricky barrette * @author ricky barrette
*/ */
@Override @Override
public NameValuePair getItem(int index) { public NameValuePair getItem(final int index) {
return this.mReport.get(index); return mReport.get(index);
} }
/** /**
@@ -65,7 +68,7 @@ public class ReportAdapter extends BaseAdapter {
* @author ricky barrette * @author ricky barrette
*/ */
@Override @Override
public long getItemId(int index) { public long getItemId(final int index) {
return index; return index;
} }
@@ -73,40 +76,34 @@ public class ReportAdapter extends BaseAdapter {
* *
*/ */
@Override @Override
public View getView(final int position, View convertView, ViewGroup parent) { public View getView(final int position, View convertView, final ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unnecessary calls to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need // A ViewHolder keeps references to children views to avoid unnecessary calls to findViewById() on each row.
// to reinflate it. We only inflate a new View when the convertView supplied ViewHolder holder;
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.exception_list_item, null);
// Creates a ViewHolder and store references to the two children views // When convertView is not null, we can reuse it directly, there is no need
// we want to bind data to. // to reinflate it. We only inflate a new View when the convertView supplied
holder = new ViewHolder(); // by ListView is null.
holder.title = (TextView) convertView.findViewById(R.id.exception_title); if (convertView == null) {
holder.body = (TextView) convertView.findViewById(R.id.exception_text); convertView = mInflater.inflate(R.layout.exception_list_item, null);
convertView.setTag(holder); // Creates a ViewHolder and store references to the two children views
} else { // we want to bind data to.
holder = (ViewHolder) convertView.getTag(); holder = new ViewHolder();
} holder.title = (TextView) convertView.findViewById(R.id.exception_title);
holder.body = (TextView) convertView.findViewById(R.id.exception_text);
/*
* Bind the data efficiently with the holder. convertView.setTag(holder);
*/ } else
holder.title.setText(getItem(position).getName()); holder = (ViewHolder) convertView.getTag();
holder.body.setText(getItem(position).getValue());
/*
return convertView; * Bind the data efficiently with the holder.
*/
holder.title.setText(getItem(position).getName());
holder.body.setText(getItem(position).getValue());
return convertView;
} }
class ViewHolder {
TextView title;
TextView body;
}
} }

View File

@@ -17,34 +17,36 @@ import android.os.Parcelable;
public final class ReportItem implements Parcelable { public final class ReportItem implements Parcelable {
public static final Parcelable.Creator<ReportItem> CREATOR = new Parcelable.Creator<ReportItem>() { public static final Parcelable.Creator<ReportItem> CREATOR = new Parcelable.Creator<ReportItem>() {
public ReportItem createFromParcel(Parcel in) { @Override
public ReportItem createFromParcel(final Parcel in) {
return new ReportItem(in); return new ReportItem(in);
} }
public ReportItem[] newArray(int size) { @Override
public ReportItem[] newArray(final int size) {
return new ReportItem[size]; return new ReportItem[size];
} }
}; };
private final String mKey; private final String mKey;
private final String mValue; private final String mValue;
/**
* Creates a new ReportItem
* @author ricky barrette
*/
public ReportItem(String key, String value) {
this.mKey = key;
this.mValue = value;
}
/** /**
* Creates a new ReportItem from a parcel * Creates a new ReportItem from a parcel
* @param in * @param in
*/ */
public ReportItem(Parcel in){ public ReportItem(final Parcel in){
this.mKey = in.readString(); mKey = in.readString();
this.mValue = in.readString(); mValue = in.readString();
}
/**
* Creates a new ReportItem
* @author ricky barrette
*/
public ReportItem(final String key, final String value) {
mKey = key;
mValue = value;
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -56,27 +58,27 @@ public final class ReportItem implements Parcelable {
return 0; return 0;
} }
/* (non-Javadoc)
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.mKey);
dest.writeString(this.mValue);
}
/** /**
* @return the key * @return the key
*/ */
public String getKey() { public String getKey() {
return this.mKey; return mKey;
} }
/** /**
* @return the value * @return the value
*/ */
public String getValue() { public String getValue() {
return this.mValue; return mValue;
}
/* (non-Javadoc)
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
*/
@Override
public void writeToParcel(final Parcel dest, final int flags) {
dest.writeString(mKey);
dest.writeString(mValue);
} }
} }

View File

@@ -28,7 +28,7 @@ import android.util.Log;
* @author ricky barrette * @author ricky barrette
*/ */
public class ReportPostingService extends Service { public class ReportPostingService extends Service {
public static final int NOTIFICATION_ID = 1973646478; public static final int NOTIFICATION_ID = 1973646478;
private NotificationManager mNotificationManager; private NotificationManager mNotificationManager;
private static final String TAG = "ReportPostingService"; private static final String TAG = "ReportPostingService";
@@ -50,20 +50,20 @@ public class ReportPostingService extends Service {
*/ */
@SuppressLint("NewApi") @SuppressLint("NewApi")
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void fireNotification(String title, String contentText, String ticker, int icon, Intent intent, boolean isOngoing) { private void fireNotification(final String title, final String contentText, final String ticker, final int icon, final Intent intent, final boolean isOngoing) {
PendingIntent pendingIntent = null; PendingIntent pendingIntent = null;
if(intent != null) if(intent != null)
pendingIntent = PendingIntent.getService(this.getApplicationContext(), 0, intent, 0); pendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent, 0);
/* /*
* Use the appropriate notificafation methods * Use the appropriate notificafation methods
*/ */
if(Integer.valueOf(android.os.Build.VERSION.SDK_INT) > 11){ if(Integer.valueOf(android.os.Build.VERSION.SDK_INT) > 11){
Builder builder = new Notification.Builder(this.getApplicationContext()) final Builder builder = new Notification.Builder(getApplicationContext())
.setContentTitle(title) .setContentTitle(title)
.setContentText(contentText) .setContentText(contentText)
.setTicker(ticker) .setTicker(ticker)
.setSmallIcon(icon) .setSmallIcon(icon)
.setWhen(System.currentTimeMillis()); .setWhen(System.currentTimeMillis());
if(isOngoing) if(isOngoing)
builder.setOngoing(true); builder.setOngoing(true);
else else
@@ -72,22 +72,22 @@ public class ReportPostingService extends Service {
builder.setContentIntent(pendingIntent); builder.setContentIntent(pendingIntent);
mNotificationManager.notify(NOTIFICATION_ID, builder.getNotification()); mNotificationManager.notify(NOTIFICATION_ID, builder.getNotification());
} else { } else {
Notification notification = new Notification(icon, title , System.currentTimeMillis()); final Notification notification = new Notification(icon, title , System.currentTimeMillis());
if(isOngoing) if(isOngoing)
notification.flags |= Notification.FLAG_ONGOING_EVENT; notification.flags |= Notification.FLAG_ONGOING_EVENT;
else else
notification.flags |= Notification.FLAG_AUTO_CANCEL; notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(this.getApplicationContext(), title, contentText, pendingIntent); notification.setLatestEventInfo(getApplicationContext(), title, contentText, pendingIntent);
mNotificationManager.notify(NOTIFICATION_ID, notification); mNotificationManager.notify(NOTIFICATION_ID, notification);
} }
} }
/** /**
* Extracts the report object from the intent * Extracts the report object from the intent
* @param intent * @param intent
* @author ricky barrette * @author ricky barrette
*/ */
private void getReport(Intent intent) { private void getReport(final Intent intent) {
mReport = (Report) intent.getParcelableExtra("report"); mReport = (Report) intent.getParcelableExtra("report");
} }
@@ -96,26 +96,26 @@ public class ReportPostingService extends Service {
* @author ricky barrette * @author ricky barrette
*/ */
private void notifyError() { private void notifyError() {
fireNotification(getString(R.string.reporting_error), fireNotification(getString(R.string.reporting_error),
getString(R.string.reporting_error_msg), getString(R.string.reporting_error_msg),
getString(R.string.reporting_error_msg), getString(R.string.reporting_error_msg),
android.R.drawable.stat_notify_error, android.R.drawable.stat_notify_error,
new Intent(this.getApplicationContext(), ReportPostingService.class).putExtras(mIntent), new Intent(getApplicationContext(), ReportPostingService.class).putExtras(mIntent),
false); false);
} }
/** /**
* notifiys the user that we are sending a report * notifiys the user that we are sending a report
* @author ricky barrette * @author ricky barrette
*/ */
private void notifySending() { private void notifySending() {
fireNotification(getString(R.string.sending), fireNotification(getString(R.string.sending),
getString(R.string.sending_report), getString(R.string.sending_report),
getString(R.string.sending), getString(R.string.sending),
android.R.drawable.stat_sys_upload, android.R.drawable.stat_sys_upload,
null, null,
true); true);
} }
/** /**
@@ -123,11 +123,11 @@ public class ReportPostingService extends Service {
* @see android.app.Service#onBind(android.content.Intent) * @see android.app.Service#onBind(android.content.Intent)
*/ */
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(final Intent intent) {
// Unused // Unused
return null; return null;
} }
/** /**
* Called when the service is being created * Called when the service is being created
* Here we want to display a notifcation, * Here we want to display a notifcation,
@@ -137,9 +137,9 @@ public class ReportPostingService extends Service {
*/ */
@Override @Override
public void onCreate() { public void onCreate() {
Context context = this.getApplicationContext(); final Context context = getApplicationContext();
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notifySending(); notifySending();
super.onCreate(); super.onCreate();
} }
@@ -163,7 +163,7 @@ public class ReportPostingService extends Service {
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public void onStart(Intent intent, int startId) { public void onStart(final Intent intent, final int startId) {
mStartId = startId; mStartId = startId;
getReport(intent); getReport(intent);
postReport(); postReport();
@@ -177,7 +177,7 @@ public class ReportPostingService extends Service {
*/ */
@TargetApi(5) @TargetApi(5)
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(final Intent intent, final int flags, final int startId) {
mStartId = startId; mStartId = startId;
getReport(intent); getReport(intent);
postReport(); postReport();
@@ -197,14 +197,14 @@ public class ReportPostingService extends Service {
public void run(){ public void run(){
try { try {
Log.d(TAG, mReport.file()); Log.d(TAG, mReport.file());
} catch (ClientProtocolException e) { } catch (final ClientProtocolException e) {
e.printStackTrace(); e.printStackTrace();
hasErrored = true; hasErrored = true;
} catch (IOException e) { } catch (final IOException e) {
e.printStackTrace(); e.printStackTrace();
hasErrored = true; hasErrored = true;
} finally { } finally {
ReportPostingService.this.stopSelf(mStartId); ReportPostingService.this.stopSelf(mStartId);
} }
} }
}).start(); }).start();

View File

@@ -15,33 +15,34 @@ import android.util.AttributeSet;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
/** /**
* this class will be a simple preference that contains only a text view that will display the application build information * this class will be a simple preference that contains only a text view that will display the application build information
* @author ricky barrette * @author ricky barrette
*/ */
public class VersionInformationPreference extends Preference { public class VersionInformationPreference extends Preference {
private Context mContext; private final Context mContext;
/** /**
* creates a preference that is nothing but a text view * creates a preference that is nothing but a text view
* @param context * @param context
*/ */
public VersionInformationPreference(Context context) { public VersionInformationPreference(final Context context) {
super(context); super(context);
mContext = context; mContext = context;
} }
/** /**
* creates a preference that is nothing but a text view * creates a preference that is nothing but a text view
* @param context * @param context
* @param attrs * @param attrs
*/ */
public VersionInformationPreference(Context context, AttributeSet attrs) { public VersionInformationPreference(final Context context, final AttributeSet attrs) {
super(context, attrs); super(context, attrs);
mContext = context; mContext = context;
} }
@@ -52,12 +53,12 @@ public class VersionInformationPreference extends Preference {
* @param attrs * @param attrs
* @param defStyle * @param defStyle
*/ */
public VersionInformationPreference(Context context, AttributeSet attrs, int defStyle) { public VersionInformationPreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle); super(context, attrs, defStyle);
mContext = context; mContext = context;
} }
/** /**
* creates a linear layout the contains only a textview. * creates a linear layout the contains only a textview.
* (non-Javadoc) * (non-Javadoc)
@@ -67,38 +68,38 @@ public class VersionInformationPreference extends Preference {
* @author ricky barrette * @author ricky barrette
*/ */
@Override @Override
protected View onCreateView(ViewGroup parent){ protected View onCreateView(final ViewGroup parent){
/* /*
* get the build information, and build the string * get the build information, and build the string
*/ */
PackageManager pm = mContext.getPackageManager(); final PackageManager pm = mContext.getPackageManager();
PackageInfo pi; PackageInfo pi;
try { try {
pi = pm.getPackageInfo(mContext.getPackageName(), 0); pi = pm.getPackageInfo(mContext.getPackageName(), 0);
} catch (NameNotFoundException eNnf) { } catch (final NameNotFoundException eNnf) {
//doubt this will ever run since we want info about our own package //doubt this will ever run since we want info about our own package
pi = new PackageInfo(); pi = new PackageInfo();
pi.versionName = "unknown"; pi.versionName = "unknown";
pi.versionCode = 1; pi.versionCode = 1;
} }
/* /*
* create a vertical linear layout that width and height that wraps content * create a vertical linear layout that width and height that wraps content
*/ */
LinearLayout layout = new LinearLayout(getContext()); final LinearLayout layout = new LinearLayout(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// params.gravity = Gravity.CENTER; // params.gravity = Gravity.CENTER;
layout.setPadding(15, 5, 10, 5); layout.setPadding(15, 5, 10, 5);
layout.setOrientation(LinearLayout.VERTICAL); layout.setOrientation(LinearLayout.VERTICAL);
layout.removeAllViews(); layout.removeAllViews();
/* /*
* create a textview that will be used to display the application's name and build information * create a textview that will be used to display the application's name and build information
* and add it to the layout * and add it to the layout
*/ */
TextView title = new TextView(getContext()); final TextView title = new TextView(getContext());
title.setText(mContext.getString(R.string.version)+" "+pi.versionName+" bulid "+pi.versionCode); title.setText(mContext.getString(R.string.version)+" "+pi.versionName+" bulid "+pi.versionCode);
title.setTextSize(16); title.setTextSize(16);
title.setTypeface(Typeface.SANS_SERIF); title.setTypeface(Typeface.SANS_SERIF);