I need a service in my reminder program to check location repeatedly and I'm doing that with this code but I get force close when service started:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
ll = new Mylocationlistener();
checkPermission("android.permission.ACCESS_FINE_LOCATION",1,0);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ll);
return START_STICKY;
}
private class Mylocationlistener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
if (location != null) {
Toast.makeText(getBaseContext(), "Location changed" + location.getLatitude() + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
You have to check if GPS is enabled, every time your Service is triggered. Try this:
In onStartCommand, add a GPS checker:
if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ll);
}
Related
I have implemented a LocationListener to receive regular updates in a service when app is minimized. However this does not work. Updates are only received when the app is visible. Location updates cease when screen is locked or app is minimized.
public class MapService1 extends Service {
private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 0;
private static final long MINIMUM_TIME_BETWEEN_UPDATES = 0;
protected LocationManager locationManager;
Location location;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationListener());
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
#Override
public void onDestroy() {
super.onDestroy();
}
private class MyLocationListener implements LocationListener {
public void onLocationChanged(Location location) {
System.out.println("----------------------NEW ON LOCATION CHANGED (" + location.getLatitude() + "," + location.getLongitude() + ")----------------------");
}
public void onStatusChanged(String s, int i, Bundle b) {
}
public void onProviderDisabled(String s) {
}
public void onProviderEnabled(String s) {
}
}
}
Add this permission to your manifest file
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Your problem is likely that your app only has permission to location while using the app. This will give you the option to accept location permissions all the time.
UPDATED QUESTION - STILL NOT WORKING
I've changed the code.
Now, deactivateAlerts and activateAlerts are in the MainActivity.
Now, inside activateAlerts(), I'm instantiating a GPSListener for the GPS Provider:
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
gpsListener = new GPSListener(getApplicationContext());
} else if
Where the GPSListener is this:
public class GPSListener implements LocationListener {
private Context mCtx;
private Location cLoc;
private LocationManager mLocMan;
public GPSListener (Context ctx){
mCtx = ctx;
mLocMan = (LocationManager) mCtx.getSystemService(Context.LOCATION_SERVICE);
mLocMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
public Location getLocation()
{
cLoc = mLocMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
return cLoc;
}
public void stop()
{
mLocMan.removeUpdates(GPSListener.this);
}
#Override
public void onLocationChanged(Location location) {
Log.i("UPDATING", "updating location");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
With the deactiveAlerts() function, I execute the instruction to remove the GPS updates:
if(gpsListener!=null){
gpsListener.stop();
}
But the GPS is not stopping yet =(
What is the problem now?
ORIGINAL QUESTION
The user can activate or deactivate location updates.
If the location updates are activated, it works ok, but when the location updates are deactivated, the GPS is still waiting for updates (and the icon appears on the action bar).
The code is that:
public class Alerts extends Fragment {
MyLocationListener myLocationListener = null;
...
public void activateAlerts() {
locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
myLocationListener = new MyLocationListener();
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
Utils.MINIMUM_TIME_BETWEEN_UPDATE,
Utils.MINIMUM_DISTANCECHANGE_FOR_UPDATE,
myLocationListener
);
} else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
Utils.MINIMUM_TIME_BETWEEN_UPDATE,
Utils.MINIMUM_DISTANCECHANGE_FOR_UPDATE,
myLocationListener
);
} else {
locationManager.requestLocationUpdates(
LocationManager.PASSIVE_PROVIDER,
Utils.MINIMUM_TIME_BETWEEN_UPDATE,
Utils.MINIMUM_DISTANCECHANGE_FOR_UPDATE,
myLocationListener
);
}
}
});
...
}
public void deactivateAlerts() {
...
locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
if(myLocationListener != null) {
locationManager.removeUpdates(myLocationListener);
myLocationListener = null;
}
...
}
public class MyLocationListener implements android.location.LocationListener {
public void onLocationChanged(Location location) {
Log.i("UPDATING", "updating location");
}
public void onStatusChanged(String s, int i, Bundle b) {
Log.v("LocationListener", "onStatusChanged");
}
public void onProviderDisabled(String s) {
Log.v("LocationListener", "onProviderDisabled");
}
public void onProviderEnabled(String s) {
Log.v("LocationListener", "onProviderEnabled");
}
}
What is the problem?
I've read this posts:
Post1
Post2
Post3
Post4
On this code i want to get the gps location every 3 seconds. but when i run this program on my device it tells me that latitude and longitude are both 0 every time. how should i handle this problem?
and what is the looper task ?? it gives me error when i donot use it
public class LocationService extends Service {
final static String TAG = "MyService";
double latitude ;
double Longitude ;
LocationManager lm;
LocationListener ll;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "onCreate");
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread() {
public void run() {
Looper.prepare();
while(true){
lm = (LocationManager) getSystemService(LOCATION_SERVICE);
ll = new MyLocationListener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0, 0, ll);
//when i log here , it gives me wronganswer
Log.d(TAG,Double.toString(latitude));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
Log.d(TAG, "OnDestroy");
super.onDestroy();
}
class MyLocationListener implements LocationListener{
#Override
public void onLocationChanged(Location location) {
//when i log here , it gives me correct answer
double lat = location.getLatitude();
double lon = location.getLongitude();
latitude = lat;
Longitude = lon;
}
#Override
public void onProviderDisabled(String arg0) {
}
#Override
public void onProviderEnabled(String arg0) {
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
};
}
When you get location from GPS, it can take some time, because GPS module needs to find satellites. So you need to wait couple or few minutes while GPS module find satellites. If WI-FI location provider available you can get location more quick.
Additional info about location providers you can find here: http://developer.android.com/guide/topics/location/strategies.html
Since Android has
GPS_PROVIDER and NETWORK_PROVIDER
you can register to both and start fetch events from onLocationChanged(Location location) from two at the same time. So far so good. Now the question do we need two results or we should take the best. As I know GPS_PROVIDER results have better accuracy than NETWORK_PROVIDER.
for example you have location listener:
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
//here you get locations from both providers
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
YOu need to do something like that:
LocationManager lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,locationListener);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,locationListener);
but before registering you need to check is these providers available on this device, like that:
boolean network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
boolean gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
I have managed to get a fix on an android device's location (both with network provider and gps provider) using:
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
but i would like calculate the phones location at the same moment once using the NETWORK_PROVIDER and then the GPS_PROVIDER so that i can compare each accuracy together.
Does anyone know how to pinpoint the device once with NETWORK_PROVIDER and then with GPS_PROVIDER?
Use 2 Location Listeners
public class MainActivity extends Activity {
private Location networkLocation = null;
private Location gpsLocation = null;
private class NetworkLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
// if you only want one location
// if (networkLocation == null)
networkLocation = location;
if (gpsLocation != null) {
// do something
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
}
private class GpsLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
// if you only want one location
// if (gpsLocation == null)
gpsLocation = location;
if (networkLocation != null) {
// do something
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
}
}
There is the following code for getting current location:
final LocationManager manager=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener listener=new LocationListener() {
#Override
public void onLocationChanged(Location location) {
manager.removeUpdates(this);
Toast.makeText(MainActivity.this, "2", Toast.LENGTH_LONG).show();
if (location!=null) {
doSomeAction();
}
else {
Toast.makeText(MainActivity.this, LOCATION_IS_NULL_MESSAGE, Toast.LENGTH_LONG).show();
}
}
#Override
public void onProviderDisabled(String provider) {
manager.removeUpdates(this);
String newProvider=provider.equals(LocationManager.GPS_PROVIDER) ? LocationManager.NETWORK_PROVIDER : null;
if (newProvider==null) {
Toast.makeText(MainActivity.this, LOCATION_PROVIDERS_ARE_DISABLED_MESSAGE, Toast.LENGTH_LONG).show();
}
else {
manager.requestLocationUpdates(newProvider, 0, 0, this);
}
}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {}
};
String provider=manager.isProviderEnabled(LocationManager.GPS_PROVIDER) ? LocationManager.GPS_PROVIDER :
LocationManager.NETWORK_PROVIDER;
Location location=manager.getLastKnownLocation(provider);
if (location!=null) {
doSomeAction();
}
else {
Toast.makeText(this, "1", Toast.LENGTH_LONG).show();
manager.requestLocationUpdates(provider, 0, 0, listener);
}
I see toast "1" each time, but I've never seen "2" toast, therefore my location isn't be updated. Please, tell me, I need to get my current location - how can I fix my problem? I use network location provider.
Did you actually attach the listener? With out attaching the listener its code is useless, but furthermore afaik: If the LocationManager has no Listener attached it will not update any location.
Try like this :
public class Locato extends Activity implements LocationListener {
LocationManager locman;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.idlayout);
locman = (LocatonManager) getSystemService(Context.LOCATION_SERVICE);
}
public void onStatusChanged(String pr, int s, Bundle a) {}
#Override
public void onProviderDisabled(String provider) {
Log.d("MyApp", "Provider disabled : " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.d("MyApp", "Provider enabled : " + provider);
}
#Override
public void onLocationChanged(Location location) {
// do something
}
You must also add permissions to manifest : access coarse location and access fine location