Android Maps not initializing on 2g or slow internet connections - java

In one of my activity I am showing google map in fragment. It's working fine with 3g or high speed internet connection. But in 2g or very slow internet connection it's hang my mobile, And after some time I get 'not responding' message. Is there any way by which i can handle this situation?
here's the code
#Override
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
InitializeClient();
InitializeDB();
} catch (Exception e) {
e.printStackTrace();
}
mqtt=new MQTT();
try{
if(ip==null){
System.out.println("Mqtt Initialized in Maps Activity");
ip="demo.aiotm.in:1883";
}
//mqtt.setHost("tcp://"+ip);
mqtt.setHost("tcp://10.30.60.242:1883");
connection = mqtt.blockingConnection();
connection.connect();
}catch (Exception e){
e.printStackTrace();
}
}
private void InitializeClient() {
try {
//Initializing googleApiClient
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}catch (Exception e){e.printStackTrace();}
if (this.mMap != null) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}else {System.out.println(":::::::::::::::::::::::::::::::::: Map Not Initialized :::::::::::::::::::::::::::::::::::::::::;");}
mMap.setMyLocationEnabled(true);
}
if (googleApiClient.isConnected()||googleApiClient.isConnecting()){System.out.println("------------------------------------>Api is connecting<-----------------------------------");}
}
the above is my initialization code for maps activity..!!, i hope this much code is enough
NOTE:- It's not a full code. I removed some of code for security reason.

getMapAsync() provides a callback onMapReady where you receive the googleMap.
On slow internet connection maybe it takes time to query the maps, so you can move the googleApiClient initialization in onMapReady callback and also the permission requests.
Your code should look something like this
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
LatLngBounds SINGAPORE = new LatLngBounds(new LatLng(1.2729, 103.6066), new LatLng(1.3553, 104.0323));
mGoogleMap.setLatLngBoundsForCameraTarget(SINGAPORE);
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mGoogleMap.setPadding(0, 0, 16, 500);
//Initialize Google Play Services
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
mGoogleMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
} else {
mGoogleMap.setMyLocationEnabled(true);
}
getGoogleApiClient();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
final PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(#NonNull LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
final LocationSettingsStates state = locationSettingsResult.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
//All location settings are satisfied
displayMarker();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
//Location settings are not satisfied, but could be fixed by showing a dialog
try {
//Show the dialog by calling startResolutionForResult(), and check the result in onActivityResult()
status.startResolutionForResult(getActivity(), FragmentSearchLocation.LOCATION_SETTINGS);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
//Location settings are not satisfied. However, we have no way to fix the settings so we won't show the dialog
break;
}
}
});
}

Related

getLastKnownLocation first time return null issue

I'm developing a simple android location app but I have a little bit trauble.(Also sorry for my bad english.)
I want to get current location with button click, but getLastKnownLocation returns null all of first time.
But also if I first opened google maps and show my current location on map, after that I passed background it then I opened my own app, click the button that works. But I dont want this way, I just want provide location on the my app not with this way.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Object clipboardService = getSystemService(CLIPBOARD_SERVICE);
final ClipboardManager clipboardManager = (ClipboardManager) clipboardService;
tvEnlem = (TextView) findViewById(R.id.textViewEnlem);
tvBoylam = (TextView) findViewById(R.id.textViewBoylam);
retrieveLocationButton = (Button) findViewById(R.id.buttonNeredeyim);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, 101);
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
retrieveLocationButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showCurrentLocation();
}
});
}
protected void showCurrentLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, 101);
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
String message = String.format(
"Current Location \n Longitude: %1$s \n Latitude: %2$s",
location.getLongitude(), location.getLatitude()
);
Toast.makeText(MainActivity.this, message,
Toast.LENGTH_LONG).show();
this.tvBoylam.setText(String.valueOf(location.getLongitude()));
this.tvEnlem.setText(String.valueOf(location.getLatitude()));
}
else{
Toast.makeText(MainActivity.this,"LOKASYON BİLGİLERİ BOŞ",
Toast.LENGTH_SHORT).show();
}
}
private class MyLocationListener implements LocationListener {
public void onLocationChanged(Location location) {
String message = String.format(
"New Location \n Longitude: %1$s \n Latitude: %2$s",
location.getLongitude(), location.getLatitude()
);
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
}
public void onStatusChanged(String s, int i, Bundle b) {
Toast.makeText(MainActivity.this, "Provider status changed",
Toast.LENGTH_LONG).show();
}
public void onProviderDisabled(String s) {
Toast.makeText(MainActivity.this,
"Provider disabled by the user. GPS turned off",
Toast.LENGTH_LONG).show();
}
public void onProviderEnabled(String s) {
Toast.makeText(MainActivity.this,
"Provider enabled by the user. GPS turned on",
Toast.LENGTH_LONG).show();
}
}
}
How can I get location without null values?
this isn't a bug but simply the Google politics.
The getLastKnowLocation() method return the last location that google service has retrieved.
As Google Documentation says:
The location object may be null in the following situations:
Location is turned off in the device settings. The result could be null even if the last location was previously retrieved because
disabling location also clears the cache.
The device never recorded its location, which could be the case of a new device or a device that has been restored to factory
settings.
Google Play services on the device has restarted, and there is no active Fused Location Provider client that has requested
location after the services restarted.
This is why if you switch from Google Maps to your app, you can get last location.
To get actual position without pass from an app to other, you need to implement a new client and request location updates yourself. For more information, see Receiving Location Updates.
I hope I have clarified your every doubt. Otherwise, do not hesitate to write :)

GEOFENCE_NOT_AVAIBLE (code 1000) while trying to set up geofence

The problem occurs on Android older than Oreo and both Oreo and newer.
I can't get geofences working even though following steps are done:
Location services are set to High Accuracy
Wi-Fi and mobile data are enabled
Application is granted location permissions
Google Services are added to the project
Google Services and Play Store are up to date and installed on the device
Disabled battery optimizations (testing purpose)
I've checked with the following code if GPS_PROVIDER and NETWORK_PROVIDER are enabled:
#Override
protected void onResume() {
super.onResume();
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.e("Provider", "Provider is not avaible");
} else if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.v("Provider", "GPS Provider is avaible");
}
if (!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
Log.e("Network Provider", "Provider is not avaible");
} else if (manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
Log.v("Network Provider", "provider is avaible");
}
}
Those both above gave me positive result, so problem can't be here.
Exact error:
E/Geofence: com.google.android.gms.common.api.ApiException: 1000:
I set mGeofencingClient in the begin of onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGeofencingClient = LocationServices.getGeofencingClient(getApplicationContext());
I set geofences with the following code:
mGeofenceList.add(
new Geofence.Builder()
.setRequestId("blablabla")
.setCircularRegion(50.32, 43.23, 232)
.setExpirationDuration(-1L)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
// }
PermissionCheck mPermissionCheck = new PermissionCheck();
if (!mPermissionCheck.isPermissionGranted(getApplicationContext())){
mPermissionCheck.askForPermission(MainActivity.this);
return;
}
setGeofences();
}
private GeofencingRequest getGeofencingRequest(){
if (mGeofenceList.isEmpty()){
return null;}
Log.v("mGeofenceList", mGeofenceList.toString());
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER |
GeofencingRequest.INITIAL_TRIGGER_EXIT);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent(){
if (mGeofencePendingIntent != null){
return mGeofencePendingIntent;
}
Intent intent = new Intent(getApplicationContext(), Geofencing.class);
mGeofencePendingIntent = PendingIntent.getService(getApplication(),
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
#SuppressLint("MissingPermission")
private void setGeofences(){
GeofencingRequest geofencingRequest = getGeofencingRequest();
PendingIntent pi = getGeofencePendingIntent();
mGeofencingClient.addGeofences(geofencingRequest, pi)
.addOnSuccessListener(MainActivity.this, new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("Geofences", "geofencing set up succesfully");
Toast.makeText(MainActivity.this, "Geofences set up", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(MainActivity.this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e("Geofence", e.toString());
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.e("Provider", "Provider is not avaible");
}
if (!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
Log.e("Network Provider", "Provider is not avaible");
}
}
});
}
This code is almost the same as from Google Documentation.
Manifest permission:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-feature android:name="android.hardware.location.network"/>
<uses-feature android:name="android.hardware.location.gps"/>
Gradle:
implementation 'com.google.android.gms:play-services-maps:16.0.0'
implementation 'com.google.android.gms:play-services-location:16.0.0'
Can anyone see the mystake I could have done?
Thanks in advance!
OK this is a minimal working program for geofences based on you OP - just to rule out your code implementation - there's a couple other interfaces implemented for other tests so ignore.
"Working" means it successfuly adds the geofence.:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
private List<Geofence> mGeofenceList = new ArrayList<>();
private GeofencingClient gfc;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
gfc = LocationServices.getGeofencingClient(getApplicationContext());
mGeofenceList.add(new Geofence.Builder().setRequestId("aa").setCircularRegion(50.32, 43.23, 232).setExpirationDuration(-1L).setTransitionTypes(
Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT).build());
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
1);
}
else {
setGeofences();
}
}
private GeofencingRequest getGeofencingRequest(){
if (mGeofenceList.isEmpty()){
return null;}
Log.v("mGeofenceList", mGeofenceList.toString());
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER |
GeofencingRequest.INITIAL_TRIGGER_EXIT);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent mGeofencePendingIntent;
private PendingIntent getGeofencePendingIntent(){
if (mGeofencePendingIntent != null){
return mGeofencePendingIntent;
}
Intent intent = new Intent(getApplicationContext(), Object.class);
mGeofencePendingIntent = PendingIntent.getService(getApplication(),
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
#SuppressLint("MissingPermission")
private void setGeofences(){
GeofencingRequest geofencingRequest = getGeofencingRequest();
PendingIntent pi = getGeofencePendingIntent();
gfc.addGeofences(geofencingRequest, pi)
.addOnSuccessListener(this, new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d("Geofences", "geofencing set up succesfully");
Toast.makeText(MapsActivity.this, "Geofences set up", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(MapsActivity.this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e("Geofence", e.toString());
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.e("Provider", "Provider is not avaible");
}
if (!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
Log.e("Network Provider", "Provider is not avaible");
}
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
setGeofences();
}
}
After some investigation I found I could recreate the 1000 error code with this code sample. It is based on this forum post: https://androidforums.com/threads/error-adding-geofence-on-android-8.1289302/
So to follow those directions (to fix - but I flipped them to recreate and then fix):
Use phone "Settings | Security & location | Location | Mode" - toggle between "High accuracy, Battery saving or Device only" until you get this prompt (the settings path will vary depending on android build):
In this example code - if you respond with "DISAGREE", the example code will generate the 1000 error code; if you repeat and respond with "AGREE" it will be successful in adding the geofence.
for android oreo to android S make sure to access setting high priority because geofence need that or it became error 1000
fun ceksetting(){
val builder = LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest)
val locationRequest = LocationRequest()
locationRequest!!.interval = 50000
locationRequest!!.fastestInterval = 50000
locationRequest!!.smallestDisplacement = 170f // 170 m = 0.1 mile
locationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY //set according to your app function
val client: SettingsClient = LocationServices.getSettingsClient(requireActivity())
val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())
task.addOnSuccessListener { locationSettingsResponse ->
//here call your geofence
}
task.addOnFailureListener { exception ->
if (exception is ResolvableApiException){
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
exception.startResolutionForResult(requireActivity(),
REQUEST_CHECK_SETTINGS)
} catch (sendEx: IntentSender.SendIntentException) {
// Ignore the error.
}
}
}
}

Why my app doesn't show location button when I accept the permission request dialog the second time is runned?

I am programming an Android App in Java. The activity holds a Google map and what I want is to have a button location at the top, like is shown in the picture:
I want that when I click the location to point to my current Location and for that I am using the class FusedLocationProviderClient.
When I run the program everything goes fine until i follow these steps sequencially:
1- Run app first time and I deny permissions
2- Run app second time. It request again permissions so I answer ok, but the button doesn't appear.
3- I close the app, and because I said yes last time, to the location permission, the button is on the map and is working.
Here is my code:
private void checkPermissions(int fineLocationPermission) {
if (fineLocationPermission != PackageManager.PERMISSION_GRANTED) { //If we don't have any permissions yet
// TODO: Consider calling
//We have to request permissions and in case the user refuse the permission we show an explanation of why he needs the permission
//The following method returns true in case the user reject the permission
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_CODE);
} else
mLocationPermissionGranted=true;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//If the user accepts the dialog box then we get the last location and show button
mLocationPermissionGranted=true;
} else {
mLocationPermissionGranted=false;
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
}
}
}
public void onLocationChanged(final Location location) {
String msg = "Updated location: " +
Double.toString(location.getLatitude()) + ", " +
Double.toString(location.getLongitude());
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
final LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
//Show button to locate current position
mMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
#Override
public boolean onMyLocationButtonClick() {
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
CameraUpdateFactory.newLatLngZoom(latLng,12);
//mMap.setMaxZoomPreference(12);
return false;
}
});
// Add a marker our current position
LatLng CurrentPosition = new LatLng(location.getLatitude(), location.getLongitude());
mMap.addMarker(new MarkerOptions().position(CurrentPosition).title("Here you are!"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(CurrentPosition));
}
#Override
public void onMapReady(GoogleMap googleMap) {
//Create the map
mMap = googleMap;
//Set the type of the map: HYBRID, NORMAL, SATELLITE or TERRAIN. In our case TERRAIN type
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
//Set the zoom
mMap.setMaxZoomPreference(12);
//Set the markers
MarkerOptions markerOptions= new MarkerOptions();
//Checking permissions with the permissions we have included in the manifiest
checkPermissions(permissionCheckFineLocation);
if (mLocationPermissionGranted) {
try {
mMap.setMyLocationEnabled(true);
//Last location task
Task<Location> locationResult = mFusedLocationClient.getLastLocation();
locationResult.addOnSuccessListener(this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
//Got last known location. In some rare situations this can be null
if (location != null) {
//Logic to handle location object
onLocationChanged(location);
}
}
});
} catch (SecurityException e) {
Log.e("error", e.getMessage());
}
}
}
I know is a weird question, but I don't know how to express myself.
Any help would be great!
Thank you in advance!
onMapReady isn't called (again) after permission is granted (this happens after onMapReady).
Move the code in onMapReady in the if (mLocationPermissionGranted) clause to a separate method and call it from inside the if as well as from onRequestPermissionsResult if permission was granted.

Google location settings not working as exptected

I am working with the google features to enable and disable location for the user, my main goal is, i enter the camera activity and it asks the user if he clicks cancel it goes back to the previous activity if everything fine it let the user take the photo.
This is my code:
`public class GoogleLocation extends Activity {
private static final int REQUEST_CHECK_SETTINGS = 5 ;
public static void displayLocationSettingsRequest(final Context context) {
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(10000 / 2);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.i("location", "All location settings are satisfied.");
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i("location", "Location settings are not satisfied. Show the user a dialog to upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
Log.d("HELLO2","HELLO2");
status.startResolutionForResult((Activity) context, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
Log.i("location", "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.i("location", "Location settings are inadequate, and cannot be fixed here. Dialog not created.");
break;
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("requestCode",String.valueOf(requestCode));
Log.d("resultCode",String.valueOf(resultCode));
if (requestCode == REQUEST_CHECK_SETTINGS) {
Log.d("ENTERED","ENTERED");
if(resultCode == RESULT_OK){
}
if(resultCode == RESULT_CANCELED){
Log.d("ENTERED","ENTERED");
this.finish();
}
}
}
}
`
i thaught that i can controll the dialog options 'ok' and 'cancel' with the onactivityresult, but as you guys can see inside the onactivity result i have 2 Log.d this just get fired when i pres the 'x' from the camera to close the camera, what is going on? i need to control the dialog but it is not working :/.
Any tip?
Thanks
use this function to enable location in high accuracy
public static void checkLocationSettings(final Activity context){
if(!LocationUtil.isLocationServicesAvailable(context)){
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(10000 / 2);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.e(TAG, "All location settings are satisfied.");
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.e(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the result in onActivityResult().
status.startResolutionForResult(context, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.e(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created.");
break;
}
}
});
}
use this function to check location is enabled with high accuracy
public static boolean isLocationServicesAvailable(Context context) {
int locationMode = 0;
boolean isAvailable = false;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT){
try {
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
isAvailable = (locationMode != Settings.Secure.LOCATION_MODE_OFF && locationMode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
}
return isAvailable;
}
if the user hit ok then the location will enable with high accuracy. else it will stay in the current state. if the location is already enabled and not in high accuracy, then it also the prompt will come to change location mode to high accuracy.

Programmatically Turn On Gps in Android Lollipop [duplicate]

I know that the question about turning on/off GPS programatically on android has been discussed many times, and the answer is always the same:
"You can't for security/privacy reasons, you have to forward to location preferences screen and let the user enable/disable it."
I understand that, however I recently bought Tasker from the market and, among many other things that you can accomplish with it, you can set rules to auto-enable GPS on entering pre-determined applications and disable it on exit (see here for the tutorial on how to do it, and it just works!) and this app can't be signed with the firmware signing key as it works on many android versions and different devices and you don't even need to be rooted.
I would like to do this in my app. Of course, I don't want to blow up the users privacy, so I would first ask the user if he wants to turn it on automatically with the typical "remember my decision" checkbox and if he answers yes, enable it.
Does anybody have any idea or clue on how Tasker achieves this?
the GPS can be toggled by exploiting a bug in the power manager widget. see this xda thread for discussion.
here's some example code i use
private void turnGPSOn(){
String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if(!provider.contains("gps")){ //if gps is disabled
final Intent poke = new Intent();
poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
sendBroadcast(poke);
}
}
private void turnGPSOff(){
String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if(provider.contains("gps")){ //if gps is enabled
final Intent poke = new Intent();
poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
sendBroadcast(poke);
}
}
use the following to test if the existing version of the power control widget is one which will allow you to toggle the gps.
private boolean canToggleGPS() {
PackageManager pacman = getPackageManager();
PackageInfo pacInfo = null;
try {
pacInfo = pacman.getPackageInfo("com.android.settings", PackageManager.GET_RECEIVERS);
} catch (NameNotFoundException e) {
return false; //package not found
}
if(pacInfo != null){
for(ActivityInfo actInfo : pacInfo.receivers){
//test if recevier is exported. if so, we can toggle GPS.
if(actInfo.name.equals("com.android.settings.widget.SettingsAppWidgetProvider") && actInfo.exported){
return true;
}
}
}
return false; //default
}
All these answers are not allowed now. Here is the correct one:
For all those still looking for the Answer:
Here is how OLA Cabs and other such apps are doing it.
Add this in your onCreate
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(Login.this).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
// **************************
builder.setAlwaysShow(true); // this is the key ingredient
// **************************
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi
.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result
.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can
// initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be
// fixed by showing the user
// a dialog.
try {
// Show the dialog by calling
// startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(Login.this, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have
// no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
These are the implmented methods:
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
Here is the Android Documentation for the same.
This is to help other guys if they are still struggling:
Edit: Adding Irfan Raza's comment for more help.
#Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1000) {
if(resultCode == Activity.RESULT_OK){
String result=data.getStringExtra("result");
} if (resultCode == Activity.RESULT_CANCELED) {
//Write your code if there's no result
}
}
}
ENABLE GPS:
Intent intent=new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);
DISABLE GPS:
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);
This code works on ROOTED phones if the app is moved to /system/aps, and they have the following permissions in the manifest:
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
Code
private void turnGpsOn (Context context) {
beforeEnable = Settings.Secure.getString (context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
String newSet = String.format ("%s,%s",
beforeEnable,
LocationManager.GPS_PROVIDER);
try {
Settings.Secure.putString (context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
newSet);
} catch(Exception e) {}
}
private void turnGpsOff (Context context) {
if (null == beforeEnable) {
String str = Settings.Secure.getString (context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if (null == str) {
str = "";
} else {
String[] list = str.split (",");
str = "";
int j = 0;
for (int i = 0; i < list.length; i++) {
if (!list[i].equals (LocationManager.GPS_PROVIDER)) {
if (j > 0) {
str += ",";
}
str += list[i];
j++;
}
}
beforeEnable = str;
}
}
try {
Settings.Secure.putString (context.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
beforeEnable);
} catch(Exception e) {}
}
Instead of using intent Settings.ACTION_LOCATION_SOURCE_SETTINGS you can directly able to show pop up in your app like Google Map & on Gps on click of ok button their is no need to redirect to setting simply you need to use my code as
Note : This line of code automatic open the dialog box if Location is not on. This piece of line is used in Google Map also
public class MainActivity extends AppCompatActivity
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
PendingResult<LocationSettingsResult> result;
final static int REQUEST_LOCATION = 199;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(30 * 1000);
mLocationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
//final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
//...
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
MainActivity.this,
REQUEST_LOCATION);
} catch (SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
//...
break;
}
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
Log.d("onActivityResult()", Integer.toString(resultCode));
//final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode)
{
case REQUEST_LOCATION:
switch (resultCode)
{
case Activity.RESULT_OK:
{
// All required changes were successfully made
Toast.makeText(MainActivity.this, "Location enabled by user!", Toast.LENGTH_LONG).show();
break;
}
case Activity.RESULT_CANCELED:
{
// The user was asked to change settings, but chose not to
Toast.makeText(MainActivity.this, "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
break;
}
default:
{
break;
}
}
break;
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
Note : This line of code automatic open the dialog box if Location is not on. This piece of line is used in Google Map also
Since Android version 4.4, you can't enable/disable gps programatically. If you try the code proposed on this answer, an exception will be fired.
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.location.GPS_ENABLED_CHANGE
Above correct answer is very old it needs something new so Here is answer
As in last update we have androidx support so first include dependency in your app level build.gradle file
implementation 'com.google.android.gms:play-services-location:17.0.0'
then add in your manifest file:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
don't forget to take user consent for these permissions if you are releasing
now here is code just use it
protected void createLocationRequest() {
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
// All location settings are satisfied. The client can initialize
// location requests here.
// ...
Toast.makeText(MainActivity.this, "Gps already open",
Toast.LENGTH_LONG).show();
Log.d("location settings",locationSettingsResponse.toString());
}
});
task.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
if (e instanceof ResolvableApiException) {
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(MainActivity.this,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sendEx) {
// Ignore the error.
}
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==REQUEST_CHECK_SETTINGS){
if(resultCode==RESULT_OK){
Toast.makeText(this, "Gps opened", Toast.LENGTH_SHORT).show();
//if user allows to open gps
Log.d("result ok",data.toString());
}else if(resultCode==RESULT_CANCELED){
Toast.makeText(this, "refused to open gps",
Toast.LENGTH_SHORT).show();
// in case user back press or refuses to open gps
Log.d("result cancelled",data.toString());
}
}
}
if something goes wrong please ping me
Short and easy solution with newest API, from https://developer.android.com/training/location/change-location-settings.html.
You will get nice Google AlertDialog with ok button without any need of going to settings.
Straight to the point. My code in Fragment:
override fun onResume() {
super.onResume()
checkGPSEnabled()
}
private fun checkGPSEnabled() {
val manager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER).not()) {
turnOnGPS()
}
}
private fun turnOnGPS() {
val request = LocationRequest.create().apply {
interval = 2000
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
val builder = LocationSettingsRequest.Builder().addLocationRequest(request)
val client: SettingsClient = LocationServices.getSettingsClient(requireActivity())
val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())
task.addOnFailureListener {
if (it is ResolvableApiException) {
try {
it.startResolutionForResult(requireActivity(), 12345)
} catch (sendEx: IntentSender.SendIntentException) {
}
}
}.addOnSuccessListener {
//here GPS is On
}
}
That's it. Just copy and paste. You will need also:
implementation 'com.google.android.gms:play-services-location:18.0.0' and in Manifest <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
An answer was developed in another question, but it was closed, and I'd like the community to try it out as well.
boolean gpsStatus = locmanager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!gpsStatus) {
Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "network,gps");
}
See this comment
This solution would require the WRITE_SETTINGS and WRITE_SECURE_SETTINGS permissions.
Maybe with reflection tricks around the class android.server.LocationManagerService.
Also, there is a method (since API 8) android.provider.Settings.Secure.setLocationProviderEnabled
This is the best solution provided by Google Developers. Simply call this method in onResume of onCreate after initializing GoogleApiClient.
private void updateMarkers() {
if (mMap == null) {
return;
}
if (mLocationPermissionGranted) {
// Get the businesses and other points of interest located
// nearest to the device's current location.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).build();
mGoogleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(10000);
locationRequest.setFastestInterval(10000 / 2);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest
.Builder()
.addLocationRequest(mLocationRequest);
PendingResult<LocationSettingsResult> resultPendingResult = LocationServices
.SettingsApi
.checkLocationSettings(mGoogleApiClient, builder.build());
resultPendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(#NonNull LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
final LocationSettingsStates locationSettingsStates = locationSettingsResult.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can
// initialize location requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
MainActivity.this,
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way
// to fix the settings so we won't show the dialog.
break;
}
}
});
#SuppressWarnings("MissingPermission")
PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
.getCurrentPlace(mGoogleApiClient, null);
result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
#Override
public void onResult(#NonNull PlaceLikelihoodBuffer likelyPlaces) {
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
// Add a marker for each place near the device's current location, with an
// info window showing place information.
String attributions = (String) placeLikelihood.getPlace().getAttributions();
String snippet = (String) placeLikelihood.getPlace().getAddress();
if (attributions != null) {
snippet = snippet + "\n" + attributions;
}
mMap.addMarker(new MarkerOptions()
.position(placeLikelihood.getPlace().getLatLng())
.title((String) placeLikelihood.getPlace().getName())
.snippet(snippet));
}
// Release the place likelihood buffer.
likelyPlaces.release();
}
});
} else {
mMap.addMarker(new MarkerOptions()
.position(mDefaultLocation)
.title(getString(R.string.default_info_title))
.snippet(getString(R.string.default_info_snippet)));
}
}
Note : This line of code automatic open the dialog box if Location is not on. This piece of line is used in Google Map also
status.startResolutionForResult(
MainActivity.this,
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
This code works on ROOTED phones:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] cmds = {"cd /system/bin" ,"settings put secure location_providers_allowed +gps"};
try {
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd + "\n");
}
os.writeBytes("exit\n");
os.flush();
}
catch (IOException e){
e.printStackTrace();
}
}
}
For turning off GPS you can use this command instead
settings put secure location_providers_allowed -gps
You can also toggle network accuracy using the following commands:
for turning on use:
settings put secure location_providers_allowed +network
and for turning off you can use:
settings put secure location_providers_allowed -network
This one works for me.
It is a simpler solution than Rj0078's answer under this question, but that one is worked as well.
It shows a dialog like this:
(Written in Kotlin)
googleApiClient = GoogleApiClient.Builder(context!!)
.addApi(LocationServices.API).build()
googleApiClient!!.connect()
locationRequest = LocationRequest.create()
locationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationRequest!!.interval = 30 * 1000.toLong()
locationRequest!!.fastestInterval = 5 * 1000.toLong()
val builder = LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest!!)
builder.setAlwaysShow(true)
result =
LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
result!!.setResultCallback { result ->
val status: Status = result.status
when (status.statusCode) {
LocationSettingsStatusCodes.SUCCESS -> {
// Do something
}
LocationSettingsStatusCodes.RESOLUTION_REQUIRED ->
try {
startResolutionForResult(),
status.startResolutionForResult(
activity,
REQUEST_LOCATION
)
} catch (e: SendIntentException) {
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
// Do something
}
}
}
Things have changed since this question was posted, now with new Google Services API, you can prompt users to enable GPS:
https://developers.google.com/places/android-api/current-place
You will need to request ACCESS_FINE_LOCATION permission in your manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Also watch this video:
https://www.youtube.com/watch?v=F0Kh_RnSM0w
This is a more statble code for all Android versions and possibly for new ones
void checkGPS() {
LocationRequest locationRequest = LocationRequest.create();
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
SettingsClient settingsClient = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = settingsClient.checkLocationSettings(builder.build());
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.d("GPS_main", "OnSuccess");
// GPS is ON
}
});
task.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull final Exception e) {
Log.d("GPS_main", "GPS off");
// GPS off
if (e instanceof ResolvableApiException) {
ResolvableApiException resolvable = (ResolvableApiException) e;
try {
resolvable.startResolutionForResult(ActivityMain.this, REQUESTCODE_TURNON_GPS);
} catch (IntentSender.SendIntentException e1) {
e1.printStackTrace();
}
}
}
});
}
And you can handle the GPS state changes here
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == Static_AppVariables.REQUESTCODE_TURNON_GPS) {
switch (resultCode) {
case Activity.RESULT_OK:
// GPS was turned on;
break;
case Activity.RESULT_CANCELED:
// User rejected turning on the GPS
break;
default:
break;
}
}
}
You just need to remove the LocationListener from LocationManager
manager.removeUpdates(listener);
Use This code Simple and Easy to Access:
Permissions:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Follow this Code to access the GPS programmatically:
LocationManager locationManager ;
boolean GpsStatus ;
GPSStatus();
if(GpsStatus == true)
{
textview.setText("Your Location Services Is Enabled");
}else
{textview.setText("Your Location Services Is Disabled");}
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
public void GPSStatus(){
locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
GpsStatus = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}

Categories

Resources