0

I want to check if the GPS is on if it is should show the current location. If not it should ask to turn it on. If user click cancel or dont turn the coordinates will be set as basic. Unfortunetly allways choose the basic. Even if the GPS is of (i dont get the message to turn on GPS)

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;


    locationManagerr = (LocationManager) getSystemService(LOCATION_SERVICE);
    currentLocation=new Location("location");

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,
                            Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.INTERNET}
                    , 10);
        }
    }else
        getLocation();
    log.i(TAG,"latitude  "+currentLocation.getLatitude());
    }

    private Location getLocation(){

                locationListener= new LocationListener() {
                    @Override
                    public void onLocationChanged(Location location) {
                        currentLocation=location;
                    }

                    @Override
                    public void onStatusChanged(String provider, int status, Bundle extras) {
                    }
                    @Override
                    public void onProviderEnabled(String provider) {
                    }

                    @Override
                    public void onProviderDisabled(String provider) {
                        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(LocationFinder.this);
                        alertDialogBuilder.setMessage("GPS is off. Want to turn on GPS?")
                                .setCancelable(false)
                                .setPositiveButton("Turn On",
                                        new DialogInterface.OnClickListener() {
                                            public void onClick(DialogInterface dialog, int id) {
                                                Intent callGPSSettingIntent = new Intent(
                                                        android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                                startActivity(callGPSSettingIntent);
                                            }
                                        });
                        alertDialogBuilder.setNegativeButton("Cancel",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                       currentLocation=setStartCoordinate();
                                        dialog.cancel();
                                    }
                                });
                        AlertDialog alert = alertDialogBuilder.create();
                        alert.show();
                    }
                };
       return currentLocation;
        }
    private Location setStartCoordinate(){
        Location primaryLocalization= new Location("Basic");
        primaryLocalization.setLongitude(0);
        primaryLocalization.setLatitude(0);
        return primaryLocalization;
    }

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode){
        case 10:
            try{
                getLocation();
                log.i(TAG,"latitude  "+currentLocation.getLatitude());
            }
            catch (SecurityException ex){log.i(TAG,"security error");}
            break;
        default:
            break;
    }
}
Expiredmind
  • 788
  • 1
  • 8
  • 29
  • try like this.. **if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){ //Do what you need if enabled... }else{ //Do what you need if not enabled... }** and refer here http://stackoverflow.com/questions/843675/how-do-i-find-out-if-the-gps-of-an-android-device-is-enabled – brahmy adigopula Sep 14 '16 at 13:08

3 Answers3

2

This requires a lot of case handling and I am providing a complete implementation of the all the features you requested with brief explanations below.

1. Provide location permission in the manifest

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

2. Add location dependency in app's build.gradle

compile 'com.google.android.gms:play-services-location:9.2.1'

3. extend BroadcastReceiver and create GPSStatusReceiver

public class GPSStatusReceiver extends BroadcastReceiver {

    private GpsStatusChangeListener mCallback;
    private Context mContext;

    public GPSStatusReceiver(Context context, GpsStatusChangeListener callback) {
        mCallback = callback;
        mContext = context;

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.location.PROVIDERS_CHANGED");
        intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
        context.registerReceiver(this, intentFilter);
    }

    public void unRegisterReceiver(){
        Log.d("ali", "unRegisterReceiver");
        mContext.unregisterReceiver(this);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
            Log.d("ali", "in PROVIDERS_CHANGED");
            mCallback.onGpsStatusChange();
        }
    }

    public interface GpsStatusChangeListener{
        void onGpsStatusChange();
    }
}

4. Create a class GPSLocation

