Eric Kok
12 years ago
29 changed files with 573 additions and 39 deletions
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 3.2 KiB |
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- This layout is a simple wrapper to display dialogs (which might be show full screen, without border) --> |
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:id="@+id/dialogholder" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
tools:context=".DialogHolderActivity" /> |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:orientation="vertical" |
||||
android:layout_margin="@dimen/margin_default" > |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_horizontal" |
||||
android:text="@string/app_name" |
||||
android:textSize="36sp" |
||||
android:textColor="@android:color/white" |
||||
android:fontFamily="sans-serif-condensed" |
||||
android:drawableLeft="@drawable/ic_launcher" |
||||
android:drawablePadding="@dimen/margin_half" |
||||
android:layout_marginTop="@dimen/margin_half" |
||||
android:layout_marginBottom="@dimen/margin_half" /> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_horizontal" |
||||
android:text="@string/system_description" |
||||
android:gravity="center" /> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_horizontal" |
||||
android:layout_marginTop="@dimen/margin_default" |
||||
android:text="@string/app_developer" |
||||
android:textColor="@android:color/white" |
||||
android:textSize="18sp" |
||||
android:fontFamily="sans-serif-condensed" |
||||
android:gravity="center" /> |
||||
|
||||
<TextView |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_horizontal" |
||||
android:layout_marginTop="4dip" |
||||
android:layout_marginBottom="@dimen/margin_default" |
||||
android:text="@string/app_license" |
||||
android:gravity="center" /> |
||||
|
||||
</LinearLayout> |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" > |
||||
|
||||
<item |
||||
android:id="@+id/action_visitwebsite" |
||||
android:icon="@drawable/ic_action_website" |
||||
android:showAsAction="always" |
||||
android:title="@string/action_visitwebsite" /> |
||||
|
||||
</menu> |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<!-- Used to determine if a device is 'small', i.e. a phone; for reference: a Nexus 7's smallest width is 533dip --> |
||||
<bool name="small_screen">false</bool> |
||||
</resources> |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<!-- Used to determine if a device is 'small', i.e. a phone; for reference: a Nexus 7's smallest width is 533dip --> |
||||
<bool name="small_screen">true</bool> |
||||
</resources> |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
package org.transdroid.core.gui; |
||||
|
||||
import org.androidannotations.annotations.AfterViews; |
||||
import org.androidannotations.annotations.EFragment; |
||||
import org.androidannotations.annotations.OptionsItem; |
||||
import org.androidannotations.annotations.OptionsMenu; |
||||
|
||||
import android.app.Dialog; |
||||
import android.content.Intent; |
||||
import android.net.Uri; |
||||
import android.os.Bundle; |
||||
import android.view.Window; |
||||
|
||||
import com.actionbarsherlock.app.SherlockDialogFragment; |
||||
|
||||
/** |
||||
* Fragment that shows info about the application developer and used open source libraries. |
||||
* @author Eric Kok |
||||
*/ |
||||
@EFragment(resName="fragment_about") |
||||
@OptionsMenu(resName="fragment_about") |
||||
public class AboutFragment extends SherlockDialogFragment { |
||||
|
||||
@AfterViews |
||||
protected void init() { |
||||
// TODO: Add list of used open source libraries
|
||||
} |
||||
|
||||
@OptionsItem(resName="action_visitwebsite") |
||||
protected void visitWebsite() { |
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://transdroid.org"))); |
||||
} |
||||
|
||||
@Override |
||||
public Dialog onCreateDialog(Bundle savedInstanceState) { |
||||
// Allow presenting of this fragment as a dialog
|
||||
Dialog dialog = super.onCreateDialog(savedInstanceState); |
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); |
||||
return dialog; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
package org.transdroid.core.gui.log; |
||||
|
||||
import java.sql.SQLException; |
||||
|
||||
import android.content.Context; |
||||
import android.database.sqlite.SQLiteDatabase; |
||||
import android.util.Log; |
||||
|
||||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper; |
||||
import com.j256.ormlite.support.ConnectionSource; |
||||
import com.j256.ormlite.table.TableUtils; |
||||
|
||||
/** |
||||
* Helper to access the database to access persisting objects. |
||||
* @author Eric Kok |
||||
*/ |
||||
public class DatabaseHelper extends OrmLiteSqliteOpenHelper { |
||||
|
||||
private static final String DATABASE_NAME = "transdroid.db"; |
||||
private static final int DATABASE_VERSION = 1; |
||||
|
||||
public DatabaseHelper(Context context) { |
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION); |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) { |
||||
try { |
||||
TableUtils.createTable(connectionSource, ErrorLogEntry.class); |
||||
} catch (SQLException e) { |
||||
Log.e(org.transdroid.core.gui.log.Log.LOG_NAME, "Could not create new table for ErrorLogEntry", e); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int oldVersion, |
||||
int newVersion) { |
||||
try { |
||||
switch (oldVersion) { |
||||
case 1: |
||||
TableUtils.createTable(connectionSource, ErrorLogEntry.class); |
||||
/*case 1: |
||||
etc...*/ |
||||
} |
||||
|
||||
} catch (SQLException e) { |
||||
Log.e(org.transdroid.core.gui.log.Log.LOG_NAME, "Could not upgrade the table for ErrorLogEntry", e); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
package org.transdroid.core.gui.log; |
||||
|
||||
import java.util.Date; |
||||
|
||||
import android.os.Parcel; |
||||
import android.os.Parcelable; |
||||
|
||||
import com.j256.ormlite.field.DatabaseField; |
||||
import com.j256.ormlite.table.DatabaseTable; |
||||
|
||||
/** |
||||
* Represents an error log entry to be registered in the database. |
||||
* @author Eric Kok |
||||
*/ |
||||
@DatabaseTable(tableName = "ErrorLogEntry") |
||||
public class ErrorLogEntry implements Parcelable { |
||||
|
||||
public static final String ID = "logId"; |
||||
public static final String DATEANDTIME = "dateAndTime"; |
||||
|
||||
@DatabaseField(id = true, columnName = ID) |
||||
private Integer logId; |
||||
@DatabaseField(columnName = DATEANDTIME) |
||||
private Date dateAndTime; |
||||
@DatabaseField |
||||
private Integer priority; |
||||
@DatabaseField |
||||
private String tag; |
||||
@DatabaseField |
||||
private String message; |
||||
|
||||
public ErrorLogEntry() { |
||||
} |
||||
|
||||
public ErrorLogEntry(Integer priority, String tag, String message) { |
||||
this.dateAndTime = new Date(); |
||||
this.priority = priority; |
||||
this.tag = tag; |
||||
this.message = message; |
||||
} |
||||
|
||||
public Integer getLogId() { |
||||
return logId; |
||||
} |
||||
|
||||
public Date getDateAndTime() { |
||||
return dateAndTime; |
||||
} |
||||
|
||||
public Integer getPriority() { |
||||
return priority; |
||||
} |
||||
|
||||
public String getTag() { |
||||
return tag; |
||||
} |
||||
|
||||
public String getMessage() { |
||||
return message; |
||||
} |
||||
|
||||
public int describeContents() { |
||||
return 0; |
||||
} |
||||
|
||||
public void writeToParcel(Parcel out, int flags) { |
||||
out.writeInt(logId); |
||||
out.writeLong(dateAndTime.getTime()); |
||||
out.writeInt(priority); |
||||
out.writeString(tag); |
||||
out.writeString(message); |
||||
} |
||||
|
||||
public static final Parcelable.Creator<ErrorLogEntry> CREATOR = new Parcelable.Creator<ErrorLogEntry>() { |
||||
public ErrorLogEntry createFromParcel(Parcel in) { |
||||
return new ErrorLogEntry(in); |
||||
} |
||||
|
||||
public ErrorLogEntry[] newArray(int size) { |
||||
return new ErrorLogEntry[size]; |
||||
} |
||||
}; |
||||
|
||||
private ErrorLogEntry(Parcel in) { |
||||
logId = in.readInt(); |
||||
dateAndTime = new Date(in.readLong()); |
||||
priority = in.readInt(); |
||||
tag = in.readString(); |
||||
message = in.readString(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
package org.transdroid.core.gui.log; |
||||
|
||||
import java.sql.SQLException; |
||||
import java.util.List; |
||||
|
||||
import org.androidannotations.annotations.Bean; |
||||
import org.androidannotations.annotations.EBean; |
||||
import org.androidannotations.annotations.OrmLiteDao; |
||||
import org.transdroid.core.R; |
||||
import org.transdroid.core.app.settings.ServerSetting; |
||||
import org.transdroid.core.gui.navigation.NavigationHelper; |
||||
|
||||
import android.app.Activity; |
||||
import android.content.ActivityNotFoundException; |
||||
import android.content.Intent; |
||||
|
||||
import com.j256.ormlite.dao.Dao; |
||||
|
||||
@EBean |
||||
public class ErrorLogSender { |
||||
|
||||
@Bean |
||||
protected NavigationHelper navigationHelper; |
||||
@OrmLiteDao(helper = DatabaseHelper.class, model = ErrorLogEntry.class) |
||||
protected Dao<ErrorLogEntry, Integer> errorLogDao; |
||||
|
||||
public void collectAndSendLog(final Activity callingActivity, final ServerSetting serverSetting) { |
||||
|
||||
try { |
||||
|
||||
// Prepare an email with error logging information
|
||||
StringBuilder body = new StringBuilder(); |
||||
body.append("Please describe your problem:\n\n\n"); |
||||
body.append("\n"); |
||||
body.append(navigationHelper.getAppNameAndVersion()); |
||||
body.append("\n"); |
||||
body.append(serverSetting.getType().toString()); |
||||
body.append(" settings: "); |
||||
body.append(serverSetting.getHumanReadableIdentifier()); |
||||
body.append("\n\nConnection and error log:"); |
||||
|
||||
// Print the individual error log messages as stored in the database
|
||||
List<ErrorLogEntry> all = errorLogDao.queryBuilder().orderBy(ErrorLogEntry.ID, true).query(); |
||||
for (ErrorLogEntry errorLogEntry : all) { |
||||
body.append("\n"); |
||||
body.append(errorLogEntry.getLogId()); |
||||
body.append(" -- "); |
||||
body.append(errorLogEntry.getDateAndTime()); |
||||
body.append(" -- "); |
||||
body.append(errorLogEntry.getPriority()); |
||||
body.append(" -- "); |
||||
body.append(errorLogEntry.getMessage()); |
||||
} |
||||
|
||||
Intent target = new Intent(Intent.ACTION_SEND); |
||||
target.setType("message/rfc822"); |
||||
target.putExtra(Intent.EXTRA_EMAIL, new String[] { "transdroid.org@gmail.com" }); |
||||
target.putExtra(Intent.EXTRA_SUBJECT, "Transdroid error report"); |
||||
target.putExtra(Intent.EXTRA_TEXT, body.toString()); |
||||
try { |
||||
callingActivity.startActivity(Intent.createChooser(target, |
||||
callingActivity.getString(R.string.pref_sendlog)).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); |
||||
} catch (ActivityNotFoundException e) { |
||||
Log.i(callingActivity, "Tried to send error log, but there is no email app installed."); |
||||
} |
||||
|
||||
} catch (SQLException e) { |
||||
Log.e(callingActivity, "Cannot read the error log to build an error report to send: " + e.toString()); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
package org.transdroid.core.gui.log; |
||||
|
||||
import java.sql.SQLException; |
||||
import java.util.Date; |
||||
|
||||
import org.androidannotations.annotations.EBean; |
||||
import org.androidannotations.annotations.EBean.Scope; |
||||
import org.androidannotations.annotations.OrmLiteDao; |
||||
|
||||
import android.content.Context; |
||||
|
||||
import com.j256.ormlite.dao.Dao; |
||||
import com.j256.ormlite.stmt.DeleteBuilder; |
||||
|
||||
/** |
||||
* Application-wide logging class that registers entries in the database (for a certain time). |
||||
* @author Eric Kok |
||||
*/ |
||||
@EBean(scope = Scope.Singleton) |
||||
public class Log { |
||||
|
||||
public static final String LOG_NAME = "Transdroid"; |
||||
private static final long MAX_LOG_AGE = 15 * 60 * 1000; // 15 minutes
|
||||
|
||||
@OrmLiteDao(helper = DatabaseHelper.class, model = ErrorLogEntry.class) |
||||
Dao<ErrorLogEntry, Integer> errorLogDao; |
||||
|
||||
protected void log(String logName, int priority, String message) { |
||||
android.util.Log.println(priority, LOG_NAME, message); |
||||
try { |
||||
// Store this log message to the database
|
||||
errorLogDao.create(new ErrorLogEntry(priority, logName, message)); |
||||
// Truncate the error log
|
||||
DeleteBuilder<ErrorLogEntry, Integer> db = errorLogDao.deleteBuilder(); |
||||
db.setWhere(db.where().le(ErrorLogEntry.DATEANDTIME, new Date(new Date().getTime() - MAX_LOG_AGE))); |
||||
errorLogDao.delete(db.prepare()); |
||||
} catch (SQLException e) { |
||||
android.util.Log.e(LOG_NAME, "Cannot write log message to database: " + e.toString()); |
||||
} |
||||
} |
||||
|
||||
public static void e(Context caller, String message) { |
||||
Log_.getInstance_(caller).log(caller.getClass().toString(), android.util.Log.ERROR, message); |
||||
} |
||||
|
||||
public static void i(Context caller, String message) { |
||||
Log_.getInstance_(caller).log(caller.getClass().toString(), android.util.Log.INFO, message); |
||||
} |
||||
|
||||
public static void d(Context caller, String message) { |
||||
Log_.getInstance_(caller).log(caller.getClass().toString(), android.util.Log.DEBUG, message); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
package org.transdroid.core.gui.navigation; |
||||
|
||||
import org.androidannotations.annotations.AfterViews; |
||||
import org.androidannotations.annotations.EActivity; |
||||
import org.androidannotations.annotations.Extra; |
||||
import org.transdroid.core.gui.log.Log; |
||||
|
||||
import android.content.Context; |
||||
import android.support.v4.app.DialogFragment; |
||||
import android.support.v4.app.FragmentTransaction; |
||||
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity; |
||||
|
||||
@EActivity(resName = "activity_dialogholder") |
||||
public class DialogHolderActivity extends SherlockFragmentActivity { |
||||
|
||||
@Extra |
||||
protected String dialogType; |
||||
|
||||
/** |
||||
* Use this method to show some dialog; it will show the dialog as full screen fragment on smaller devices. Use the |
||||
* DialogFragment's class here only; a new instance will be created by this holder activity. |
||||
*/ |
||||
public static void showDialog(Context context, Class<? extends DialogFragment> dialogType) { |
||||
DialogHolderActivity_.intent(context).start(); |
||||
} |
||||
|
||||
@AfterViews |
||||
public void init() { |
||||
try { |
||||
// Instantiate an instance of the requested dialog
|
||||
DialogFragment dialog = (DialogFragment) Class.forName(dialogType).newInstance(); |
||||
// Determine if the dialog should be shown as full size screen
|
||||
boolean isSmall = NavigationHelper_.getInstance_(this).isSmallScreen(); |
||||
if (!isSmall) { |
||||
// Show as normal dialog
|
||||
dialog.show(this.getSupportFragmentManager(), "about_dialog"); |
||||
} else { |
||||
// Small device, so show the fragment full screen
|
||||
FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction(); |
||||
// Note: the fragment is not added to the back stack, as this activity already is
|
||||
ft.add(android.R.id.content, dialog).commit(); |
||||
} |
||||
} catch (InstantiationException e) { |
||||
Log.e(this, "Tried to show a dialog of type " + dialogType + ", but that cannot be instantiated."); |
||||
} catch (IllegalAccessException e) { |
||||
Log.e(this, "Tried to show a dialog of type " + dialogType + ", but it is not accessible."); |
||||
} catch (ClassNotFoundException e) { |
||||
Log.e(this, "Tried to show a dialog of type " + dialogType + ", but that class doesn't exist."); |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue