I am working on an application and need to integrate GPS location. I want to switch the GPS on programmatically. The condition is: I don\'t want to send the user to the Setting
I've created a library based on Anirudh answer.
Short guide how to use it:
Add it to you build.gradle
file:
compile 'net.alexandroid.utils:gps:1.6'
Implement GpsStatusDetectorCallBack
interface.
Implement interface methods: onGpsSettingStatus
and onGpsAlertCanceledByUser
Create instance variable:
private GpsStatusDetector mGpsStatusDetector;
Instantiate it in onCreate()
:
mGpsStatusDetector = new GpsStatusDetector(this);
In place you need to check the status and show a dialog if need add:
mGpsStatusDetector.checkGpsStatus();
Override onActivityResult and add there:
mGpsStatusDetector.checkOnActivityResult(requestCode, resultCode);
More information about the library: https://github.com/Pulimet/GpsDetector-Library
Example:
public class MainActivity extends AppCompatActivity implements GpsStatusDetector.GpsStatusDetectorCallBack {
private GpsStatusDetector mGpsStatusDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGpsStatusDetector = new GpsStatusDetector(this);
mGpsStatusDetector.checkLocationSettingStatus();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mGpsStatusDetector.checkOnActivityResult(requestCode, resultCode);
}
@Override
public void onGpsSettingStatus(boolean enabled) {
Log.d("TAG", "onGpsSettingStatus: " + enabled);
}
@Override
public void onGpsAlertCanceledByUser() {
Log.d("TAG", "onGpsAlertCanceledByUser");
}
}
Since SettingsApi is deprecated and after checking into the developer site here. I was able to achive the same result as Ola app.
Add the below method in your Activity class
private void switchOnGPS() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(new LocationRequest().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY));
Task<LocationSettingsResponse> task = LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());
task.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
@Override
public void onComplete(@NonNull Task<LocationSettingsResponse> task) {
try {
LocationSettingsResponse response = task.getResult(ApiException.class);
} catch (ApiException e) {
switch (e.getStatusCode())
{
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED :
ResolvableApiException resolvableApiException = (ResolvableApiException) e;
try {
resolvableApiException.startResolutionForResult(MainActivity.this,REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e1) {
e1.printStackTrace();
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
//open setting and switch on GPS manually
break;
}
}
}
});
//Give permission to access GPS
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 11);
}
Call the above method in your Activity's onResume method like below
@Override
protected void onResume() {
super.onResume();
switchOnGPS();
}
Add respective Location permission in Manifest file.
Here is my 100% working code first add this dependencie compile 'com.google.android.gms:play-services:9.2.1'
to your build.gradle(Module: app)
After that create class with name StartLocationAlert.java
and copy this code and paste in this file
import android.app.Activity;
import android.content.IntentSender;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import com.example.googlemappromt.MainActivity;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.vision.barcode.Barcode;
/**
* Created by Anirudh on 20/07/16.
*/
public class StartLocationAlert implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
Activity context;
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
GoogleApiClient googleApiClient;
public StartLocationAlert(Activity context) {
this.context = context;
googleApiClient = getInstance();
if(googleApiClient != null){
//googleApiClient.connect();
settingsrequest();
googleApiClient.connect();
}
}
public GoogleApiClient getInstance(){
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(context).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
return mGoogleApiClient;
}
public void settingsrequest()
{
Log.e("settingsrequest","Comes");
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.
// Log.e("Application","Button Clicked");
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
// Log.e("Application","Button Clicked1");
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(context, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
Log.e("Applicationsett",e.toString());
}
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.
//Log.e("Application","Button Clicked2");
Toast.makeText(context, "Location is Enabled", Toast.LENGTH_SHORT).show();
break;
}
}
});
}
@Override
public void onConnected(@Nullable Bundle bundle) {
/* MainActivity mm = new MainActivity();
mm.requestLocationUpdates();*/
Toast.makeText(context , "Connected", Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
}
Usage of this above class is show below
@Override
protected void onResume() {
super.onResume();
Activity mContext = MainActivity.this //change this your activity name
StartLocationAlert startLocationAlert = new StartLocationAlert(mContext);
requestLocationUpdates();
}
And don't forget to add below permissions in AndroidManifest.xml
file or else this might not work properly
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Hope this might help you..
Ola Cabs is using the newly released Settings API to achieve this functionality. As per the new API the user is not required to navigate to the settings page to enable location services giving a seamless integration for the same. Please read below for more details:
https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi
Check the code below. Firstly, it will check if location is enabled or not and will prompt user to enable the location.
private GoogleApiClient googleApiClient;
final static int REQUEST_LOCATION = 199;
// check whether gps is enabled
public boolean noLocation() {
final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
// buildAlertMessageNoGps();
enableLoc();
return true;
}
return false;
}
private void enableLoc() {
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Timber.v("Location error " + connectionResult.getErrorCode());
}
}).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);
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.RESOLUTION_REQUIRED:
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
(Activity) context, REQUEST_LOCATION);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
}
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_LOCATION:
switch (resultCode) {
case Activity.RESULT_CANCELED: {
// The user was asked to change settings, but chose not to
finish();
break;
}
default: {
break;
}
}
break;
}
}
}
Here I have user this code
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);
}
}
Permissions in your manifest file:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>