Stop Location Service - android

whenever I try to stop my location service on android I get a NullPointerException. anyone has some tips on how to do it? I want to implemented on some activities onstop() and ondestroy() methods. Here is my service code:
LocationService.Java
package com.storetab;
public class LocationService extends Service {
static LocationManager locationManager;
static Location lastknown;
final static String MY_ACTION = "MY_ACTION";
static LocationListener ll;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
final Criteria criteria = new Criteria();
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setSpeedRequired(false);
criteria.setCostAllowed(true);
locationManager.getBestProvider(criteria, true);
ll = new MyLocListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, ll);
lastknown = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Log.d("Teste","lastknown");
Intent intent1 = new Intent();
intent.putExtra("location1", lastknown);
intent.setAction(MY_ACTION);
sendBroadcast(intent1);
Log.d("broadcastlast","lastknown");
return START_STICKY;
}
private class MyLocListener implements LocationListener {
public void onLocationChanged(Location location) {
}
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
Log.d("1Provider DIsabled", "Provider Disabled");
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
Log.d("1Provider Enabled", "Provider Enabled");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
Log.d("1Provider Changed", "Service Status Changed");
}
}
#Override public void onDestroy() {
locationManager.removeUpdates(ll);
};
}

In your onStartCommand() you have this code:
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
This creates a local variable called locationManager, which hides the class variable you have declared above that at the top of the class:
static LocationManager locationManager;
The static class variable locationManager never gets set to anything, so it is null in onDestroy().
To fix that, just change it to this in onStartCommand():
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

Related

GPS Service stops after push power button

I'm starting a GPS location service on several devices, the service works correctly in devices with Android Version <= 7 even when the power button is pressed and in the lockscreen status, but I tried in a Nokia 3 with Android 8.0.0 and the service stops after push the power button but it doesn't stop when the device locks by itself after some time. When I push the power button and unlock the device the service starts to send the GPS data again. This is my code:
public class GPS_Service extends Service {
private static final String TAG = GPS_Service.class.getName();
private static final int minTimeSecondsSamplingRate = AppConfig.GPS_MIN_TIME;
private static final int minDistMetersSamplingRate = AppConfig.GPS_MIN_DISTANCE;
private LocationManager locationManager;
private LocationListener locationListener;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#SuppressLint("MissingPermission")
#Override
public void onCreate() {
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Location changed");
Intent intentSendToMainActivity = new Intent(AppConfig.C_STR_INTENT_FILTER_LOCATION_CHANGED);
intentSendToMainActivity.putExtra(AppConfig.C_STR_LATITUDE, location.getLatitude());
intentSendToMainActivity.putExtra(AppConfig.C_STR_LONGITUDE, location.getLongitude());
sendBroadcast(intentSendToMainActivity);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
};
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
if (locationManager != null) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTimeSecondsSamplingRate, minDistMetersSamplingRate, locationListener);
Log.i(TAG, "Starting Location Service");
} else {
Log.e(TAG, "Can't Start Location Service");
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (locationManager != null) {
locationManager.removeUpdates(locationListener);
}
}
}
I've tried dissabling the battery optimization for my application but the problem persists
stop/start location update if no location is received in 2 minutes
also create a service an make it foreground and put location updates methods inside it
all the best

Stop the background service which contains the LocationManager

