Fatal Exception: java.lang.IllegalStateException GoogleApiClient is not connected yet - java

We have this crash in crashlytics, the weird thing is it happens in onConnected() callback when requesting location updates.
Code:
abstract public class MainService_6_LocationClient extends MainService_5_DriverGpsLocationStoring
implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private LocationListener highAccuracyListener;
private GoogleApiClient googleApiClient;
private LocationRequest gpsRequest;
#Override
public void onCreate() {
super.onCreate();
lazyInit();
googleApiClient.connect();
}
#Override public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected");
lazyInit();
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, gpsRequest,
highAccuracyListener);
}
private void lazyInit() {
if (highAccuracyListener == null) {
highAccuracyListener = new HighAccuracyLocationListener();
}
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
if (gpsRequest == null) {
gpsRequest = new LocationRequest().setInterval(2000)
.setFastestInterval(1000)
.setSmallestDisplacement(0)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
}
#Override public void onConnectionSuspended(int i) {
Log.w(TAG, "onConnectionSuspended");
lazyInit();
googleApiClient.reconnect();
}
#Override public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed");
}
#Override public void onDestroy() {
Log.d(TAG, "onDestroy");
if (googleApiClient != null) {
if (googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient,
highAccuracyListener);
googleApiClient.disconnect();
}
googleApiClient = null;
}
highAccuracyListener = null;
gpsRequest = null;
super.onDestroy();
}
Crash log:
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.common.internal.o.a()
at com.google.android.gms.common.api.b.b()
at com.google.android.gms.internal.lu.requestLocationUpdates()
at ee.mtakso.driver.service.orderState.MainService_6_LocationClient.onConnected(MainService_6_LocationClient.java:33)
at com.google.android.gms.common.internal.f.d()
at com.google.android.gms.common.api.b.gm()
at com.google.android.gms.common.api.b.d()
at com.google.android.gms.common.api.b$2.onConnected()
at com.google.android.gms.common.internal.f.d()
at com.google.android.gms.common.internal.f.dL()
at com.google.android.gms.common.internal.e$h.b()
at com.google.android.gms.common.internal.e$h.g()
at com.google.android.gms.common.internal.e$b.gU()
at com.google.android.gms.common.internal.e$a.handleMessage()
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4947)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
at dalvik.system.NativeStart.main(NativeStart.java)
Doesn't onConnected() imply GoogleApiClient is connected and ready to be used? How can I resolve this?

https://developer.android.com/reference/com/google/android/gms/common/api/GoogleApiClient.html
You should instantiate a client object in your Activity's onCreate(Bundle) method and then call connect() in onStart() and disconnect() in onStop(), regardless of the state.
The implementation of the GoogleApiClient appears designed for only a single instance. It's best to instantiate it only once in onCreate, then perform connections and disconnections using the single instance.

Maybe you should notice, GoogleApiClient.Builder has a method setAccountName(). You should invoke this method with your Google account name. I have tried, and succeeded. I used the following code:
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.setAccountName("李江涛")
.build();
}
if (mLocationRequest == null) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

Try using com.google.android.gms.location.LocationClient instead of GoogleApiClient. Note that the ConnectionCallbacks and OnConnectionFailedListener interfaces that you implement will be slightly different.
Here's a quick example:
class LocationHandler implements ConnectionCallbacks,
OnConnectionFailedListener, LocationListener {
private LocationClient client;
void getLocation(Context context) {
client = new LocationClient(context, this, this);
client.connect();
}
#Override
public void onConnected(Bundle connectionHint) {
LocationRequest request = LocationRequest.create();
request.setNumUpdates(1);
client.requestLocationUpdates(request, this);
client.unregisterConnectionCallbacks(this);
}
#Override
public void onDisconnected() { }
#Override
public void onConnectionFailed(ConnectionResult result) {
// handle connection failure
}
#Override
public void onLocationChanged(Location location) {
client.removeLocationUpdates(this);
client.disconnect();
// do stuff with the location
}
}

Related

Implementing a background service to catch location

