Android GPS as an Activity - android

This is working perfectly for me.
public class GPSActivity extends Activity {
LocationManager locmgr = null;
String android_id;
DbAdapter db;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = new DbAdapter(getBaseContext());
db.open();
android_id = Secure.getString(getBaseContext().getContentResolver(), Secure.ANDROID_ID);
locmgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, this.onLocationChange);
Toast.makeText(getBaseContext(), "Waiting for location..." , Toast.LENGTH_SHORT).show();
}
LocationListener onLocationChange=new LocationListener() {
public void onLocationChanged(Location loc) {
String latlong = "Lat: " + loc.getLatitude() + " Long: " + loc.getLongitude();
Toast.makeText(getBaseContext(), latlong, Toast.LENGTH_SHORT).show();
try{
db.insertGPSCoordinates(android_id, Double.toString(loc.getLatitude()), Double.toString(loc.getLongitude()));
}
catch(Exception e){
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
};
//pauses listener while app is inactive
#Override
public void onPause() {
super.onPause();
locmgr.removeUpdates(onLocationChange);
}
//reactivates listener when app is resumed
#Override
public void onResume() {
super.onResume();
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, onLocationChange);
}
}
How do I use this from Broadcastreceiver ? I want to to start collecting co-ordinates when BOOT_COMPLETE. And keep that running depending on that locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, this.onLocationChange); setting. I am getting confused how to keep that working periodically.

Don't use and activity for this stuff. Use a Service. Here's what you do. Have a broadcast receiver that receives the BOOT_COMPLETE broadcast. When it receives the broadcast have it start up a service. In this service is where you put all your code for recording the locations. The service won't stop until you call stopService on it of for what ever reason you have your service call stopSelf().

Related

Why LocationManager is null after initialization? I'm trying to removeUpdates()

I have a class "OldLocationService" (generally I'm using fused location from GoogleApiClient but I keep that class in case of old Google Play):
public class OldLocationService {
static Location loc;
private static final String TAG = MainActivity.class.getSimpleName();
protected LocationManager service;
private final LocationListener mLocationListener = new LocationListener() {
#Override
public void onLocationChanged(final Location location) {
Log.d(TAG, "New location: " + location.toString());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
public void EnableGPS(String provider, Context ctx) {
service = (LocationManager) ctx.getSystemService(ctx.LOCATION_SERVICE);
boolean enabled = service.isProviderEnabled(provider);
if (enabled) {
service.requestLocationUpdates(provider, 10000, 0, mLocationListener, Looper.getMainLooper());
}
else
{
Log.d(TAG, "GPS is not enabled");
}
}
public void DisableGPS() {
try {
if (!(service==null)) {
service.removeUpdates(mLocationListener);
} else {
Log.d(TAG, "service is null");
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
Somewhere in another class I'm calling:
OldLocationService OLS = new OldLocationService();
OLS.EnableGPS(LocationManager.NETWORK_PROVIDER, mContext);
And I'm getting locations correctly. However, when I'm trying to disable GPS:
OldLocationService ols = new OldLocationService();
ols.DisableGPS();
Then in logcat I get:
service is null
Why I can't remove GPS updates? How to do that?
Sorry for my English errors,
Defozo
First of all don't make 2 instances of your OldLocationService class.. you must remove updates from the same instance from which you started them.. because each instance has its own copy of variables/fields, in your case protected LocationManager service;
OldLocationService ols = new OldLocationService(); // declare it globally
// in middle of some code
OLS.EnableGPS(LocationManager.NETWORK_PROVIDER, mContext);
// more code here
If you're removing Location updates from a Service then you must put the code in it's onDestroy() method from the same instance:
public void onDestroy(){
ols.DisableGPS();
super.onDestroy();
}

Android locationClient returning null, location updates non-responsive

This is my onConnected() method that is being called after I connect the locationClient. This method is called ok, so the GPS is connecting fine. However, getLastLocation() is returning null, which perhaps can be expected due to trying to get a location too soon, and the locationListener method is not being called at all.
It's being run on a Samsung Galaxy S3. When I open the google maps app, it gets a fix on my position instantly, so the GPS must be fine.
#Override
public void onConnected(Bundle arg0)
{
Toast.makeText(context, "GPS connected", Toast.LENGTH_SHORT).show();
connector = new Connector();
connector.execute("clues", null, null);
listener = new LocationListener()
{
#Override
public void onLocationChanged(Location location)
{
Log.d("location", "listener activated");
try
{
coords = locationCoords(location);
if(coords[0] != 0)
{
meMarker = map.addMarker(new MarkerOptions()
.position(new LatLng(coords[0], coords[1]))
.title("Me")
.snippet("Your position")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(coords[0], coords[1]), (float) 19));
}
Toast.makeText(context, coords[0] + ", " + coords[1], Toast.LENGTH_LONG).show();
}
catch(NullPointerException e)
{
Log.d("nulls", "null");
}
}
};
mLocationClient.requestLocationUpdates(mLocationRequest, listener);
try
{
coords = locationCoords(new Location(mLocationClient.getLastLocation()));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(coords[0], coords[1]), (float) 19));
}
catch(NullPointerException e)
{
Toast.makeText(context,"location null", Toast.LENGTH_LONG).show();
}
//Toast.makeText(context, coords[0] + ", " + coords[1], Toast.LENGTH_LONG).show();
Log.d("location", "location updates initiated");
}
Defining request parameters:
public dbConnector(Context con, Activity acti, GoogleMap map)
{
context = con;
activity = acti;
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
setGPSUpdates(10000, 5000);
mLocationRequest.setInterval(updateRate);
mLocationRequest.setFastestInterval(fastestUpdate);
mLocationRequest.setSmallestDisplacement(1);
Log.d("location", "location request constructed");
this.map = map;
}
public void setGPSUpdates(int update, int fastupdate)
{
updateRate = update;
fastestUpdate = fastupdate;
}
The Google Maps app uses both the GPS and network positioning.
Using the GPS, it is normal that the first fix gets some time to arrive. Also, it works well outside, and quite badly inside. (Also, make sure GPS is enabled)
This code works for me:
public class MainActivity extends Activity implements LocationListener {
private LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
// GPS is disabled
}
}
#Override
protected void onStart() {
super.onStart();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
0, this);
}
#Override
protected void onStop() {
locationManager.removeUpdates(this);
super.onStop();
}
#Override
public void onLocationChanged(Location location) {
// do something with the fix
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}

Service with a LocationListener not updated the position. What to do?

A service which starts at boot with a LocationListener then sends the position and device data to a web service. The code works perfectly when not part of a service, the service but passes only a first position and not updated.
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the location provider -> use
// default
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
// Initialize the location fields
if (location != null) {
onLocationChanged(location);
item.LatitudePhone = f_latitude;
item.LongitudePhone = f_longitude;
} else {
item.LatitudePhone = f_latitude;
item.LongitudePhone = f_longitude;
}
item.Active = false;
return item;
}
/* Request updates at startup */
// #Override
protected void onResume() {
// super.onResume();
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
/* Remove the location listener updates when Activity is paused */
// #Override
protected void onPause() {
// super.onPause();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
f_latitude = (float) (location.getLatitude());
f_longitude = (float) (location.getLongitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(this, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
If you are using the same code as it is in the service, then problem can be because you are telling the listener not to update in OnPause() method: locationManager.removeUpdates(this); . So maybe after giving one value it stops updating. Try to remove it, so as to let it update. See what happens. Hope this helps else please comment.

Starting LocationManager as Service Android

What I'm attempting to do is when receiving a c2dm message, start a service that asks for location for 'x' amount of time and then hands that location off to our server. The c2dm message starts the service correctly, and the GPS location turns on, but it never updates. It just sits there for the length of time I specify (currently 12 seconds) in the thread and does nothing. I'm using the exact same code somewhere else in my app (not as a service) and it works perfectly. What am I doing wrong?
This starts the service when receiving a c2dm message.
context.startService(new Intent(context, ServicePingLocation.class));
This is the code for the service itself. All that ever gets called, is "onCreate" and "onStart".
public class ServicePingLocation extends Service implements LocationListener {
private final String DEBUG_TAG = "[GPS Ping]";
private boolean xmlSuccessful = false;
private boolean locationTimeExpired = false;
private LocationManager lm;
private double latitude;
private double longitude;
private double accuracy;
#Override
public void onLocationChanged(Location location) {
Log.d(DEBUG_TAG, "onLocationChanged");
latitude = location.getLatitude();
longitude = location.getLongitude();
accuracy = location.getAccuracy();
}
#Override
public void onProviderDisabled(String provider) {
Log.d(DEBUG_TAG, "onProviderDisabled");
Toast.makeText(
getApplicationContext(),
"Attempted to ping your location, and GPS was disabled.",
Toast.LENGTH_LONG).show();
}
#Override
public void onProviderEnabled(String provider) {
Log.d(DEBUG_TAG, "onProviderEnabled");
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10f, this);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(DEBUG_TAG, "onStatusChanged");
}
#Override
public void onCreate() {
Log.d(DEBUG_TAG, "onCreate");
}
#Override
public void onDestroy() {
Log.d(DEBUG_TAG, "onDestroy");
}
#Override
public IBinder onBind(Intent intent) {
Log.d(DEBUG_TAG, "onBind");
return null;
}
#Override
public void onStart(Intent intent, int startid) {
Log.d(DEBUG_TAG, "onStart");
lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10f, this);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000,
300f, this);
Log.d(DEBUG_TAG, lm.toString());
new SubmitLocationTask(ServicePingLocation.this).execute();
}
private void locationTimer() {
new Handler().postDelayed(new Runnable() {
// #Override
#Override
public void run() {
locationTimeExpired = true;
}
}, 12000);
}
private class SubmitLocationTask extends AsyncTask<String, Void, Boolean> {
/** application context. */
private Context context;
private Service service;
public SubmitLocationTask(Service service) {
this.service = service;
context = service;
}
#Override
protected void onPreExecute() {
locationTimer(); // Start 12 second timer
}
#Override
protected void onPostExecute(final Boolean success) {
if (success && xmlSuccessful) {
lm.removeUpdates(ServicePingLocation.this);
onDestroy();
} else {
if (!GlobalsUtil.DEBUG_ERROR_MSG.equals(""))
Toast.makeText(getBaseContext(),
GlobalsUtil.DEBUG_ERROR_MSG, Toast.LENGTH_SHORT)
.show();
GlobalsUtil.DEBUG_ERROR_MSG = "";
}
}
#Override
protected Boolean doInBackground(final String... args) {
try {
DateFormat df = null;
df = new SimpleDateFormat("M/d/yy h:mm a");
Date todaysDate = new Date();// get current date time with
// Date()
String currentDateTime = df.format(todaysDate);
while ((accuracy > 100f || accuracy == 0.0)
&& !locationTimeExpired) {
// We just want it to sit here and wait.
}
return xmlSuccessful = SendToServerUtil.submitGPSPing(
0, longitude,
latitude, accuracy, currentDateTime);
} catch (Exception e) {
return false;
}
}
}
}
[Edit]
Fixed the issue I was having. Code was actually working. I added the network provider, adjusted the onDestroy() method to stop the service, and tweaked the time used to grab GPS signal.
Thank you for the advice, CommonsWare
Fixed the issue I was having. Code was actually working. I added the network provider, adjusted the onDestroy() method to stop the service, and tweaked the time used to grab GPS signal.
Thank you for the advice, CommonsWare

Android requestLocationUpdates using PendingIntent with BroadcastReceiver

How do I use
requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
PendingIntent intent)
In BroadcastReciver so that I can keep getting GPS coordinates.
Do I have to create a separate class for the LocationListener ?
Goal of my project is when I receive BOOT_COMPLETED to start getting GPS lats and longs periodically.
Code I tried is :
public class MobileViaNetReceiver extends BroadcastReceiver {
LocationManager locmgr = null;
String android_id;
DbAdapter_GPS db;
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
startGPS(context);
} else {
Log.i("MobileViaNetReceiver", "Received unexpected intent "
+ intent.toString());
}
}
public void startGPS(Context context) {
Toast.makeText(context, "Waiting for location...", Toast.LENGTH_SHORT)
.show();
db = new DbAdapter_GPS(context);
db.open();
android_id = Secure.getString(context.getContentResolver(),
Secure.ANDROID_ID);
Log.i("MobileViaNetReceiver", "Android id is _ _ _ _ _ _" + android_id);
locmgr = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5,
onLocationChange);
}
LocationListener onLocationChange = new LocationListener() {
public void onLocationChanged(Location loc) {
// sets and displays the lat/long when a location is provided
Log.i("MobileViaNetReceiver", "In onLocationChanged .....");
String latlong = "Lat: " + loc.getLatitude() + " Long: "
+ loc.getLongitude();
// Toast.makeText(this, latlong, Toast.LENGTH_SHORT).show();
Log.i("MobileViaNetReceiver", latlong);
try {
db.insertGPSCoordinates(android_id,
Double.toString(loc.getLatitude()),
Double.toString(loc.getLongitude()));
} catch (Exception e) {
Log.i("MobileViaNetReceiver",
"db error catch _ _ _ _ " + e.getMessage());
}
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
//pauses listener while app is inactive
/*#Override
public void onPause() {
super.onPause();
locmgr.removeUpdates(onLocationChange);
}
//reactivates listener when app is resumed
#Override
public void onResume() {
super.onResume();
locmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, onLocationChange);
}*/
}
There are two ways of doing this:
Use the method that you are and register a BroadcastReceiver which has an intent filter which matches the Intent that is held within your PendingIntent (2.3+) or, if you are only interested in a single location provider, requestLocationUpdates (String provider, long minTime, float minDistance, PendingIntent intent) (1.5+) instead.
Register a LocaltionListener using the requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener) method of LocationManager.
I think that you are getting a little confused because you can handle the location update using either a BroadcastReceiver or a LocationListener - you don't need both. The method of registering for updates is very similar, but how you receive them is really very different.
A BroadcastReceiver will allow your app / service to be woken even if it is not currently running. Shutting down your service when it is not running will significantly reduce the impact that you have on your users' batteries, and minimise the chance of a Task Killer app from terminating your service.
Whereas a LocationListener will require you to keep your service running otherwise your LocationListener will die when your service shuts down. You risk Task Killer apps killing your service with extreme prejudice if you use this approach.
From your question, I suspect that you need to use the BroadcastReceiver method .
public class MobileViaNetReceiver extends BroadcastReceiver {
private static final String TAG = "MobileViaNetReceiver"; // please
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())){
Log.i(TAG, "Boot : registered for location updates");
LocationManager lm = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
Intent intent = new Intent(context, this.getClass());
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000,5,pi);
} else {
String locationKey = LocationManager.KEY_LOCATION_CHANGED;
if (intent.hasExtra(locationKey)) {
Location loc = (Location) intent.getExtras().get(locationKey);
Log.i(TAG, "Location Received");
try {
DbAdapter_GPS db = new DbAdapter_GPS(context);//what's this
db.open();
String android_id = Secure.getString(
context.getContentResolver(), Secure.ANDROID_ID);
Log.i(TAG, "Android id is :" + android_id);
db.insertGPSCoordinates(android_id,
Double.toString(loc.getLatitude()),
Double.toString(loc.getLongitude()));
} catch (Exception e) { // NEVER catch generic "Exception"
Log.i(TAG, "db error catch :" + e.getMessage());
}
}
}
}
}

Categories

Resources