I am starting my background service from the MainActivity with startService(intent) which sends the location of the user to the server. I want to enable the user to stops this service (also stoping requestLocationUpdates of firing the data from the onLocationChanged method) if he does not wish it by clicking button in the Menu.
I have tried the code in the onOptionsItemSelected method but the service it still works when I click button.
How can I stop this service?
MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.route_available);
Intent i = new Intent(this, TrackingService.class);
startService(i);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.disconnect_id:
System.out.println("test onCreateOptionsMenu was invoked.");
// Stop the service when the Menu button clicks.
Intent i = new Intent(this, TrackingService.class);
stopService(i);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Tracking Service class:
public class TrackingService extends Service {
....
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Toast.makeText(this, "Location Updation has started", Toast.LENGTH_LONG)
.show();
Log.v("X", "Response:in onStartCommand()");
detectLocation();
stopSelf();
return START_STICKY;
}
private void detectLocation() {
// TODO Auto-generated method stub
Toast.makeText(this, "Inside detectlocation()", Toast.LENGTH_SHORT)
.show();
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener ll = new MyLocationListener(this);
// location updates: at least 0 meter and 60 seconds change.
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 0,
ll);
Log.v("X", "Response:After lm1.requestLocationUpdates ");
enableGPS(lm);
}
}
It looks like the way you have it coded now, your Service isn't really doing anything.
Because you have registered your MyLocationListener instance as the LocationListener, stopping the Service doesn't do anything.
Also, since you call stopSelf() in onStartCommand(), you're stopping the Service immediately every time it starts.
I would recommend making the Service the LocationListener, and don't call stopSelf() in onStartCommand()
.
Also, override onDestroy() in the Service, and explicitly call removeUpdates() in order to ensure your app releases it's request to keep the GPS radio active.
Something like this:
public class TrackingService extends Service implements LocationListener{
LocationManager lm; //make instance variable
//....
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Toast.makeText(this, "Location Updation has started", Toast.LENGTH_LONG)
.show();
Log.v("X", "Response:in onStartCommand()");
detectLocation();
//stopSelf(); //don't stop the service here
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
lm.removeUpdates(this);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void detectLocation() {
// TODO Auto-generated method stub
Toast.makeText(this, "Inside detectlocation()", Toast.LENGTH_SHORT)
.show();
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//LocationListener ll = new MyLocationListener(this);
// location updates: at least 0 meter and 60 seconds change.
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 0,
this);
Log.v("X", "Response:After lm1.requestLocationUpdates ");
enableGPS(lm);
}
#Override
public void onLocationChanged(Location location) {
//put your location changed code here
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}

How to track location using GPS continuously using service in background

I am working on an app which will track user location and I have added proximity alert to do some action in that specific location. I practiced this using activity and it works fine, but in background it doesn't work. Here is an example it doesn't work. Kindly tell me a solution if any one has:
public class TrackLoc extends Service implements LocationListener{
LocationManager locationManager;
Location location;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
#Deprecated
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
locationManager=(LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
10000,
0, this);
if (locationManager != null) {
{location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
onLocationChanged(location);
}
}
hope it will helps :
public class TrackLoc extends Service implements LocationListener{
LocationManager locationManager;
Location location;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
locationManager=(LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
10000,
0, this);
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
10000,
0, this);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onLocationChanged(Location location) {
// Do work with new location. Implementation of this method will be covered later.
Log.e("Location updated: ", "Lat: "+location.getLatitude()+" Long: "+location.getLongitude());
}
}
In this i replace request location code from OnStart() to onStartCommand() because of onStartCommand() is calls when another component, such as an activity, requests that the service be started, by calling startService(). Once this method executes, the service is started and can run in the background indefinitely. If you implement this, it is your responsibility to stop the service when its work is done, by calling stopSelf() or stopService().
If you need to track him just for proximity alerts use the Location APIs, in particular the Geofence API.
You can track up to 100 Geofences without burning the device's battery.

Android addProximityAlarm doesn't work