I have an app that can capture fotos and send to the server.
I need to get location(lat,lon,alt) everytime i take a foto.
After a lot of research i understood that taking this data requires some time, the gps triangulation must run asyncronous, so i tried to figure out the best way to do this.
After some time, i had the idea, to start a service, everytime i run the aplication, this service will grab the last location everytime, and when i send a foto i will get the last location values.
So i did something like this(Service):
package com.example.afcosta.inesctec.pt.android.services;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "BOOMBOOMTESTGPS";
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 1000;
private static final float LOCATION_DISTANCE = 10f;
private class LocationListener implements android.location.LocationListener
{
Location mLastLocation;
public LocationListener(String provider)
{
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location)
{
Log.e("asd", "onLocationChanged: " + location);
mLastLocation.set(location);
}
#Override
public void onProviderDisabled(String provider)
{
Log.e(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider)
{
Log.e(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.e(TAG, "onStatusChanged: " + provider);
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onCreate()
{
Log.e(TAG, "onCreate");
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "network provider does not exist, " + ex.getMessage());
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "gps provider does not exist " + ex.getMessage());
}
}
#Override
public void onDestroy()
{
Log.e(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.i(TAG, "fail to remove location listners, ignore", ex);
}
}
}
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(this.LOCATION_SERVICE);
}
}
}
and then i call the service when my app runs(at the moment i am testing this just with login(onCreate))
startService(new Intent(this, MyService.class));
i get this logTrace(with red):
`05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: LocationListener gps
05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: LocationListener network
05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: onCreate
05-22 20:35:39.652 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: initializeLocationManager
05-22 20:35:39.657 32426-32426/com.example.afcosta.inesctec.pt.android E/BOOMBOOMTESTGPS: onStartCommand
CHANGES
that was what i tried to do before:
`
public class GoogleLocation implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private double lat;
private double lon;
private double alt;
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLon() {
return lon;
}
public void setLon(double lon) {
this.lon = lon;
}
public double getAlt() {
return alt;
}
public void setAlt(double alt) {
this.alt = alt;
}
boolean gps_enabled = false;
boolean network_enabled = false;
private Context context;
LocationManager lm;
LocationListener listener;
final int MY_PERMISSION_ACCESS_COURSE_LOCATION = 1;
public GoogleLocation(Context context) {
this.context = context;
}
public void getPosition() {
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
setLat(location.getLatitude());
setLon(location.getLongitude());
setAlt(location.getAltitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
location();
}
#Override
public void onProviderDisabled(String provider) {
}
};
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) context, new String[] { android.Manifest.permission.ACCESS_COARSE_LOCATION },
MY_PERMISSION_ACCESS_COURSE_LOCATION);
}
}
lm.requestLocationUpdates("gps", 5000, 0, listener);
}
public void location(){
GoogleApiClient googleApiClient = null;
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(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.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
(Activity) context, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
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.
break;
}
}
});
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
`
i don't get any location, i don't know why, the onlocationchanged never runs, if the location doesn't change i want to get the last.
How can i accomplish that?
Thanks
Best regards
`
You don't need service class as you can get location in activity in which you are taking photos.
So first of all add permissions in manifest file
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
and dependencies in gradle
compile 'com.google.android.gms:play-services:10.2.6'
Then in activity in which you are taking photos
Implement listeners
public class Activity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener{
protected Location mLastLocation;
private double Latitude;
private double Longitude;
in onCreate method ask user for location permission and call
buildGoogleApiClient();
and then define buildGoogleApiClient() method
/**
* Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
*/
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
after that implements listener interfaces methods
#Override
public void onConnected(Bundle connectionHint) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
Latitude = mLastLocation.getLatitude();
Longitude = mLastLocation.getLongitude();
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
#Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
then at the end
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
let me know if you don't understand anything

GoogleApiClient OnConnected Not Called unless Service is stopped

I am calling a service which connects to googleapiclient. Whenever the service is called first time, everything works smooth, client is connected, Onconnected is called. But the moment I recall service without stopping, I get googleapiclient connected but Onconnected is never called. Why So? Is there required to terminate service everytime. Here is the code:
public class ALW extends Service implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, LocationListener {
private GoogleApiClient mGoogleApiClient;
#Override
public void onDestroy() {
super.onDestroy();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
Log.d("ALWFA", "Stopped");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ALWFA", "Called");
if (!mGoogleApiClient.isConnected()) {
Log.e("ALWFA", "Called for Connection");
mGoogleApiClient.connect();
} else {
Log.e("ALWFA", "Already Connected");
}
//Do Work
return super.onStartCommand(intent, flags, startId);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
buildGoogleApiClient();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d("Google Client", "Connected");
//Do work
}
#Override
public void onConnectionSuspended(int i) {
System.out.println("Connection Sus");
buildGoogleApiClient();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.i("Connection Error", "onConnectionFailed:" + connectionResult.getErrorCode() + "," + connectionResult.getErrorMessage());
buildGoogleApiClient();
System.out.println("Connection Failed");
}
synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
and I m not getting any error in Onconenctiofailed. Normally code stuck at onStartCommand: "ALWFA Called". whenever service is called second time.
You should check before calling it again like this
if(mGoogleApiClient!=null && !mGoogleApiClient.isConnected())
{
//Do your work
}
and implement these methods
#Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null)
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient != null)
mGoogleApiClient.disconnect();
}

java.lang.IllegalStateException: GoogleApiClient is not connected yet

ERROR MESSAGE
FATAL EXCEPTION: main
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.internal.zzlg.zzb(Unknown Source)
at com.google.android.gms.internal.zzli.zzb(Unknown Source)
at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
at com.example.argede06.argede.KonumServis_KonumCek.Konum_GoogleApi.startLocationUpdate(Konum_GoogleApi.java:82)
at com.example.argede06.argede.KonumServis_KonumCek.Konum_GoogleApi$1.run(Konum_GoogleApi.java:62)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5336)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
CODE
public class Konum_GoogleApi extends Service implements ConnectionCallbacks,OnConnectionFailedListener,LocationListener
{
int mStartMode;
protected GoogleApiClient mgoogleApiClient;
protected LocationRequest mLocationRequest;
protected Location location;
private Handler mServiceHandler;
private static final String TAG = Konum_GoogleApi.class.getSimpleName();
#Override
public void onCreate() {
Log.e("BuildAPi googlclient","sycbhorid");
mgoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mgoogleApiClient.connect();
createRequest();
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
startLocationUpdate();
}
});
HandlerThread handlerThread = new HandlerThread(TAG);
handlerThread.start();
mServiceHandler = new Handler(handlerThread.getLooper());
}
protected void createRequest(){
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(0);
mLocationRequest.setFastestInterval(0);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void startLocationUpdate(){
Log.i(TAG, "Requesting location updates");
try {
LocationServices.FusedLocationApi.requestLocationUpdates(mgoogleApiClient, mLocationRequest,(com.google.android.gms.location.LocationListener)this);
} catch (SecurityException unlikely) {
Log.e(TAG, "Lost location permission. Could not request updates. " + unlikely);
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onConnected(Bundle bundle) {
Log.e("Connect","onconnected");
if(location == null){
location = LocationServices.FusedLocationApi.getLastLocation(mgoogleApiClient);
}
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "GoogleApiClient connection suspended.");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "GoogleApiClient connection failed.");
}
#Override
public void onLocationChanged(Location location) {
Log.e("(Google)Kordinatlar =",String.valueOf(location.getLongitude())+","+String.valueOf(location.getLatitude()));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public void onDestroy(){
mServiceHandler.removeCallbacksAndMessages(null);
mgoogleApiClient.disconnect();
}
}
GoogleApiClient Error in StartLocationUpdate line protected void
///this eror LocationServices.FusedLocationApi.requestLocationUpdates(mgoogleApiClient, mLocationRequest,(com.google.android.gms.location.LocationListener)this);
I can not run activiy on service. I can not run location update on service. I am constantly getting this error. How can I resolve this error?
You are calling createRequest before the client has connected. mgoogleApiClient.connect(); is asynchronous and does not connect to the client straight away, move createRequest(); to the onConnected method that way the location request will be sent when the API client is connected.

I cannot seem to connect to GoogleAPI Client, there is no connection, neither is there a failure

So I am trying to connect to the Google API client, but I am not getting a response from my onConnected method or onConnectionFailed method. Both methods are like so, respectively:
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG, "OnConnected");
if (PackageManager.PERMISSION_GRANTED ==
(ContextCompat.checkSelfPermission(mParentBase, android.Manifest.permission.ACCESS_FINE_LOCATION)))
{
Log.d(TAG, "Permission Was Granted" );
mMyLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mMyLocation == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, requestLocation, mParentIntent);
} else {
Log.d(TAG, mMyLocation.toString());
}
} else {
ActivityCompat.requestPermissions(mParentActivity, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_ACCESS_FINE_LOCATION);
Log.d(TAG, "Permission Was Requested" );
}
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.i(TAG, "Connection Failed");
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(mParentActivity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
I have a public interface that starts the connection to the API:
public void connect()
{
mGoogleApiClient.connect();
Log.d(TAG, "Connection Requested");
}
I can see the above log output file on Android Studio Run Console.
Has anyone else seen this type of problem?
Edit:
Code to build and initialise the client
public myLocation(Context Base, Activity activitiyBase, PendingIntent intent) {
mParentBase = Base;
mParentActivity = activitiyBase;
mParentIntent = intent;
initialLocationService();
}
/**
* Initialize the Location Service and API Client
*/
private void initialLocationService(){
mGoogleApiClient = new GoogleApiClient.Builder(mParentBase)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
requestLocation = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10*1000)
.setFastestInterval(1*1000);
the class implements the following:
public class myLocation implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
ActivityCompat.OnRequestPermissionsResultCallback,
LocationListener
{
OK. I've put together some code that I hope will help you find your problem. I have this code as a working app on a device. I've used a mix of your code with mine. By comparing the differences, you should be able to narrow down your problem. 1st myLocation class...
public class myLocation implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
ActivityCompat.OnRequestPermissionsResultCallback,
LocationListener {
private final static String TAG = "myLocation";
private final static int MY_PERMISSION_ACCESS_FINE_LOCATION = 1;
private final static long ONE_SECOND = 1000;
private final static long UPDATE_INTERVAL = ONE_SECOND;
private final static long FASTEST_UPDATE_INTERVAL = ONE_SECOND;
private GoogleApiClient mGoogleApiClient = null;
Context mParentBase;
Activity mParentActivity;
public myLocation(Context Base, Activity activitiyBase) {
mParentBase = Base;
mParentActivity = activitiyBase;
initialLocationService();
}
// you call this an interface in your question but I'm just
// making it a public method which can be called from Activity
public void connect()
{
mGoogleApiClient.connect();
Log.d(TAG, "Connection Requested");
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG, "OnConnected");
if (PackageManager.PERMISSION_GRANTED ==
(ContextCompat.checkSelfPermission(mParentBase,
android.Manifest.permission.ACCESS_FINE_LOCATION)))
{
Log.d(TAG, "Permission Was Granted");
startLocationUpdates();
} else {
ActivityCompat.requestPermissions(mParentActivity,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSION_ACCESS_FINE_LOCATION);
Log.d(TAG, "Permission Was Requested");
}
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.i(TAG, "Connection Failed");
// just logging for now
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions, #NonNull int[] grantResults) {
// loading from Android Studio, not going to worry about this now
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection Suspended");
// just logging for now, not trying to resolve failure
}
#Override
public void onLocationChanged(Location location) {
Log.i(TAG, "Entered the onLocationChanged() method");
// this calls one or the other private methods that don't
// matter to your problem. I can post them if you like.
if (location != null) {
showLocationInfo(location);
} else {
Log.d(TAG, "Can't get last location");
setAllUnavailable();
}
}
private void initialLocationService() {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(mParentBase)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
private void locationRequestUpdates(long interval, long fastestInterval, int priority) {
// remove any previous updates
try {
if(mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi
.removeLocationUpdates(mGoogleApiClient, this);
}
} catch (SecurityException e) {
logException("SecurityException", e);
}
// build a new request
LocationRequest locationRequest = new LocationRequest()
.setInterval(interval)
.setFastestInterval(fastestInterval)
.setPriority(priority);
// now send new request
try {
if(mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, locationRequest, this);
}
} catch (SecurityException e) {
logException("SecurityException", e);
}
}
private void startLocationUpdates() {
Location lastLocation = null;
try {
lastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
} catch (SecurityException e) {
logException("SecurityException", e);
}
if (lastLocation != null) {
showLocationInfo(lastLocation);
} else {
Log.d(TAG, "Can't get last location");
setAllUnavailable();
}
locationRequestUpdates(UPDATE_INTERVAL,
FASTEST_UPDATE_INTERVAL,
LocationRequest.PRIORITY_HIGH_ACCURACY);
}
}
In the Activity, in onCreate()...
mMyLocation = new myLocation(getApplicationContext(), this);
and in onStart()...
mMyLocation.connect();
I hope this helps.

Update location in googleMap (android)

I'm trying to build an app that will show me my location in googleMap and will update my location every few seconds.
here is my code:
public class MapsActivity extends FragmentActivity implements
ConnectionCallbacks, OnConnectionFailedListener, LocationListener, OnMapReadyCallback {
protected static final String TAG = "location-updates-sample";
/**
* The desired interval for location updates. Inexact. Updates may be more or less frequent.
*/
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
/**
* The fastest rate for active location updates. Exact. Updates will never be more frequent
* than this value.
*/
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
// Keys for storing activity state in the Bundle.
protected final static String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
protected final static String LOCATION_KEY = "location-key";
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
protected Location mCurrentLocation;
/**
* Tracks the status of the location updates request. Value changes when the user presses the
* Start Updates and Stop Updates buttons.
*/
protected Boolean mRequestingLocationUpdates;
private GoogleMap mMap;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mRequestingLocationUpdates = false;
updateValuesFromBundle(savedInstanceState);
buildGoogleApiClient();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng loc = new LatLng(-34,151);
mMap.addMarker(new MarkerOptions().position(loc).title("my location"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(loc));
startUpdates();
}
private void updateValuesFromBundle(Bundle savedInstanceState) {
Log.i(TAG, "Updating values from bundle");
if (savedInstanceState != null) {
if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
mRequestingLocationUpdates = savedInstanceState.getBoolean(
REQUESTING_LOCATION_UPDATES_KEY);
}
// Update the value of mCurrentLocation from the Bundle and update the UI to show the
// correct latitude and longitude.
if (savedInstanceState.keySet().contains(LOCATION_KEY)) {
// Since LOCATION_KEY was found in the Bundle, we can be sure that mCurrentLocation
// is not null.
mCurrentLocation = savedInstanceState.getParcelable(LOCATION_KEY);
}
updateUI();
}
}
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
public void startUpdates() { // start updating location
if (!mRequestingLocationUpdates) {
mRequestingLocationUpdates = true;
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
public void stopUpdates() { // stop updating location
if (mRequestingLocationUpdates) {
mRequestingLocationUpdates = false;
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
/**
* Updates the latitude, the longitude, and the last location time in the UI.
*/
private void updateUI() {
LatLng loc = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
mMap.addMarker(new MarkerOptions().position(loc).title("my location"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(loc));
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
#Override
protected void onPause() {
super.onPause();
// Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
/**
* Runs when a GoogleApiClient object successfully connects.
*/
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "Connected to GoogleApiClient");
if (mCurrentLocation == null) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
updateUI();
}
if (mRequestingLocationUpdates) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
updateUI();
Toast.makeText(this, getResources().getString(R.string.location_updated_message),
Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
/**
* Stores activity data in the Bundle.
*/
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, mRequestingLocationUpdates);
savedInstanceState.putParcelable(LOCATION_KEY, mCurrentLocation);
super.onSaveInstanceState(savedInstanceState);
}
}
This code is a part from a sample code from google but i've changed a few things and added the googleMap, its just crashing after onMapReady().
stacktrace:
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.common.api.internal.zzh.zzb(Unknown Source)
at com.google.android.gms.common.api.internal.zzl.zzb(Unknown Source)
at com.google.android.gms.common.api.internal.zzj.zzb(Unknown Source)
at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
at com.idanofek.photomap.MapsActivity.startUpdates(MapsActivity.java:135)
at com.idanofek.photomap.MapsActivity.onMapReady(MapsActivity.java:91)
at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzo$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:387)
at com.google.android.gms.maps.internal.be.a(SourceFile:82)
at com.google.maps.api.android.lib6.e.fb.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Before any operation is executed, the GoogleApiClient must be connect using the 'connect()' method. The client is not considered connected until the onConnected(Bundle) callback has been called.
You should instantiate a client object in your Activity's 'onCreated(Bundle)' method then call connect() on onStart()
You may call startLocationUpdate() from the onConnected() callback
#Override
public void onConnected(Bundle connectionHint) {
...
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
Here's a Google Documentation regarding Location Updates: http://developer.android.com/training/location/receive-location-updates.html

Categories