Modified TravelPost.java to extend PreferenceActivity instead of activity, and created the settings.xml to be used for the activity.

incorpatared the exception handler into TravelPost.java

Added android permission READ_LOGS to the manifest for the exception handler

created LocationService.java, and LocationReceiver.java to handle the location services required.

updated version build code to 0.0.0 b 0 as we do not have a working version yet
This commit is contained in:
2011-01-21 18:25:23 +00:00
parent 8cd11db88c
commit 72923068ec
7 changed files with 393 additions and 12 deletions

View File

@@ -1,12 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.TwentyCodes.android.TravelPost"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
package="com.TwentyCodes.android.TravelPost" android:versionCode="0" android:versionName="0.0.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
</application>
<uses-sdk android:minSdkVersion="7" />
<activity android:label="@string/app_name"
android:configChanges="orientation" android:name="TravelPost">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="LocationService" android:enabled="true"
android:process=":locationservice" android:exported="true">
</service>
<receiver android:name="LocationReceiver" android:exported="true"
android:enabled="true" android:process=":locationreceiver">
<intent-filter>
<action android:name="TwentyCodes.TravelPost.intent.action.LocationUpdate" />
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"></uses-permission>
</manifest>

View File

@@ -21,6 +21,7 @@ public final class R {
public static final int hello=0x7f050000;
}
public static final class xml {
public static final int travelpostwidgetinfo=0x7f040000;
public static final int settings=0x7f040000;
public static final int travelpostwidgetinfo=0x7f040001;
}
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="Travel Post">
<PreferenceCategory android:title="Services">
</PreferenceCategory>
<PreferenceCategory android:title="Location Settings">
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -0,0 +1,71 @@
/**
* LocationReceiver.java
* @date Jan 21, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.TravelPost;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
/**
* The broadcast receiver that works with LocationService.java
* @author ricky barrette
*/
public class LocationReceiver extends BroadcastReceiver {
public static final String ACTION_UPDATE = "TwentyCodes.TravelPost.intent.action.LocationUpdate";
public static final String LOCATION_PARCEL = "location_parcel";
private static final String TAG = "LocationReceiver";
private WakeLock mWakeLock;
/**
* acquires a wakelock to prevent the device's cpu from sleeping
* @param context
* @author ricky barrette
*/
private void acquireWakeLock(Context context) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.acquire();
}
/**
* called when this receiver receives a location update
* @param location
* @author ricky barrette
*/
private void onLocationUpdate(Location location) {
//TODO something with the location i.e. report location to social services like twitter, ect...
removeWakeLock();
}
/**
* Called when there is a location update from the location service.
* @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
* @author ricky barrette
*/
@Override
public void onReceive(Context context, Intent intent) {
acquireWakeLock(context);
if(intent.getParcelableExtra(LOCATION_PARCEL) != null){
Location location = intent.getParcelableExtra(LOCATION_PARCEL);
onLocationUpdate(location);
}
}
/**
* removes the wake lock if there is one held
* @author ricky barrette
*/
private void removeWakeLock() {
if(mWakeLock.isHeld())
mWakeLock.release();
}
}

View File

@@ -0,0 +1,227 @@
/**
* LocationService.java
* @date Jan 21, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.TravelPost;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
/**
* A service that will gather the user's location in the background, and report it via Broadcast once the location gathered has reached the
* @author ricky barrette
*/
public class LocationService extends Service implements LocationListener {
/**
* The desired accuracy in meters
*/
private static final float DESIRED_ACCURACY = 6.0f;
/**
* Maximum running time in milliseconds
*/
private final long MAX_RUN_TIME = 180000L;
public static final String TAG = "LocationService";
private LocationManager mLocationManager;
private WakeLock mWakeLock;
private Location mLocation;
private int mStartId;
/**
* this runnable will be qued when the service is created. this will be used as a fail safe
* @author ricky barrette
*/
private Runnable mFailSafe = new Runnable() {
@Override
public void run(){
broadcastLocation();
}
};
/**
* a convince method for starting the service
* @param context
* @return a runnable that will start the service
* @author ricky barrette
*/
public static Runnable startService(final Context context){
return new Runnable(){
@Override
public void run(){
Intent service = new Intent(context, LocationService.class);
context.startService(service);
}
};
}
/**
* a convince method for stopping the service
* @param context
* @return a runnable that will stop the service
* @author ricky barrette
*/
public static Runnable stopService(final Context context){
return new Runnable(){
@Override
public void run(){
context.stopService(new Intent(context, LocationService.class));
}
};
}
/**
* broadcasts location to anything listening for updates,
* since this is the last function of the service, we call finish()u
* @author ricky barrette
*/
private void broadcastLocation() {
if (mLocation != null) {
Intent locationUpdate = new Intent();
locationUpdate.setAction(LocationReceiver.ACTION_UPDATE);
locationUpdate.putExtra(LocationReceiver.LOCATION_PARCEL, mLocation);
sendBroadcast(locationUpdate);
stopSelf(mStartId);
}
}
/**
* (non-Javadoc)
* @see android.app.Service#onBind(android.content.Intent)
* @param arg0
* @return
* @author ricky barrette
*/
@Override
public IBinder onBind(Intent arg0) {
// UNUSED
return null;
}
/**
* called when the service is created. this will initialize the location manager, and acquire a wakelock
* (non-Javadoc)
* @see android.app.Service#onCreate()
* @author ricky barrette
*/
@Override
public void onCreate(){
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.acquire();
/*
* que the fail safe runnable to kill the report location and kill it self after the MAX_RUN_TIME has been meet
*/
new Handler().postDelayed(mFailSafe, MAX_RUN_TIME);
}
/**
* called when the service is destroyed.
* this will remove any wakelock or location service running, and register to be waken back up
* (non-Javadoc)
* @see android.app.Service#onDestroy()
* @author ricky barrette
*/
@Override
public void onDestroy(){
mLocationManager.removeUpdates(this);
if(mWakeLock.isHeld())
mWakeLock.release();
}
/**
* (non-Javadoc)
* @see android.location.LocationListener#onLocationChanged(android.location.Location)
* @param location
* @author ricky barrette
*/
@Override
public void onLocationChanged(Location location) {
// Log.d(TAG, "got location +- "+ location.getAccuracy() +"m");
mLocation = location;
if(location.getAccuracy() <= DESIRED_ACCURACY){
broadcastLocation();
}
}
/**
* (non-Javadoc)
* @see android.location.LocationListener#onProviderDisabled(java.lang.String)
* @param arg0
* @author ricky barrette
*/
@Override
public void onProviderDisabled(String arg0) {
// UNUSED
}
/**
* (non-Javadoc)
* @see android.location.LocationListener#onProviderEnabled(java.lang.String)
* @param arg0
* @author ricky barrette
*/
@Override
public void onProviderEnabled(String arg0) {
// UNUSED
}
/**
* To keep backwards compatibility we override onStart which is the equivalent of onStartCommand in pre android 2.x
* @author ricky barrette
*/
@Override
public void onStart(Intent intent, int startId) {
Log.i(TAG, "onStart.Service started with start id of: " + startId);
mStartId = startId;
startLocationService();
}
/**
* This method is called when startService is called. only used in 2.x android.
* @author ricky barrette
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG , "onStartCommand.Service started with start id of: " + startId);
mStartId = startId;
startLocationService();
return START_STICKY;
}
/**
* (non-Javadoc)
* @see android.location.LocationListener#onStatusChanged(java.lang.String, int, android.os.Bundle)
* @author ricky barrette
*/
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// UNUSED
}
/**
* request periodic location updates from androids location services
* @author ricky barrette
*/
private void startLocationService() {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, this);
}
}

View File

@@ -24,9 +24,13 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
/**
* dont forget the manifest tag
* <uses-permission android:name="android.permission.READ_LOGS" />
* @author ricky
* The Twenty Codes, LLC Exception handler.<br/>
* This exception handler will generate an email with the stacktrace, cause, device & eviroment, and complete logcat <br/> <br/>
* to use create a field variable, and add the following lines to your onCreate()
* <code> mExceptionReport.run();
Thread.setDefaultUncaughtExceptionHandler(mExceptionReport); </code> <br/> <br/>
* Don't forget the manifest tag <code>android.permission.READ_LOGS</code>
* @author ricky barette
*/
public class PostMortemReportExceptionHandler implements UncaughtExceptionHandler, Runnable {
public static final String ExceptionReportFilename = "postmortem.trace";

View File

@@ -1,5 +1,42 @@
/**
* TravelPost.java
* @date Jan 21, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.TravelPost;
public class TravelPost {
import android.os.Bundle;
import android.preference.PreferenceActivity;
}
/**
* Main activity for the Travel Post widget.
* This activity will be used to gather and store the users settings for the widget using shared_prefs
* @author ricky barrette
*/
public class TravelPost extends PreferenceActivity {
private PostMortemReportExceptionHandler mExceptionReport = new PostMortemReportExceptionHandler(this);
private static final String SETTINGS = "settings";
/**
* called when the activity is first created
* (non-Javadoc)
* @see android.preference.PreferenceActivity#onCreate(android.os.Bundle)
* @author ricky barrette
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//start the exception handler
mExceptionReport.run();
Thread.setDefaultUncaughtExceptionHandler(mExceptionReport);
// set shared_prefs name
getPreferenceManager().setSharedPreferencesName(SETTINGS);
// load preferences xml
this.addPreferencesFromResource(R.xml.settings);
}
}