I found hundreds of topics related to the same problem, but I cannot understand where I get wrong! Because I have written the same code basically...
This is a service which controls the position and adds a promityAlert
public class GeoReminderService extends Service implements LocationListener{
private LocationManager locationManager;
private final String proximityIntentAction = "com.example.geo.ProximityIntentReceiver";
private float latitude;
private float longitude;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 400, 10, this);
addProximityAlert(45.477872,9.23457);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onLocationChanged(Location location) {
Log.v("Service","Location changed");
if (location != null) {
Log.v("Location changed : Lat: ", ""+location.getLatitude());
Log.v("Location changed : Lon: ", ""+location.getLongitude());
}
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
private void addProximityAlert(double latitude, double longitude) {
Log.v("Service","proximity alert added" + latitude +" "+ longitude);
Intent intent = new Intent(proximityIntentAction);
PendingIntent proximityIntent = PendingIntent.getBroadcast(getApplicationContext(), -1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
locationManager.addProximityAlert(latitude, longitude, 3000, -1, proximityIntent);
IntentFilter filter = new IntentFilter(proximityIntentAction);
registerReceiver(new ProximityIntentReceiver(), filter);
}
Instead this one is the receiver which should captures the event
public class ProximityIntentReceiver extends BroadcastReceiver {
private static final int NOTIFICATION_ID = 1000;
#Override
public void onReceive(Context context, Intent intent) {
Log.v("proximity receiver", "alert received");
String key = LocationManager.KEY_PROXIMITY_ENTERING;
Boolean entering = intent.getBooleanExtra(key, false);
if (entering) {
Log.v("ProximityIntentReceiver", "entering");
}
else {
Log.v("ProximityIntentReceiver", "exiting");
}
}
Even if I change the position (I am using the Android emulator) the event onReceive doesn't fire. At the same time I am sure that I am changing the position correctly , since the event locationChanged works. Can anyone help me, please?
Have you declared ProximityIntentReceiver in the manifest?
In the same area of the manifest where you declare activites, etc., you'd also declare your BroadcastReceiver.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.geo"
android:versionCode="001"
android:versionName="0.1"
>
<application>
...
<receiver android:name=".ProximityIntentReceiver">
</receiver>
</application>
</manifest>

Toggle Service via ToggleButton for GPS Tracker

i'm currently writing an app that should to the following:
The UI only contains one toggle button. If it is turned on the GPS Position shall be sent to an external server. If it is turned off, nothing shall happen.
If the Button was turned on and the app (activity) is closed the location should still be send until the Button is turned off again.
How can i achieve this ? I read a lot of threads and tutorials and on dev.google.com, but i was not able to find the best solution for my problem.
My current approach:
MainActivity.java
public void onClick(View v) {
if (onOffButton.isChecked()) {
Intent startIntent = new Intent(this, LocationService.class);
startService(startIntent);
} else {
stopService(new Intent(this, LocationService.class));
}
}
LocationService.java
public class LocationService extends Service implements LocationListener {
final public static String START_ACTION = "START_LOCATION";
final public static int NOTE_ID = 1;
private int updateRate;
private LocationManager locationManager;
private NotificationManager notifyManager;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// show popup message
Toast.makeText(this, getText(R.string.start_message), Toast.LENGTH_SHORT).show();
// display icon in status bar
requestLocationUpdates();
}
private void requestLocationUpdates() {
if(locationManager != null)
locationManager.removeUpdates(this);
// get location service
Criteria crit = new Criteria();
crit.setPowerRequirement(Criteria.ACCURACY_FINE);
String bestProvider = getLocationManager().getBestProvider(crit, true);
getLocationManager().requestLocationUpdates(bestProvider, updateRate * 1000,
0 /* minDist */, this);
LocationService.running = true;
}
#Override
public void onDestroy() {
super.onDestroy();
getLocationManager().removeUpdates(this);
notifyManager.cancel(NOTE_ID);
Toast.makeText(this, getText(R.string.stop_message), Toast.LENGTH_SHORT).show();
LocationService.running = false;
}
#Override
public void onLocationChanged(Location location) {
//Send Location to Server
}
#Override
public void onProviderDisabled(String provider) {
// TODO stop service, notify user
}
#Override
public void onProviderEnabled(String provider) {
requestLocationUpdates();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO notify user
}
private LocationManager getLocationManager() {
if (this.locationManager == null)
this.locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return this.locationManager;
}
}
I got this from a very old gps tracker i found on the Internet (i know that onStart() is deprecated and should replaced with onCommandStart()) I just want to know if the general approach is good..
Regards.
The approach looks fine. You just need to implement the call-back methods to report your location.

Categories

Resources