I have created an app that displays the user location on google maps using LocationListener and GPS. I'm trying to turn GPS off when the user navigates away from the app, but everything I try doesn't work, I can still see the GPS icon active at the top of the screen. At present I have:
#Override
protected void onPause() {
super.onPause();
// Turning off
locationManager.removeUpdates(locationListener);
locationManager = null;
}
help please :(
Try Your test over Device. If using device uninstall your application and restart your device and install again.
make sure the listener you are removing is the same for which you requested updates.
it should work then.
Sorted it!
It turned out the problem was in my onResume with these two lines:
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
I never bothered looking at them because I didn't expect the onResume state to be affecting the onPause.
Thanks for your help Javanator.
Hope this helps someone else :)
Related
I'm currently developing an app that requires the Android's location service to always be active.
Right now I'm able to detect if the user activates or deactivates the location service when he resumes the app (in the onResume() event ).
The problem is that, if the user deactivates the location service throught the quick settings menu, I am not able to detect the event.
How can I know when the user activates / deactivates the device's location through the quick settings?
Thank you.
My code:
...
BroadcastReceiver mGpsSwitchStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() != null && intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
// Make an action or refresh an already managed state.
Log.d("vtApp", "CHANGED");
}
}
};
currentActivity.registerReceiver(mGpsSwitchStateReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
References I followed:
How to trigger broadcast receiver when gps is turn on/off?
Android Quick Settings notifications?
Changing Location Settings
I had the same problem.
this worked for me
intentFilter.addAction(android.location.LocationManager.PROVIDERS_CHANGED_ACTION);
not to confuse it with
Intent.ACTION_PROVIDER_CHANGED
For easier access here is my GitHub Link
https://github.com/PoetryHorizon/eloteroMan2
For some reason The GPS tracking works fine, my VendorActivity works fine, but I cannot access my Main Activity. It simply just closes the app if I try to access my MainActivity.
On line 82 in my MainActivity I originally wanted to have it so if the user allows GPS tracking it will return to the MainActivity Screen, but when I set it to be MainActivity.class it does nothing. So I set it to be VendorActivity.class and it sends the user to the VendorActivity just fine. But when I hit back in the app to go to the main screen it just closes the app.
I've spent 2 days trying to figure this out and I can't pin point where the fix is.
If anyone has any free time and is willing to help a new Android App Developer, it will be greatly appreciated.
This is just a fun side project I am working on before my class begins. I have never worked with GPS location before.
According to the manifest file your project is set up such that MainActivity is your launch activity. That is where you start! But you are also removing any pathway back by calling finish() in two locations.
The easy fix is just to change this code:
if (checkAndRequestPermissions()){
finish();
return;
}
to just this single line of code:
checkAndRequestPermissions();
And also to remove finish() in the onRequestPermissionsResult() method where you switch to the VendorActivity. Change:
Intent i = new Intent(MainActivity.this, VendorActivity.class);
startActivity(i);
finish();
should simply be:
Intent i = new Intent(MainActivity.this, VendorActivity.class);
startActivity(i);
Explaination:
In your MainActivity in the onCreate() method you are checking if the user has granted location permission using the method checkAndRequestPermissions() if it returns true you simple exit you programm--lights out!
if (checkAndRequestPermissions()){ //if this is true .. user has already granted permission then you kill the app! why?
finish();
return;
}
The method checkAndRequestPermissions() returns true if the user has already granted permission.
private boolean checkAndRequestPermissions() {
int permissionLocation = ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listPermissionsNeeded = new ArrayList<>();
if (permissionLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true; //Returns true if permission has already been granted!!
}
If the user has not granted permission then you request it. Thus onRequestPermissionsResult() is triggered with the results of the request. If the user grants permission you go to VendorActivity, however, at the same time call finish() which, simply put, removes MainActivity from the Activity stack. In this case, you are showing the VendorActivity, but tapping the back button will kill the app, because you have already removed MainActivity from the stack.
If the user refuses to give you permission you simply ash them again to grant permission or you call finish() to kill the app
It looks like you are calling finish() in your MainActivity. This will cause the MainActivity to be closed. If you take out the call to finish(), MainActivity will be kept in the stack and when you press back, you will go back to MainActivity.
I have read a few questions and answers related to this , but none has solved my problem. Please suggest me what should i do. I am using this fused location api in my android background service. And i have provided all the nougat/marshmellow checks also. But i get result location only once or first time, after that , the onLocation result is not called, is it so that only when i change my location it will be called ? please help
heres my simple onCreate of service:
#Override
public void onCreate() {
super.onCreate();
fusedLocationProviderClient= LocationServices.getFusedLocationProviderClient(this);
locationRequest=new LocationRequest();
locationRequest.setInterval(4000);
locationRequest.setFastestInterval(4000);
locationCallback=new LocationCallback(){
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
Log.i("serviceTag","onLocationResult called");
}
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
fusedLocationProviderClient.requestLocationUpdates(locationRequest,locationCallback, Looper.myLooper());
}
}
FusedLocationProviderClient provides location updates only in foregrounded state either when an Activity (any not necessarily the one requesting or using location updates) is resumed or when a foreground service associated with location foregroundServiceType is started.
From Android 10, framework developers most likely choose to sub categorize foreground services by a type to ensure not all apps with generic foreground services like media apps gets free access to locations when backgrounded. Given that, it is trivial for application developers to just add this “location” type in manifest for unrelated foreground service to work around the limitation.
https://medium.com/#debuggingisfun/android-foregroundservicetype-8857a36f36b9
If I set any ACCURACY to criteria, it takes long time to LocationManager to start updating location:
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
provider = locationManager.getBestProvider(criteria, true);
locationManager.requestLocationUpdates(provider, 0, 0, this);
If I remove ACCURACY flag, it starts immediately but sometimes not accurate.
How can I make it start updating immediately and with good accuracy?
Unfortunately, no way.
If you use ACCURACY_FINE, you will use GPS only, but GPS have "cold start" effect. It means that if you device not used GPS long time, it needs a lot of time for connecting with satellites and download almanac and ephemeris. You can't change this behavior.
If you don't use ACCURACY_FINE, you will use both GPS and network (mobile, wi-fi) signals. So you will receive quick first position from network, because they don't have "cold start" effect, but accuracy of this method is low. When your GPS module will ready, you will start receive updates from it too.
If you care only about accuracy and not things like bearing or altitude I suggest switching to the new fused provider in the LocationClient API from Google.
It is very quick to get the first fix, more accurate than network based and doesn't depend on GPS.
It requires a bit more setup then the built-in LocationManager, so you may read this training article: http://developer.android.com/training/location/receive-location-updates.html
I suspect that at least with ACCURACY_FINE, it's waiting to get an initial GPS fix. You may find that if you've already got GPS turned on for another reason (e.g. if you're in the middle of navigation) that it starts reporting immediately.
It can take a while to get a GPS fix - I think it's just a natural part of how GPS works.
LocationManager is buggy on many phones, since it depends heavily on the customized android open source code for specific hardware. Samsung phones are very buggy when it comes to LocationManager.
You should not use requestLocationUpdates, instead use getLastKnownLocation with a small hack. Just before the getLastKnownLocation call put the following hack and you should be able to use a AlarmManager to get regular updates.
HomeScreen.getLocationManager().requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
#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(final Location location) {
}
});
LocationClient is the other alternative to LocationManager. It is more accurate, uses a hello a lot less battery.
I am making simple application which based on phone's location. I am using this code for GPS location. In the main() function I am requesting the GPS location and then I am working with it. (I am calculating the sunrise and sunset)
I can get the location, but when I start the application I get the LastKnown location. So, if I want real "new one" location I must wait for GPS lock on and then restart the application.
So, my question is: How can I get a "fresh" location?
Ok. I have an idea.
Can I call MainActivity refresh from another class?
in GPS class I have this
private final Context mContext;
#Override
public void onLocationChanged(Location location) {
startActivity(new Intent(mContext, MainActivity.class));
}
But this doesn't work. Can anyone help?
Here is the overview of location services in Android. Here is the LocationManager class at the heart of location services in Android.
Here is an Android developer tutorial on "Location Strategies". Here is another tutorial that might be usable.
Also, you cannot just ask Android for your current position, since GPS may take quite some time to get a fix. Instead, you need to request location updates and use the first update you get, or similar patterns.