3

I am building an application in which I have to constantly save user's location and then send it to the server. For that, I am using FusedLocationApis in a service. For the first time, I am asking user to turn on locations. It is working perfectly.

Now, what if the user unintentionally turns off the location. How should I inform him? Do developers have to take care of this or they just leave it to the user?

I thought of giving him an android notification for this. For that, I need to constantly check our locations enabled in the service. I have a working code for that (function checkHighAccuracyLocationMode). But where should I do this check (checkHighAccuracyLocationMode) ? Which function is fired up every time in this service? Or If anyhow I can get a function that fires up when the user turned off his locations?

This is my service :

public class locationUpdatesService extends Service implements
    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

private Location mLastLocation;
private Location mCurrentLocation;
private String mLastUpdateTime;
private dataBaseHandler db_helper;

@Override
public int onStartCommand(Intent intent, int flags, int startId){
    initialise();
    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onCreate() {
    super.onCreate();
    db_helper = new dataBaseHandler(getApplicationContext(),dataBaseHandler.DATABASE_NAME,null,1);
}

@Override
public void onDestroy() {
    stopLocationUpdates();
    singletGoogleClientApi.setinstancenull();
    singletLocationRequest.setinstancenull();
    super.onDestroy();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

private void initialise(){
    Log.e("ghgdhu","qaws");
    if (singletGoogleClientApi.getinstance().getGoogleApiCLient() == null) {
        singletGoogleClientApi.getinstance().setmSingletGoogleApiClient(new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build());
        singletGoogleClientApi.getinstance().getGoogleApiCLient().connect();
        createLocationRequest();
    }

    if(!singletGoogleClientApi.getinstance().getGoogleApiCLient().isConnected()){
        singletGoogleClientApi.getinstance().getGoogleApiCLient().connect();
        createLocationRequest();
    }
}

protected void createLocationRequest() {
    if(singletLocationRequest.getinstance().getLocationRequest() == null) {
        singletLocationRequest.getinstance().setSingletLocationRequest(new LocationRequest()
        .setInterval(10000)
        .setFastestInterval(5000).setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY));
    }
}

public static boolean checkHighAccuracyLocationMode(Context context) {
    int locationMode = 0;
    String locationProviders;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
        //Equal or higher than API 19/KitKat
        try {
            locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
            if (locationMode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY){
                return true;
            }
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
    }else{
        //Lower than API 19
        locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

        if (locationProviders.contains(LocationManager.GPS_PROVIDER) && locationProviders.contains(LocationManager.NETWORK_PROVIDER)){
            return true;
        }
    }
    return false;
}


@Override
public void onLocationChanged(Location location) {
    Log.e("qazxsw","inONLocationCHanged");
    mCurrentLocation = location;
    Log.e("loc : ",Double.toString(mCurrentLocation.getLatitude()));
    Toast.makeText(this, "My Location: "+Double.toString(mCurrentLocation.getLatitude())+ " , " + Double.toString(mCurrentLocation.getLongitude()),
            Toast.LENGTH_SHORT).show();
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
    if(!checkHighAccuracyLocationMode(getBaseContext())){
        Log.e("turned OFF","LOCATION");
    }
    else {
        Log.e("ONNNNN","LOCATION");
    }
    db_helper.Insert(mLastUpdateTime,mCurrentLocation.getLatitude(),mCurrentLocation.getLongitude());
}

protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(singletGoogleClientApi.
            getinstance().getGoogleApiCLient(), this);
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    startLocationUpdates();
}

protected void startLocationUpdates() {
    try {
        if(singletLocationRequest.getinstance().getLocationRequest()!=null &&
                singletGoogleClientApi.getinstance().getGoogleApiCLient()!=null){
            Log.e("requesting","yES BRO");
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    singletGoogleClientApi.getinstance().getGoogleApiCLient(), singletLocationRequest.getinstance().getLocationRequest(), this);
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                    singletGoogleClientApi.getinstance().getGoogleApiCLient());
        }
        else {
            initialise();
        }
    }
    catch (SecurityException e) {
        e.getStackTrace();
    }
}

@Override
public void onConnectionSuspended(int i) {
    Log.e("ON CONNECTION SUSPENDED","PETROL");

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    Log.e("COnnection ","DIESEL");

}

}

Abhishek Bhardwaj
  • 1,164
  • 3
  • 14
  • 39
