Search code examples
androidgpslocationandroid-fusedlocation

Location updates not working on allowing runtime permission


I've written code for app that shows phone's latitude and longitude and displays it on the screen, but after granting location permission it doesn't show anything, only when I reopen the app. This is the code for the MainActivity:

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;


public class MainActivity extends AppCompatActivity implements
    GoogleApiClient.ConnectionCallbacks,     GoogleApiClient.OnConnectionFailedListener,
    com.google.android.gms.location.LocationListener {

protected static final String TAG = "Location Services";
protected static final String TAGfail = "FAILED TO CONNECT";
protected static final String TAGNOCONNECTION = "NO CONNECTION";
protected GoogleApiClient mGoogleApiClient;
protected TextView mLatitudeText;
protected TextView mLongitudeText;
protected LocationRequest mLocationRequest;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mLatitudeText = (TextView) findViewById(R.id.latitude);
    mLongitudeText = (TextView) findViewById(R.id.longitude);
    ActivityCompat.requestPermissions(MainActivity.this,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
            1);
    buildGoogleApiClient();

}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

}

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

@Override
protected void onStop() {
    super.onStop();
    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
    }
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    mLocationRequest = LocationRequest.create();
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setInterval(1000);
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
            (this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}

@Override
public void onLocationChanged(Location location) {
    Log.i(TAG, location.toString());

    mLatitudeText.setText(String.valueOf(location.getLatitude()));
    mLongitudeText.setText(String.valueOf(location.getLongitude()));

}

@Override
public void onConnectionSuspended(int i) {
    Log.i(TAGNOCONNECTION, "no connection");
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    Toast.makeText(this, "No location permission granted", Toast.LENGTH_SHORT).show();
    Log.i(TAGfail, "failed to connect");
}

}

Manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.domin.myfavouriteplace">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <meta-data android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version"/>
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

And Gradle dependencies:

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.google.android.gms:play-services:10+'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'}

How can I resolve this problem?

Bests


Solution

  • Try this complete solution

    in onCreate() do this

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mLatitudeText = (TextView) findViewById(R.id.latitude);
        mLongitudeText = (TextView) findViewById(R.id.longitude);
        checkAndroidVersion();
    }
    

    this method checkAndroidVersion();

    public void checkAndroidVersion() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkAndRequestPermissions()) {
                    buildClient();
                    mGoogleApiClient.connect();
                } else
                {
                }
    
            } else {
                if (checkPlayServices()) {
                    // Building the GoogleApi client
                    buildClient();
                    mGoogleApiClient.connect();
                }
                // write your logic here
            }
    
        }
    

    this method

    public boolean checkAndRequestPermissions() {
    
            int location = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION);
            List<String> listPermissionsNeeded = new ArrayList<>();
    
            if (location != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
            }
            if (!listPermissionsNeeded.isEmpty()) {
                ActivityCompat.requestPermissions(MainActivity.this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
                return false;
            }
            return true;
        }
    public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
    

    then in onRequestPermission()

    @Override
        public void onRequestPermissionsResult(int requestCode,
                                               String permissions[], int[] grantResults) {
            Log.d("in main on request", "Permission callback called-------");
            switch (requestCode) {
                case REQUEST_ID_MULTIPLE_PERMISSIONS: {
                    Map<String, Integer> perms = new HashMap<>();
    
                    perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
                    // Fill with actual results from user
                    if (grantResults.length > 0) {
                        for (int i = 0; i < permissions.length; i++)
                            perms.put(permissions[i], grantResults[i]);
                        // Check for both permissions
                        if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                            Log.d("in main on request", "location services permission granted");
                            // process the normal flow
                            //else any one or both the permissions are not granted
                            buildClient();
                            mGoogleApiClient.connect();
                        } else {
                            Log.d("in fragment on request", "Some permissions are not granted ask again ");
                            //permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
    //                        // shouldShowRequestPermissionRationale will return true
                            //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
                            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)) {
                                showDialogOK("Location services  services are required for this app",
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                switch (which) {
                                                    case DialogInterface.BUTTON_POSITIVE:
                                                        checkAndRequestPermissions();
                                                        break;
                                                    case DialogInterface.BUTTON_NEGATIVE:
                                                        // proceed with logic by disabling the related features or quit the app.
                                                        break;
                                                }
                                            }
                                        });
                            }
                            //permission is denied (and never ask again is  checked)
                            //shouldShowRequestPermissionRationale will return false
                            else {
                                Toast.makeText(MainActivity.this, "Go to settings and enable permissions", Toast.LENGTH_LONG)
                                        .show();
                                //                            //proceed with logic by disabling the related features or quit the app.
                            }
                        }
                    }
                }
            }
    
        }
    
        public void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
            new AlertDialog.Builder(MainActivity.this)
                    .setMessage(message)
                    .setPositiveButton("OK", okListener)
                    .setNegativeButton("Cancel", okListener)
                    .create()
                    .show();
        }
    

    then

     public void buildClient() {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        }
    

    then do this

     @Override
        public void onStop() {
            super.onStop();
            if (mGoogleApiClient != null) {
                if (mGoogleApiClient.isConnected() && mGoogleApiClient != null) {
                    mGoogleApiClient.disconnect();
                }
            }
        }
    

    and then

    /**
         * Method to verify google play services on the device
         */
        public boolean checkPlayServices() {
            int resultCode = GooglePlayServicesUtil
                    .isGooglePlayServicesAvailable(this);
            if (resultCode != ConnectionResult.SUCCESS) {
                if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                    GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                            PLAY_SERVICES_RESOLUTION_REQUEST).show();
                } else {
                    Toast.makeText(MainActivity.this,
                            "This device is not supported.", Toast.LENGTH_LONG)
                            .show();
                    finish();
                }
                return false;
            }
            return true;
        }
    

    and then add this

    @Override
        public void onConnected(@Nullable Bundle bundle) {
            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
                // 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;
            }
            startLocationUpdates();
            mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if (mLocation == null) {
                startLocationUpdates();
            }
            if (mLocation != null) {
                double latitude = mLocation.getLatitude();
                double longitude = mLocation.getLongitude();
            } else {
                // Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
            }
            /**
             * This library works in release mode only with the same JKS key used for
             * your Previous Version
             */
    
        }
    
        protected void startLocationUpdates() {
            // Create the location request
            mLocationRequest = LocationRequest.create()
                    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                    .setInterval(5000)
                    .setFastestInterval(5000);
            // Request location updates
            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
                // 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;
            }
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
                    mLocationRequest, this);
            Log.d("reque", "--->>>>");
        }
    
        @Override
        public void onConnectionSuspended(int i) {
            Log.i(TAG, "Connection Suspended");
            mGoogleApiClient.connect();
        }
    
        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
            try {
                if (checkAndRequestPermissions()) {
                    buildClient();
                    mGoogleApiClient.connect();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onLocationChanged(Location location) {
            current_location = location;
            SharedPrefsUtils.setStringPreference(MainActivity.this, "user_current_latitude", current_location.getLatitude() + "");
            SharedPrefsUtils.setStringPreference(MainActivity.this, "user_current_longitude", current_location.getLongitude() + "");
            System.out.println("sjkbd jdsbj");
        }
    

    in the Activity or fragment

    private GoogleApiClient mGoogleApiClient;
        private Location mLocation;
        private LocationManager locationManager;
        private LocationRequest mLocationRequest;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {