I am working on an app which uses Google Maps and tracks user's location. I want to change the visibility of the "You are here!" marker when the user closes Location Services by hand or services goes to condition of inaccessible. This method can return the information of whether Location Services enabled or not:
private boolean isLocationServicesEnabled() {
LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER) || lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
return true;
}
return false;
}
However, I do not want to detect the status of Location Services for once. Whenever the user opens or closes Location Services, I should detect it and change the visibility of marker. In short, this sloppy pseudocode explains what I want to listen:
while application runs
if location services turn off
change marker visibility to false
else
change marker visibility to true
I did not find a way to achieve this task without android.location.LocationListener, want to achieve it just using Fused Location Provider. Do you have any idea? Here is the core structure I used if you want to see:
http://www.androidhive.info/2015/02/android-location-api-using-google-play-services/
(Check the title of "Complete Code")
Doing this the proper way involves a huge amount of code. You have to make use of the location SettingsApi class.
The main entry point for interacting with the location
settings-enabler APIs.
This API makes it easy for an app to ensure that the device's system
settings are properly configured for the app's location needs.
Fortunately there is a full blown sample provided by Google on github
How about implementing a gps listener?
mLocationManager.addGpsStatusListener(new GpsStatus.Listener(){
#Override
public void onGpsStatusChanged(int event) {
if(event==GpsStatus.GPS_EVENT_STARTED){
Log.d(TAG,"Gps Started");
}else if(event==GpsStatus.GPS_EVENT_STOPPED){
Log.d(TAG,"Gps Stopped");
}
}
});
modify the above code to change visibility of your marker. Hope this works.
Related
Im trying to getLastLocation(), but sometimes it is null. When that happens, I go to google maps just for a second, and return to my app and in 99% that will do. There is also one app that just returns city that you're in and it works even if my app can't getLastLocation(). I've noticed that when I use that other app, or google maps, or weather app, for a short time location icon will appear in status bar, but when I use my app that icon never appears, so I'm guessing that may be the problem?
What I need to do to assure that I get my location to be != null?
One more thing, sometimes I get my location (lat and long), but reverse geocoding goes to catch because List is empty? How to make sure it always is not empty?
The code that I use is just a copy/past from android developers.
If you are using Android Emulator it is expected that the location doesn't get updated unless you open the Maps App.
To ensure you get non-null location you need to request for location updates
You can do something like this
#SuppressLint("MissingPermission")
private fun getLastKnownLocation() {
// get last known location from fusedLocationProviderClient returned as a task
fusedLocationProviderClient.lastLocation
.addOnSuccessListener { lastLoc ->
if (lastLoc != null) {
// initialize lastKnownLocation from fusedLocationProviderClient
lastKnownLocation = lastLoc
} else {
// prompt user to turn on location
showLocationSettingDialog()
// when user turns on location trigger updates to get a location
fusedLocationProviderClient.requestLocationUpdates(
locationRequest, locationCallback, Looper.getMainLooper()
)
}
// in case of error Toast the error in a short Toast message
}
.addOnFailureListener {
Toast.makeText(requireActivity(), "${it.message}", Toast.LENGTH_SHORT).show()
}
}
This is just a stub, you will need to handle permissions, create FusedLocationProviderClient, LocationRequest and LocationCallbackObject.
You may also need to prompt the user to Turn on Location Settings.
Please show us your GeoCoding code to elaborate further.
I'm trying to set some protection against people using mock locations to manipulate my app. I realise that it's impossible to prevent 100%... I'm just trying to do what I can.
The app uses Google location services (part of play services) in its main activity.
The onLocationChanged() method is:
public void onLocationChanged(Location location) {
this.mCurrentLocation = location;
if (Build.VERSION.SDK_INT > 17 && mCurrentLocation.isFromMockProvider()) {
Log.i(TAG, "QQ Location is MOCK");
// TODO: add code to stop app
// otherwise, currently, location will never be updated and app will never start
} else {
Double LAT = mCurrentLocation.getLatitude();
Double LON = mCurrentLocation.getLongitude();
if ((LAT.doubleValue() > 33.309171) || (LAT.doubleValue() < 33.226442) || (LON.doubleValue() < -90.790165) || (LON.doubleValue() > -90.707081)) {
buildAlertMessageOutOfBounds();
} else if (waiting4FirstLocationUpdate) {
Log.i(TAG, "YYY onLocationChanged() determines this is the FIRST update.");
waiting4FirstLocationUpdate = false;
setContentView(R.layout.activity_main);
startDisplayingLists();
}
}
}
The location services work perfectly and all is well with the app in general, but when I run the app in an emulator with Android Studio (Nexus One API 23), and I set the location using extended controls (mock), the app just continues to work as normal, and so it seems that the condition:
if (Build.VERSION.SDK_INT > 17 && mCurrentLocation.isFromMockProvider())
Is returning false.
This doesn't make any sense to me. Does anyone know why this would happen?
Thanks!
The short answer: .isFromMockProvider is unreliable. Some fake locations are not properly detected as such.
I have spent an extensive amount of time researching this and written a detailed blog post about it.
I also spent time to find a solution to reliably suppress mock locations across all recent/relevant Android versions and made a utility class, called the LocationAssistant, that does the job.
In a nutshell (using the aforementioned LocationAssistant):
Set up permissions in your manifest and Google Play Services in your gradle file.
Copy the file LocationAssistant.java to your project.
In the onCreate() method of your Activity, instantiate a LocationAssistant with the desired parameters. For example, to receive high-accuracy location updates roughly every 5 seconds and reject mock locations, call new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, false). The last argument specifies that mock locations shouldn't be allowed.
Start/stop the assistant with your Activity and notify it of permission/location settings changes (see the documentation for details).
Enjoy location updates in onNewLocationAvailable(Location location). If you chose to reject mock locations, the callback is only invoked with non-mock locations.
There are some more methods to implement, but essentially this is it. Obviously, there are some ways to get around mock provider detection with rooted devices, but on stock, non-rooted devices the rejection should work reliably.
I'm trying to register a BroadcastReceiver for get the state changes of Location settings
But I didn't find any documentation for doing it. I only found BroadcastReceiver to check the status of certain search providers (GPS and Network providers); but not for checking if this particular option (Location) is active or not in the system preferences.
Somebody can show me the right direction?
NOTE:
I used Google Play Location Service (com.google.android.gms.location.LocationListener interface).
Well, I found one way to check if the "Location" setting of the action bar is enabled or disabled; but without a BroadcastReceiver (a shame, really)
private static final String TAG = getClass().getName();
/* We define the LocationManager */
LocationManager location_Manager= (LocationManager) getSystemService(LOCATION_SERVICE);
/* If the GPS provider or the network provider are enabled; the Location setting is enabled.*/
if(location_Manager.isProviderEnabled(LocationManager.GPS_PROVIDER) || location_Manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Log.d(TAG, "The Location setting is enabled");
}else{
/* We send the user to the "Location activity" to enable the setting */
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
I really did not need a BroadcastReceiver; since the "arquitecture" that has my app allows me to do without it; but I would have liked to know how to use it.
NOTICE:
If someone finds the way to make it with a BroadcastReceiver I will change my correct answer by her answer.
You can try to use Location Listener.
onProviderDisabled(String provider)
Called when the provider is disabled by the user.
Compare to provider String such as
provider.equalsIgnoreCase(LocationManager.GPS_PROVIDER)
http://developer.android.com/reference/android/location/LocationListener.html
I have created sencha touch application and i want to try get the current location of android device using below code.
Ext.create('Ext.util.Geolocation',
autoUpdate: true,
allowHighAccuracy: true,
listeners: {
locationupdate: function(geo) {
latitude=geo.position.coords.latitude;
longitude=geo.position.coords.longitude;
if(Global.currentUserPositionMarker)
{
latlng1=new google.maps.LatLng(latitude, longitude);
currentPosMarker.setPosition(latlng1);
}
}
}
});
In my device the gps icon will be blinking but Couldn't get the current location of device gps position.
It always get current location from my network provider.
I want frequently update current location from the device gps possition.
Like the google map app for android the gps icon is always stable, i want to like that in my application.
start your Device WI-FI and then try to load your app.
Because It will work for me to get the current location from gps.
I have face the same problem to get the current location from gps.
I am also add question for releated these problem See The Question.
Add Frequency parameter in GeoLocation object.
Ext.create('Ext.util.Geolocation',
autoUpdate: true,
frequency:1000,
allowHighAccuracy: true,
listeners: {
locationupdate: function(geo) {
latitude=geo.position.coords.latitude;
longitude=geo.position.coords.longitude;
if(Global.currentUserPositionMarker)
{
latlng1=new google.maps.LatLng(latitude, longitude);
currentPosMarker.setPosition(latlng1);
}
}
}
});
Frequency value is in milliseconds and it is used to update Geo location by given time.
I want to create an Activity in Android 2.3 when the application starts that checks some needed things by the application, then puts a check sign and then the text of the thing that is checked.
For example:
"GPS Provider enabled" text is shown, if it is enabled, then a check sign appears on its left (if not a stop sign)
Below the first one, "Network Provider enabled" text is shown, if it is enabled, then a check sign appears on its left (if not a stop
sign)
And so on.
I'd like to make it as an animation, if possible. Any ideas?
Thanks in advance!
In your activity's onResume() write this below code to check if GPS/Network Provider enabled of not and depending on that write your other code.
final LocationManager manager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
// available
}
else
{
//not available
}
if (!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
// available
}
else
{
//not available
}
Use ToggelButtons to indicate if they are available or not.