init commit
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* ExceptionHandler.java
|
||||
* @date Feb 12, 2011
|
||||
* @author ricky barrette
|
||||
* @author Twenty Codes, LLC
|
||||
*/
|
||||
package com.TwentyCodes.android.exception;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.AssetManager;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* This is Twenty Codes, LLC Exception Handler of Awesomeness!
|
||||
* This class will be used to generate reports that will be emailed to us via the users email client after the users approval
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class ExceptionHandler implements UncaughtExceptionHandler, Runnable {
|
||||
|
||||
private static final String MSG_SUBJECT_TAG = "Exception Report";
|
||||
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).";
|
||||
protected static final int SIMPLE_NOTFICATION_ID = 45684645;
|
||||
private Thread.UncaughtExceptionHandler mDefaultUEH;
|
||||
private Activity mApp= null;
|
||||
private Service mService = null;
|
||||
private BroadcastReceiver mBroadcastReceiver = null;
|
||||
private Context mContext;
|
||||
private Report mReport;
|
||||
private static final String TAG = "ExceptionHandler";
|
||||
private String mURL = null;
|
||||
private String mEmail;
|
||||
|
||||
/**
|
||||
* Creates a new ExceptionHandler
|
||||
* @param app
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public ExceptionHandler(Activity app) {
|
||||
this.mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
|
||||
this.mApp = app;
|
||||
this.mContext = app;
|
||||
parseProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ExceptionHandler
|
||||
* @param broadcastReceiver
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public ExceptionHandler(BroadcastReceiver broadcastReceiver, Context context){
|
||||
this.mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
|
||||
this.mBroadcastReceiver = broadcastReceiver;
|
||||
this.mContext = context;
|
||||
parseProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ExceptionHandler
|
||||
* @param service
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public ExceptionHandler(Service service){
|
||||
this.mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
|
||||
this.mService = service;
|
||||
this.mContext = service;
|
||||
parseProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an email from the report
|
||||
* @author ricky barrette
|
||||
*/
|
||||
private void displayEmailNotification(){
|
||||
Log.i(TAG, "displayEmailNotification");
|
||||
|
||||
CharSequence title = null;
|
||||
if(mApp != null)
|
||||
title = mApp.getTitle();
|
||||
|
||||
if(mService != null)
|
||||
title = mService.getClass().getName();
|
||||
|
||||
if(mBroadcastReceiver != null)
|
||||
title = mBroadcastReceiver.getClass().getName();
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
String theSubject = title + " " + MSG_SUBJECT_TAG;
|
||||
String theBody = "\n\n"+MSG_BODY+this.mReport.toString();
|
||||
intent.putExtra(Intent.EXTRA_EMAIL,new String[] {this.mEmail});
|
||||
intent.putExtra(Intent.EXTRA_TEXT, theBody);
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, theSubject);
|
||||
intent.setType("message/rfc822");
|
||||
|
||||
displayNotification(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* displays an notification in the status bar, letting the user know that there was an issue
|
||||
* @param generatedReportIntent
|
||||
*/
|
||||
private void displayNotification(Intent generatedReportIntent) {
|
||||
Log.i(TAG, "displayNotification");
|
||||
Context context = mContext.getApplicationContext();
|
||||
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());
|
||||
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.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||
notificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
* parses in the exception handler options from the client application's assets folder. /assets/exceptionhandler.properties
|
||||
* @author ricky barrette
|
||||
*/
|
||||
private void parseProperties() {
|
||||
Resources resources = this.mContext.getResources();
|
||||
AssetManager assetManager = resources.getAssets();
|
||||
// Read from the /assets directory
|
||||
try {
|
||||
InputStream inputStream = assetManager.open("exceptionhandler.properties");
|
||||
Properties properties = new Properties();
|
||||
properties.load(inputStream);
|
||||
this.mURL = properties.getProperty("server") + properties.getProperty("file");
|
||||
this.mEmail = properties.getProperty("email");
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to open exceptionhandler.properties");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if(this.mEmail == null)
|
||||
displayNotification(new Intent(this.mContext, ExceptionReportActivity.class).putExtra("report", this.mReport));
|
||||
else
|
||||
displayEmailNotification();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when there is an uncaught exception.
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Thread.UncaughtExceptionHandler#uncaughtException(java.lang.Thread, java.lang.Throwable)
|
||||
* @author ricky barrette
|
||||
*/
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
Log.d(TAG, "uncaughtException()");
|
||||
|
||||
Log.d(TAG,"mURL = "+ this.mURL);
|
||||
Log.d(TAG,"mEmail = "+ this.mEmail);
|
||||
|
||||
Date theDate = new Date();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss_zzz");
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
|
||||
//app environment;
|
||||
PackageInfo pi;
|
||||
try {
|
||||
pi = pm.getPackageInfo(mContext.getPackageName(), 0);
|
||||
} catch (NameNotFoundException eNnf) {
|
||||
//doubt this will ever run since we want info about our own package
|
||||
pi = new PackageInfo();
|
||||
pi.versionName = "unknown";
|
||||
pi.versionCode = 69;
|
||||
}
|
||||
|
||||
StringBuffer report = new StringBuffer();
|
||||
for (StackTraceElement item : e.getStackTrace())
|
||||
report.append("at "+item.toString() + "\n");
|
||||
|
||||
StringBuffer causereport = new StringBuffer();
|
||||
Throwable cause = e.getCause();
|
||||
if (cause != null) {
|
||||
causereport.append(cause.toString() + "\n \n");
|
||||
for (StackTraceElement item : cause.getStackTrace())
|
||||
causereport.append("at "+item.toString() + "\n");
|
||||
}
|
||||
|
||||
//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, mContext.getPackageName());
|
||||
|
||||
//try to send file contents via email (need to do so via the UI thread)
|
||||
if(this.mApp != null){
|
||||
this.mApp.runOnUiThread(this);
|
||||
}
|
||||
|
||||
|
||||
if(this.mService != null){
|
||||
if(this.mEmail == null)
|
||||
displayNotification(new Intent(this.mContext, ExceptionReportActivity.class).putExtra("report", this.mReport));
|
||||
else
|
||||
displayEmailNotification();
|
||||
}
|
||||
|
||||
if(this.mBroadcastReceiver != null){
|
||||
if(this.mEmail == null)
|
||||
displayNotification(new Intent(this.mContext, ExceptionReportActivity.class).putExtra("report", this.mReport));
|
||||
else
|
||||
displayEmailNotification();
|
||||
}
|
||||
|
||||
//do not forget to pass this exception through up the chain
|
||||
mDefaultUEH.uncaughtException(t,e);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* ExceptionActivity.java
|
||||
* @date May 31, 2011
|
||||
* @author Twenty Codes, LLC
|
||||
* @author ricky barrette
|
||||
*/
|
||||
package com.TwentyCodes.android.exception;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
|
||||
/**
|
||||
* This activity will be used to present the user with the exception report, and allows them to send it, or not
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class ExceptionReportActivity extends Activity implements OnClickListener {
|
||||
|
||||
private static final String TAG = "ExceptionActivity";
|
||||
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)
|
||||
* @see android.view.View.OnClickListener#onClick(android.view.View)
|
||||
* @author ricky barrette
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
EditText description = (EditText) findViewById(R.id.description);
|
||||
this.mReport.setDescription(description.getText().toString());
|
||||
v.setEnabled(false);
|
||||
final ProgressDialog progress = ProgressDialog.show(this, "", getString(R.string.sending), true, true);
|
||||
new Thread( new Runnable(){
|
||||
@Override
|
||||
public void run(){
|
||||
Looper.prepare();
|
||||
try {
|
||||
Log.d(TAG, ExceptionReportActivity.this.mReport.file());
|
||||
} catch (ClientProtocolException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
progress.dismiss();
|
||||
ExceptionReportActivity.this.finish();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* Report.java
|
||||
* @date May 29, 2011
|
||||
* @author Twenty Codes, LLC
|
||||
* @author ricky barrette
|
||||
*/
|
||||
package com.TwentyCodes.android.exception;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* This class will be used to generate a report, and insert it into our exception report database
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class Report implements Parcelable{
|
||||
|
||||
private String mUrl;
|
||||
private ArrayList<ReportItem> mReport;
|
||||
|
||||
public static final Parcelable.Creator<Report> CREATOR = new Parcelable.Creator<Report>() {
|
||||
public Report createFromParcel(Parcel in) {
|
||||
return new Report(in);
|
||||
}
|
||||
|
||||
public Report[] newArray(int size) {
|
||||
return new Report[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new Report
|
||||
* @param in
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public Report(Parcel in){
|
||||
this.mUrl = in.readString();
|
||||
this.mReport = new ArrayList<ReportItem>();
|
||||
in.readTypedList(this.mReport, ReportItem.CREATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Report
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public Report(String mysqlUrl) {
|
||||
this.mUrl = mysqlUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Files the report with the remote database
|
||||
* @author ricky barrette
|
||||
* @throws IOException
|
||||
* @throws ClientProtocolException
|
||||
* @return String result
|
||||
*/
|
||||
public String file() throws ClientProtocolException, IOException{
|
||||
HttpClient httpclient = new DefaultHttpClient();
|
||||
HttpPost httppost = new HttpPost(mUrl);
|
||||
httppost.setEntity(new UrlEncodedFormEntity(getNameValuePairs()));
|
||||
|
||||
//return the results
|
||||
HttpResponse response = httpclient.execute(httppost);
|
||||
HttpEntity entity = response.getEntity();
|
||||
InputStream is = entity.getContent();
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(reader.readLine() + "\n");
|
||||
String line="0";
|
||||
while ((line = reader.readLine()) != null)
|
||||
sb.append(line + "\n");
|
||||
is.close();
|
||||
reader.close();
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a report to be displayed form a downloaded JSON object
|
||||
* @param report
|
||||
* @return
|
||||
* @author ricky barrette
|
||||
* @throws JSONException
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Report generateReport(JSONObject report) throws JSONException{
|
||||
this.mReport = new ArrayList<ReportItem>();
|
||||
Iterator iter = report.keys();
|
||||
while(iter.hasNext()){
|
||||
String key = (String)iter.next();
|
||||
this.mReport.add(new ReportItem(key , report.getString(key)));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a report to be sent.
|
||||
* @param msg
|
||||
* @param stackTrace
|
||||
* @param cause
|
||||
* @param device
|
||||
* @param appVersion
|
||||
* @param app
|
||||
* @return this
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public Report generateReport(String msg, String stackTrace, String cause, String date, String device, String appVersion, String app){
|
||||
this.mReport = new ArrayList<ReportItem>();
|
||||
this.mReport.add(new ReportItem("app",app));
|
||||
this.mReport.add(new ReportItem("version",appVersion));
|
||||
this.mReport.add(new ReportItem("date",date));
|
||||
this.mReport.add(new ReportItem("msg",msg));
|
||||
this.mReport.add(new ReportItem("stackTrace",stackTrace));
|
||||
this.mReport.add(new ReportItem("cause",cause));
|
||||
this.mReport.add(new ReportItem("device",device));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the name value pairs from the report bundle
|
||||
* @return
|
||||
* @author ricky barrette
|
||||
*/
|
||||
private ArrayList<NameValuePair> getNameValuePairs() {
|
||||
ArrayList<NameValuePair> list = new ArrayList<NameValuePair>();
|
||||
for(ReportItem entry : this.mReport)
|
||||
list.add(new BasicNameValuePair(entry.getKey(), (String) entry.getValue()));
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the generated exception report
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public ArrayList<NameValuePair> getReport(){
|
||||
return getNameValuePairs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the optional users description of what happened
|
||||
* @param string
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public Report setDescription(String description) {
|
||||
this.mReport.add(new ReportItem("description", description));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a human readable string of this report
|
||||
* @author ricky barrette
|
||||
*/
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder s = new StringBuilder();
|
||||
for(ReportItem item : this.mReport){
|
||||
s.append("\n\n-----"+ item.getKey()+"-----");
|
||||
s.append("\n"+item.getValue());
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(this.mUrl);
|
||||
out.writeTypedList(this.mReport);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* ReportAdapter.java
|
||||
* @date May 31, 2011
|
||||
* @author Twenty Codes, LLC
|
||||
* @author ricky barrette
|
||||
*/
|
||||
package com.TwentyCodes.android.exception;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.http.NameValuePair;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
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
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class ReportAdapter extends BaseAdapter {
|
||||
|
||||
private ArrayList<NameValuePair> mReport;
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
/**
|
||||
* Creates a new ReportAdapter
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public ReportAdapter(Context context, ArrayList<NameValuePair> report) {
|
||||
super();
|
||||
// Cache the LayoutInflate to avoid asking for a new one each time.
|
||||
this.mInflater = LayoutInflater.from(context);
|
||||
this.mReport = report;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
* @see android.widget.Adapter#getCount()
|
||||
* @author ricky barrette
|
||||
*/
|
||||
@Override
|
||||
public int getCount() {
|
||||
return this.mReport.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
* @see android.widget.Adapter#getItem(int)
|
||||
* @author ricky barrette
|
||||
*/
|
||||
@Override
|
||||
public NameValuePair getItem(int index) {
|
||||
return this.mReport.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
* @see android.widget.Adapter#getItemId(int)
|
||||
* @author ricky barrette
|
||||
*/
|
||||
@Override
|
||||
public long getItemId(int index) {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public View getView(final int position, View convertView, 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
|
||||
// to reinflate it. We only inflate a new View when the convertView supplied
|
||||
// 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
|
||||
// we want to bind data to.
|
||||
holder = new ViewHolder();
|
||||
holder.title = (TextView) convertView.findViewById(R.id.exception_title);
|
||||
holder.body = (TextView) convertView.findViewById(R.id.exception_text);
|
||||
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* ReportItem.java
|
||||
* @date July 13, 2010
|
||||
* @author Twenty Codes, LLC
|
||||
* @author ricky barrette
|
||||
*/
|
||||
package com.TwentyCodes.android.exception;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* This class will represent an individual report item. The ReportItems will be used in an array list that will be passed via intent.
|
||||
* This will allow for our report items to stay in the proper order.
|
||||
* @author ricky
|
||||
*/
|
||||
public class ReportItem implements Parcelable {
|
||||
|
||||
public static final Parcelable.Creator<ReportItem> CREATOR = new Parcelable.Creator<ReportItem>() {
|
||||
public ReportItem createFromParcel(Parcel in) {
|
||||
return new ReportItem(in);
|
||||
}
|
||||
|
||||
public ReportItem[] newArray(int size) {
|
||||
return new ReportItem[size];
|
||||
}
|
||||
};
|
||||
|
||||
private String mKey;
|
||||
private 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
|
||||
* @param in
|
||||
*/
|
||||
public ReportItem(Parcel in){
|
||||
this.mKey = in.readString();
|
||||
this.mValue = in.readString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
// TODO Auto-generated method stub
|
||||
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
|
||||
*/
|
||||
public String getKey() {
|
||||
return this.mKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value
|
||||
*/
|
||||
public String getValue() {
|
||||
return this.mValue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @author Twenty Codes
|
||||
* @author ricky barrette
|
||||
* @date June 29, 2011
|
||||
*/
|
||||
package com.TwentyCodes.android.exception;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.graphics.Typeface;
|
||||
import android.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* this class will be a simple preference that contains only a text view that will display the application build information
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class VersionInformationPreference extends Preference {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
|
||||
/**
|
||||
* creates a preference that is nothing but a text view
|
||||
* @param context
|
||||
*/
|
||||
public VersionInformationPreference(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a preference that is nothing but a text view
|
||||
* @param context
|
||||
* @param attrs
|
||||
*/
|
||||
public VersionInformationPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a preference that is nothing but a text view
|
||||
* @param context
|
||||
* @param attrs
|
||||
* @param defStyle
|
||||
*/
|
||||
public VersionInformationPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* creates a linear layout the contains only a textview.
|
||||
* (non-Javadoc)
|
||||
* @see android.preference.Preference#onCreateView(android.view.ViewGroup)
|
||||
* @param parent
|
||||
* @return
|
||||
* @author ricky barrette
|
||||
*/
|
||||
@Override
|
||||
protected View onCreateView(ViewGroup parent){
|
||||
|
||||
/*
|
||||
* get the build information, and build the string
|
||||
*/
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
PackageInfo pi;
|
||||
try {
|
||||
pi = pm.getPackageInfo(mContext.getPackageName(), 0);
|
||||
} catch (NameNotFoundException eNnf) {
|
||||
//doubt this will ever run since we want info about our own package
|
||||
pi = new PackageInfo();
|
||||
pi.versionName = "unknown";
|
||||
pi.versionCode = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* create a vertical linear layout that width and height that wraps content
|
||||
*/
|
||||
LinearLayout layout = new LinearLayout(getContext());
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
// params.gravity = Gravity.CENTER;
|
||||
layout.setPadding(15, 5, 10, 5);
|
||||
layout.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
layout.removeAllViews();
|
||||
|
||||
/*
|
||||
* create a textview that will be used to display the application's name and build information
|
||||
* and add it to the layout
|
||||
*/
|
||||
TextView title = new TextView(getContext());
|
||||
title.setText(mContext.getString(R.string.version)+" "+pi.versionName+" bulid "+pi.versionCode);
|
||||
title.setTextSize(16);
|
||||
title.setTypeface(Typeface.SANS_SERIF);
|
||||
title.setGravity(Gravity.LEFT);
|
||||
title.setLayoutParams(params);
|
||||
|
||||
/*
|
||||
* add the title views to the layout
|
||||
*/
|
||||
layout.addView(title);
|
||||
layout.setId(android.R.id.widget_frame);
|
||||
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user