Sanjeev
  • 53
  • 2
  • 5
  • override the method onProviderDisabled . This is where you write your logic for your scenario. Refer to https://developer.android.com/reference/android/location/LocationListener.html for detail. – Jimmy Nov 10 '17 at 06:04
  • Possible duplicate of https://stackoverflow.com/questions/35496339/how-can-i-detect-if-user-disable-gps-android-play-services – Hemant Parmar Nov 10 '17 at 06:04
  • @Jimmy I tried previously to override onProviderEnabled/Disabled methods. But I think with my current implementation I wont be able to do so. – Sanjeev Nov 10 '17 at 08:59
  • @Jimmy I guess I would be able to implement all the methods if I go by LocationManager not through goooglefusedAPIs. What do you think? – Sanjeev Nov 10 '17 at 09:07
  • if you are able to override onLocationChanged ,then you can provide implementation for onProviderDisabled as well. No need to change anything, You already are implementing LocationListener, just override that method and you are set. – Jimmy Nov 10 '17 at 09:16

3 Answers3

9

You can use location state changed receiver to know when user manually turns of location GpsReceiver.java

public class GpsReceiver extends BroadcastReceiver {
    private final LocationCallBack locationCallBack;

    /**
     * initializes receiver with callback
     * @param iLocationCallBack Location callback
     */
    public GpsReceiver(LocationCallBack iLocationCallBack){
            this.locationCallBack = iLocationCallBack;
    }

    /**
     * triggers on receiving external broadcast
     * @param context Context
     * @param intent Intent
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
            locationCallBack.onLocationTriggered();
        }
    }
}

Create an interface to communicate GPS changes to Activity

public interface LocationCallBack {
    /**
     * on Location switch triggered
     */
    void onLocationTriggered();
}

Register receiver in onCreate() of Activity to start listening to GPS state changes

public void onCreate(Bundle savedInstance){
//---
registerReceiver(new GpsReceiver(new LocationCallBack() {
            @Override
            public void onLocationTriggered() {
                //Location state changed
            }
        }), new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
//---
}
Rajan Kali
  • 12,627
  • 3
  • 25
  • 37
  • 3
    This works nicely for me. But make sure you call `unregisterReceiver()` when the activity is killed to prevent a leak – RH201 Nov 08 '18 at 15:20
  • In a foreground service, i want to check if location is "ON" and notify the user when location is turned off. How can i achieve this ?? This foreground service will run even when the app is closed. – K Pradeep Kumar Reddy Apr 21 '20 at 13:11
1

This code worked on Android 9 (Pie) version perfectly

MainActivity

public class MainActivity extends AppCompatActivity {

    private MyLocationReceiver mLocationReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mLocationReceiver = new MyLocationReceiver(this, Snackbar.make(findViewById(android.R.id.content), "Location service is not enabled", Snackbar.LENGTH_INDEFINITE));

    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(mLocationReceiver, new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
    }

    @Override
    protected void onPause() {
        super.onPause();
        try {
            unregisterReceiver(mLocationReceiver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

MyLocationReceiver

public class MyLocationReceiver extends BroadcastReceiver {

    private static final String TAG = "MyLocationReceiver";
    private Context context;
    private Snackbar snackbar;

    public MyLocationReceiver(Context context, Snackbar snackbar){
        this.context = context;
        this.snackbar = snackbar;
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
            boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            boolean networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            if(gpsEnabled && networkEnabled) {
                if (snackbar != null) {
                    snackbar.dismiss();
                }
                Log.d(TAG, "GPS is enabled");
            } else {
                snackbar.show();
                Log.d(TAG, "GPS is disabled");
            }
        }

    }

}
Mustofa Kamal
  • 616
  • 7
  • 13
0

You can use below to check Location availability:

LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }catch (Exception ex){}
    try{
        network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }catch (Exception ex){}
    if(!gps_enabled && !network_enabled){
        AlertDialog.Builder dialog = new AlertDialog.Builder(this);
        dialog.setMessage(getResources().getString(R.string.gps_network_not_enabled));
        dialog.setPositiveButton(getResources().getString(R.string.open_location_settings), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {                 
                Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                Startup.this.startActivity(myIntent);                    
            }
        });
        dialog.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                // TODO Auto-generated method stub

            }
        });
        dialog.show();
    }
halfer
  • 19,824
  • 17
  • 99
  • 186
Niraj Sanghani
  • 1,493
  • 15
  • 23
  • (Aside: we would prefer answers to be written as clearly as possible, observing the rules of English as best you know how, and featuring no "txtspk" whatsoever. Thanks!) – halfer Mar 25 '18 at 15:56