Im building a geolocation app and I can't get it to work. The mGoogleApiClient is built and has a normal value, but after the method that creates the object is called, becomes null and therefore can't connect. I've seen this through debug mode. Any ideas what's happening? This is the code. Everythng is correct on the manifest and build.gradle file; basically I've followed this tutorial http://www.toptal.com/android/android-developers-guide-to-google-location-services-api.
The app is also integrated with Parse. I'm developing on Android Studio on a virtual device.
Here is a screenshot of debug mode, the mGoogleApiClient object:
http://s18.postimg.org/75svx6i1l/debug1.png
/*
* Copyright (c) 2015-present, Parse, LLC.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.parse.starter;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.app.Activity;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.parse.ParseAnalytics;
import com.parse.ParseObject;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener{
private TextView lblLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
static final int REQUEST_CODE_RECOVER_PLAY_SERVICES = 200;
private Location mLastLocation;
private LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lblLocation = (TextView) findViewById(R.id.lblLocation);
if (checkGooglePlayServices()) {
buildGoogleApiClient();
//prepare connection request
createLocationRequest();
}
//SDK test
ParseObject testObject = new ParseObject("TestObject");
testObject.put("foo", "bar");
testObject.saveInBackground();
ParseAnalytics.trackAppOpenedInBackground(getIntent());
}//end of function onCreate
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/* Check if Google Play services are available on the device*/
private boolean checkGooglePlayServices() {
int checkGooglePlayServices = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (checkGooglePlayServices != ConnectionResult.SUCCESS) {
/*
* google play services is missing or update is required
* return code could be
* SUCCESS,
* SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED,
* SERVICE_DISABLED, SERVICE_INVALID.
*/
GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices,
this, REQUEST_CODE_RECOVER_PLAY_SERVICES).show();
return false;
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) {
if (resultCode == RESULT_OK) {
// Make sure the app is not already connected or attempting to connect
if (!mGoogleApiClient.isConnecting() &&
!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "Google Play Services must be installed.",
Toast.LENGTH_SHORT).show();
finish();
}
}
}
public void buildGoogleApiClient() {
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
}//end of function buildGoogleApiClient
@Override
public void onConnected(Bundle bundle) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
lblLocation.setText(latitude + ", " + longitude);
Toast.makeText(this, "Latitude:" + mLastLocation.getLatitude() +", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show();
} else {
lblLocation.setText("(Couldn't get the location. Make sure location is enabled on the device)");
}
startLocationUpdates();
}//end of function onConnected
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
@Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this);
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(20000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
Toast.makeText(this, "Update -> Latitude:" + mLastLocation.getLatitude()+", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
protected void stopLocationUpdates() {
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (com.google.android.gms.location.LocationListener) this);
}
}
@Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
}
}//end of MainActivity class
答案 0 :(得分:1)
I think you forget to initialize mGoogleApiClient
private void initGoogleApiClient(Context context) {
if (!isGooglePlayServicesAvailable(context)) {
Toast.makeText(context, "Cannot Auto Locate", Toast.LENGTH_SHORT).show();
isGoogleServicesAvailable = false;
return;
} else {
isGoogleServicesAvailable = true;
mGoogleApiClient = (new GoogleApiClient.Builder(context)).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
return;
}
}
答案 1 :(得分:0)
You are using the wrong variable scope. Your problem is that you are using a local variable to store the GoogleApiClient:
public void buildGoogleApiClient() {
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
}//end of function buildGoogleApiClient
Instead, use your field:
public void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
}//end of function buildGoogleApiClient