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();
}
Related
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
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 want to get current location of user by using play service api. But always its calling onConnectionFailed() method. I have added google-services.json file with SHA-1 key. But its showing the Toast message written in onConnectionFailed() method. How can i fix it?
Here is my code -
public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//setup GoogleApiClient
setupGoogleApiClient();
}
}
}
//setup GoogleApiClient object
private void setupGoogleApiClient() {
// Create an instance of GoogleAPIClient.
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
mGoogleApiClient.connect();
}
protected void onStart() {
super.onStart();
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Toast.makeText(this, "Connected with google play service", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionSuspended(int i) {
Toast.makeText(this, "Connection suspended with google play service", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Toast.makeText(this, "Failed to connect with google play service", Toast.LENGTH_LONG).show();
}
}
Try changing play service version in your gradle file,
if you are using
compile 'com.google.android.gms:play-services:10.0.1'
try with
compile 'com.google.android.gms:play-services:8.x.x'
and other combination.
Note:- replace "x" with suitable values
I am trying to find last known location of device using GoogleApiClient, So I used fine level access, but getting following exception because location coming is null.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.kuldeep.location2, PID: 1421
java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at com.example.kuldeep.location2.MainActivity.onConnected(MainActivity.java:51)
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(Bundle bundle) {
try {
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
Toast.makeText(this, mLastLocation.getLatitude() + ", " + mLastLocation.getLongitude(), Toast.LENGTH_SHORT);
} catch (SecurityException e){
e.printStackTrace();
}
}
My manifest file is as follow :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.kuldeep.location2">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
</manifest>
First of all, getLastLocation() can be null so you be carefull acessing directly to mLastLocation without a "null" check. In second place, i suggest you to add in your manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
and then call a LocationRequest.
if(locRequest== null)
{
locRequest= new LocationRequest();
locRequest.setInterval( interval );
locRequest.setFastestInterval( fastestInterval );
locRequest.setPriority( priority );
LocationServices.FusedLocationApi.requestLocationUpdates(yourGoogleApiClient, locRequest, this);
}
Using GoogleApiClient find a CurrentLocation like these:
private GoogleApiClient googleApiClient;
private Location mLastLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
isCheckLocationServiceisOn(context);
if(googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
protected void onResume() {
super.onResume();
isCheckLocationServiceisOn(context);
}
#Override
public void onConnected(Bundle arg0) {
if(googleApiClient.isConnected()) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (mLastLocation != null) {
System.out.println("latiTude....."+ String.valueOf(mLastLocation.getLatitude()));
System.out.println("longiTude....."+ String.valueOf(mLastLocation.getLongitude()));
}
}
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
System.out.println("onConnectionFailed...."+ arg0.toString());
}
#Override
public void onConnectionSuspended(int arg0) {
System.out.println("onConnectionSuspended...."+ arg0);
}
Add Permission in manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Here,
Implements ConnectionCallbacks, OnConnectionFailedListener interface for that supported override methods they must be com.google.android.gms.common.api.GoogleApiClient package.
MUST REMEMBER:
Wi-Fi and GSM and GPS is must be on in device if not then generate these kind of error in onConnected()
I give you code to check & open location service also:
public static void isCheckLocationServiceisOn (final Context context) {
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
boolean network_enabled = false;
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) {
// notify user
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setMessage("Location Services Disabled. \n Please enable location services.");
dialog.setPositiveButton("Enable", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(myIntent);
//get gps
}
});
dialog.setNegativeButton("Cancle", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.show();
}
}
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
}
}