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:
@@ -1,12 +1,36 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.TwentyCodes.android.TravelPost"
|
package="com.TwentyCodes.android.TravelPost" android:versionCode="0" android:versionName="0.0.0">
|
||||||
android:versionCode="1"
|
|
||||||
android:versionName="1.0">
|
|
||||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||||
|
|
||||||
|
<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>
|
</application>
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="7" />
|
<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>
|
</manifest>
|
||||||
@@ -21,6 +21,7 @@ public final class R {
|
|||||||
public static final int hello=0x7f050000;
|
public static final int hello=0x7f050000;
|
||||||
}
|
}
|
||||||
public static final class xml {
|
public static final class xml {
|
||||||
public static final int travelpostwidgetinfo=0x7f040000;
|
public static final int settings=0x7f040000;
|
||||||
|
public static final int travelpostwidgetinfo=0x7f040001;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
TravelPost/res/xml/settings.xml
Normal file
17
TravelPost/res/xml/settings.xml
Normal 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>
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -24,9 +24,13 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dont forget the manifest tag
|
* The Twenty Codes, LLC Exception handler.<br/>
|
||||||
* <uses-permission android:name="android.permission.READ_LOGS" />
|
* This exception handler will generate an email with the stacktrace, cause, device & eviroment, and complete logcat <br/> <br/>
|
||||||
* @author ricky
|
* 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 class PostMortemReportExceptionHandler implements UncaughtExceptionHandler, Runnable {
|
||||||
public static final String ExceptionReportFilename = "postmortem.trace";
|
public static final String ExceptionReportFilename = "postmortem.trace";
|
||||||
|
|||||||
@@ -1,5 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* TravelPost.java
|
||||||
|
* @date Jan 21, 2011
|
||||||
|
* @author ricky barrette
|
||||||
|
* @author Twenty Codes, LLC
|
||||||
|
*/
|
||||||
package com.TwentyCodes.android.TravelPost;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user