I am trying to get the permission for accessing the location and using the Fusedlocation provider API for android, however, my app crashes on opening. I reviewed the Google developer documentation and made the changes appropriately to the respective method.
When I get a location, I am passing the coordinates and store them using SharedPreferences. Can you please let me know what did I not handle in the program or handle incorrectly?
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private final String TAG = "LocationActivity";
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
String lat, lon;
Location mLastLocation;
GridView androidGridView;
String[] gridViewString = {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//checkAppPermission();
Log.d(TAG, "Test location ..............");
//setup GoogleApiclient
buildGoogleApiClient();
Log.d(TAG, "After build api client");
}
public void checkAppPermission(){
if (checkPermission()) {
Toast.makeText(this, "Permission already granted.", Toast.LENGTH_LONG).show();
} else {
requestPermission();
Toast.makeText(this, "Please request permission.", Toast.LENGTH_LONG).show();
}
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
Log.d(TAG, "Test location 2..............");
return result == PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, 1);
Log.d(TAG, "requestPermissions..............");
}
//This method will be called when the user will tap on allow or deny
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//Checking the request code of our request
Log.d(TAG, "onRequestPermissionsResult..............");
if (requestCode == 1) {
//If permission is granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//Displaying a toast
Toast.makeText(this, "Permission granted now you can read the storage", Toast.LENGTH_LONG).show();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(android.Manifest.permission.ACCESS_FINE_LOCATION)) {
showMessageOKCancel("You need to allow access to both the permissions",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{ACCESS_FINE_LOCATION,},
1);
}
}
});
return;
}
}
}
}
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Log.d(TAG, "GoogleAPIclient init ..............");
}
@Override
protected void onStart() {
super.onStart();
// Connect the client.
Log.d(TAG, "onStart fired ..............");
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
// Disconnecting the client invalidates it.
mGoogleApiClient.disconnect();
Log.d(TAG, "onStop fired ..............");
super.onStop();
}
@Override
public void onConnected(Bundle bundle) {
checkAppPermission();
Log.d(TAG, "inside onconnected");
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(1000); // Update location every 10 seconds
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
lat = String.valueOf(mLastLocation.getLatitude());
lon = String.valueOf(mLastLocation.getLongitude());
}
Log.d(TAG,"" +lat);
Log.d(TAG,""+ lon);
Log.d(TAG, "calling storeprefs inside onconnected");
storeprefs(lat,lon);
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "GoogleApiClient connection has been suspend");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "GoogleApiClient connection has failed");
}
@Override
protected void onPause() {
super.onPause();
}
@Override
public void onLocationChanged(Location location) {
// New location has now been determined
String lat = Double.toString(location.getLatitude());
String lon = Double.toString(location.getLongitude());
Log.i(TAG, lat);
Log.i(TAG, lon);
storeprefs(lat,lon);
// You can now create a LatLng Object for use with maps
//LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
}
Error:
FATAL EXCEPTION: main
Process: com.example.android.wesport, PID: 11572
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.wesport/com.example.android.wesport.MainActivity}: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.internal.zzof.zzd(Unknown Source)
at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
at com.example.android.wesport.MainActivity.onCreate(MainActivity.java:82)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Stack trace 2
FATAL EXCEPTION: main
Process: com.example.android.wesport, PID: 5763
java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations.
at android.os.Parcel.readException(Parcel.java:1683)
at android.os.Parcel.readException(Parcel.java:1636)
at com.google.android.gms.location.internal.zzi$zza$zza.zza(Unknown Source)
at com.google.android.gms.location.internal.zzk.zza(Unknown Source)
at com.google.android.gms.location.internal.zzl.zza(Unknown Source)
at com.google.android.gms.location.internal.zzd$1.zza(Unknown Source)
at com.google.android.gms.location.internal.zzd$1.zza(Unknown Source)
at com.google.android.gms.internal.zznt$zza.zzb(Unknown Source)
at com.google.android.gms.internal.zzoc.zzf(Unknown Source)
at com.google.android.gms.internal.zzoc.zzd(Unknown Source)
at com.google.android.gms.internal.zzoh.zzd(Unknown Source)
at com.google.android.gms.internal.zzof.zzd(Unknown Source)
at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
at com.example.android.wesport.MainActivity.onConnected(MainActivity.java:171)
at com.google.android.gms.common.internal.zzl.zzm(Unknown Source)
at com.google.android.gms.internal.zzof.zzk(Unknown Source)
at com.google.android.gms.internal.zzod.zzsb(Unknown Source)
at com.google.android.gms.internal.zzod.onConnected(Unknown Source)
at com.google.android.gms.internal.zzoh.onConnected(Unknown Source)
at com.google.android.gms.internal.zznw.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzk$1.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzd$zzj.zztp(Unknown Source)
at com.google.android.gms.common.internal.zzd$zza.zzc(Unknown Source)
at com.google.android.gms.common.internal.zzd$zza.zzw(Unknown Source)
at com.google.android.gms.common.internal.zzd$zze.zztr(Unknown Source)
at com.google.android.gms.common.internal.zzd$zzd.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
You cannot call
requestLocationUpdates()
untilonConnected()
is called. However, you are callingrequestLocationUpdates()
already inonCreate()
, if you have determined that you hold the runtime permission.