public class GPSLocation implements
        ConnectionCallbacks,
        OnConnectionFailedListener,
        LocationListener,
        GPSStatusReceiver.GpsStatusChangeListener {

    public static final int REQUEST_CHECK_SETTINGS = 100;
    public static final int LOCATION_PERMISSION_REQUEST_CODE = 200;

    private static final int PERMISSION_GRANTED = 0;
    private static final int PERMISSION_DENIED = 1;
    private static final int PERMISSION_BLOCKED = 2;

    private GoogleApiClient mGoogleApiClient;
    private Location mCurrentLocation;
    private LocationCallback mCallback;
    private Activity mActivity;
    private Context mContext;
    private LocationRequest mLocationRequest;
    private GPSStatusReceiver mGPSStatusReceiver;

    private long intervalMillis = 10000;
    private long fastestIntervalMillis = 5000;
    private int accuracy = LocationRequest.PRIORITY_HIGH_ACCURACY;

    private boolean isInitialized = false;
    private boolean isLocationEnabled = false;
    private boolean isPermissionLocked = false;

    public GPSLocation(Activity activity, LocationCallback callback) {
        mActivity = activity;
        mContext = activity.getApplicationContext();
        mCallback = callback;
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(mContext)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
        createLocationRequest();
        mGPSStatusReceiver = new GPSStatusReceiver(mContext, this);
    }


    public void init(){
        isInitialized = true;
        if(mGoogleApiClient != null) {
            if (mGoogleApiClient.isConnected()) {
                requestPermission();
            } else {
                connect();
            }
        }
    }


    public void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(intervalMillis);
        mLocationRequest.setFastestInterval(fastestIntervalMillis);
        mLocationRequest.setPriority(accuracy);
    }


    public LocationRequest getLocationRequest() {
        return mLocationRequest;
    }


    public void connect(){
        if(mGoogleApiClient != null && isInitialized) {
            mGoogleApiClient.connect();
        }
    }


    public void disconnect(){
        if(mGoogleApiClient != null && isInitialized) {
            mGoogleApiClient.disconnect();
        }
    }


    private void getLastKnownLocation(){
        if(!mGoogleApiClient.isConnected()){
            Log.d("ali", "getLastKnownLocation restart ");
            mGoogleApiClient.connect();
        }
        else {
            if (checkLocationPermission(mContext) && isLocationEnabled) {
                Log.d("ali", "getLastKnownLocation read ");
                if(mCurrentLocation == null) {
                    mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                    mCallback.onLastKnowLocationFetch(mCurrentLocation);
                }
                startLocationUpdates();
            }else{
                Log.d("ali", "getLastKnownLocation get permission ");
                requestPermission();
            }
        }
        Log.d("ali", "mCurrentLocation " + mCurrentLocation);
    }


    public void startLocationUpdates() {
        if(checkLocationPermission(mContext)
                && mGoogleApiClient != null
                && mGoogleApiClient.isConnected()
                && isLocationEnabled) {
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
        }
    }


    public void stopLocationUpdates() {
        if(mGoogleApiClient != null
                && mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(
                    mGoogleApiClient, this);
        }
    }


    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.d("ali", "onConnected");
        requestPermission();
    }


    @Override
    public void onConnectionSuspended(int i) {
        Log.d("ali", "onConnectionSuspended");
    }


    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.d("ali", "onConnectionFailed");
    }


    @Override
    public void onLocationChanged(Location location) {
        Log.d("ali", "onLocationChanged : " + location);
        mCallback.onLocationUpdate(location);
    }


    @Override
    public void onGpsStatusChange() {
        Log.d("ali", "onGpsStatusChange");
        if(isInitialized && !isPermissionLocked) {
            if (!isLocationEnabled(mContext)) {
                isLocationEnabled = false;
                isPermissionLocked = true;
                stopLocationUpdates();
                requestPermission();
            }
        }
    }


    private void requestPermission(){
        if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED){
            String[] appPerm = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
            ActivityCompat.requestPermissions(mActivity, appPerm, LOCATION_PERMISSION_REQUEST_CODE);
        }else{
            getLocationSetting();
        }
    }


    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == GPSLocation.REQUEST_CHECK_SETTINGS) {
            if (resultCode == Activity.RESULT_OK) {
                getLastKnownLocation();
            }else{
                Toast.makeText(mContext, "Permission Denied", Toast.LENGTH_SHORT).show();
                mCallback.onLocationSettingsError();
            }
        }
    }


    private void getLocationSetting(){
        LocationSettingsRequest.Builder builder =
                new LocationSettingsRequest
                        .Builder()
                        .addLocationRequest(mLocationRequest);

        PendingResult<LocationSettingsResult> 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 locationSettingsStates = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        Log.d("ali", "SUCCESS");
                        isLocationEnabled = true;
                        isPermissionLocked = false;
                        getLastKnownLocation();
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        Log.d("ali", "RESOLUTION_REQUIRED");
                        try {
                            status.startResolutionForResult(
                                    mActivity,
                                    REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            e.printStackTrace();
                            mCallback.onLocationSettingsError();
                        }finally {
                            isPermissionLocked = false;
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        Log.d("ali", "SETTINGS_CHANGE_UNAVAILABLE");
                        Toast.makeText(mContext, "Location Unavailable", Toast.LENGTH_SHORT).show();
                        mCallback.onLocationSettingsError();
                        isPermissionLocked = false;
                        break;
                }
            }
        });

    }


    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        int permState;
        switch (requestCode) {
            case LOCATION_PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0) {
                    if(grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                        if(!ActivityCompat.shouldShowRequestPermissionRationale(
                                mActivity,
                                Manifest.permission.ACCESS_FINE_LOCATION)){
                            permState = PERMISSION_BLOCKED;
                        }else{permState = PERMISSION_DENIED;}
                    }else {permState = PERMISSION_GRANTED;}
                }
                else{permState = PERMISSION_DENIED;}

                switch (permState){
                    case PERMISSION_BLOCKED:
                        Toast.makeText(mContext,"Please give gps location permission to use the app.",Toast.LENGTH_LONG).show();
                        startInstalledAppDetailsActivity(mContext);
                        mCallback.onLocationPermissionDenied();
                        break;
                    case PERMISSION_DENIED:
                        Toast.makeText(mContext,"Permission Denied, app cannot access the gps location.", Toast.LENGTH_LONG).show();
                        break;
                    case PERMISSION_GRANTED:
                        getLocationSetting();
                        break;
                }
                break;
        }
    }

    public static boolean isLocationEnabled(Context context){
        LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        boolean gpsEnabled = false;
        boolean networkEnabled = false;

        try {
            gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch(Exception ex) {}

        try {
            networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch(Exception ex) {}

        return gpsEnabled && networkEnabled;
    }

    public static void startInstalledAppDetailsActivity(final Context context) {
        if (context == null) {
            return;
        }
        final Intent i = new Intent();
        i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        i.setData(Uri.parse("package:" + context.getPackageName()));
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        context.startActivity(i);
    }

    public static boolean checkLocationPermission(Context context) {
        String permission = "android.permission.ACCESS_FINE_LOCATION";
        int res = context.checkCallingOrSelfPermission(permission);
        return (res == PackageManager.PERMISSION_GRANTED);
    }

    public interface LocationCallback {
        void onLastKnowLocationFetch(Location location);
        void onLocationUpdate(Location location);
        void onLocationPermissionDenied();
        void onLocationSettingsError();
    }


    public void close() {
        mGPSStatusReceiver.unRegisterReceiver();
    }
}

5. In the activity use the below code

public class MainActivity extends AppCompatActivity implements GPSLocation.LocationCallback {

    private GPSLocation mGPSLocation;

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

        mGPSLocation = new GPSLocation(this, this);
        mGPSLocation.init();
    }

    @Override
    public void onLastKnowLocationFetch(Location location) {
        if(location != null) {
            Log.d("ali ", "onLastKnowLocationFetch " + location);
        }
    }

    @Override
    public void onLocationUpdate(Location location) {
        if(location != null) {
            Log.d("ali ", "onLocationUpdate " + location);
        }
    }

    @Override
    public void onLocationPermissionDenied() {

    }

    @Override
    public void onLocationSettingsError() {

    }

    @Override
    protected void onStart() {
        mGPSLocation.connect();
        super.onStart();
    }


    @Override
    public void onResume() {
        super.onResume();
        mGPSLocation.startLocationUpdates();
    }


    @Override
    protected void onPause() {
        super.onPause();
        mGPSLocation.stopLocationUpdates();
    }


    @Override
    protected void onStop() {
        mGPSLocation.disconnect();
        super.onStop();
    }


    @Override
    protected void onDestroy() {
        mGPSLocation.close();
        super.onDestroy();
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode == GPSLocation.LOCATION_PERMISSION_REQUEST_CODE) {
            mGPSLocation.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == GPSLocation.REQUEST_CHECK_SETTINGS) {
            mGPSLocation.onActivityResult(requestCode, resultCode, data);
        }
    }
}
Janishar Ali
  • 376
  • 3
  • 8
  • I tried your solution, but the resoults are odd. Very often Ive got log that currentLocation is equal null. Sometimes the log is correct, do you have any idea why? – Expiredmind Sep 14 '16 at 20:31
  • 1
    current location is null because when u start reading and try to fetch the last known location then it's possible that the last known location will not be available in the 1st read. That is why in the activity callback there is a null check. let the system read the gps and the last known location and process the result in the callback if not null. Otherwise the location read is correct depending upon the GPS satellite visible. You have to implement filtering to choose the next location to choose. It's the raw location that system is providing is being read. – Janishar Ali Sep 15 '16 at 06:13
  • Could you tell me how to let system read the gps last known location? I thought the LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); line get the last known location but its returning null – Expiredmind Sep 15 '16 at 07:00
  • You are right this line itself is reading the last known location but system is providing null. If u keep your gps open and then run the application and log the last known location then it will not return null. If you find a way to get system to not return null then let me know too – Janishar Ali Sep 15 '16 at 08:30
  • I found similiar issue at here http://stackoverflow.com/questions/16830047/locationclient-getlastlocation-return-null . I understand what happend but I cannot solve it. Maybe It good to setUp the basic coordinate (like 0.0) until they find last location. I need to check location only one. – Expiredmind Sep 15 '16 at 09:22
  • What I think will be good is to show loading till u get the location and when u have a location then project on map and move the camera to that location and remove loading – Janishar Ali Sep 15 '16 at 13:43
  • Do you know how to add loading part to that code? Im trying to implement this for couple days and still didnt figured out that :/ – Expiredmind Sep 19 '16 at 09:57
  • Ive implement waiting function but iVe still obtain null. Do you have any ideas? Ive called the function at case LocationSettingsStatusCodes.SUCCESS: in result.setResultCallback(new ResultCallback() part private void waitForGPSSignal(){ progressWindow(); new Handler().postDelayed(new Runnable() { @Override public void run() { getLastKnownLocation(); if(mCurrentLocation!=null) progress.dismiss(); } }, 10000); } – Expiredmind Sep 20 '16 at 09:24
  • 1
    Create a progress dialog and call its show method in onLastKnowLocationFetch(Location location) if location !=null or onLocationUpdate(Location location) when location !=null, use flag to control if loading is shown once – Janishar Ali Sep 20 '16 at 11:52
  • 1
    But still u will get the google map is being rendered. so call dialog cancel method when the camera on the map has moved and then set the isShown = true, I would suggest show loading dialog when u launch the map activity and cancel when camera on map moves for the first time with your location – Janishar Ali Sep 20 '16 at 11:58
  • I tried using AsyncTask to get the first location: new FetchCoordinates((mContext)); asyncTask.execute(); new Handler().postDelayed(new Runnable() { run() { if ( asyncTask.getStatus() == AsyncTask.Status.RUNNING || asyncTask.getStatus() AsyncTask.Status.PENDING ) asyncTask.cancel(true); } },5000); (after 5 secounds set default ones) FetchClass implementation http://pastebin.com/cKmcqHra – Expiredmind Sep 20 '16 at 12:07
  • Why are u using asynctask. The location callback is already in a different thread than UI. u dont need aynctask to get location – Janishar Ali Sep 20 '16 at 12:10
  • The googleMap rendering is not a problem we can allways called mMap.clear and mMap.addMarker(postion) if the coordiantes are correct. I tried to call progress bar with waiting – Expiredmind Sep 20 '16 at 12:53
  • I tried used progress dialog in onLocationUpdate function and it finally works ! Thank you very much man! – Expiredmind Sep 20 '16 at 16:55
  • One more question, when I clicked to deny to enable my location (when gps is turn off) i call callback onLocationPermissionDenied where I setting up the flag isSet which is one of the condition in onLocationUpdate callback run the progress dial, but Ive still got it, It means that onLocationChange is called before that? – Expiredmind Sep 20 '16 at 17:38
  • There are two dialogs.. one for permission to use location and other to use gps. Once you have given location permission then it can read the lastknownlocation and location of the network, if gps location is not available. If u go to app permission and deny the location permission then it wont read any location. try it and let me know too – Janishar Ali Sep 20 '16 at 17:44
  • okay i found the problem. Earlier when i tried to fix this null location i called onLocationUpdate in onConnected function. Now everything works perfect, thanks again! – Expiredmind Sep 20 '16 at 18:12
2

The following code checks, if location is enabled or not. If not it shows alert dialog to enable location service.

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();
}

add below code in AndroidManifest.xml

<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" />
Prathap Badavath
  • 1,621
  • 2
  • 20
  • 24
0

Add this override method for me its worked fine--

 @Override
public void onLocationChanged(Location location) {
    getLocation("onLocationChanged");
}
ShriKant A
  • 105
  • 5