I wrote some code to get a continuously track location it works but the update triggers only sometimes after restarting the app after the screen timeout, but not allways...
In the "Google Play Services", i use only com.google.android.gms:play-services-location:8.3.0 (to reduce the size).
The AndroidManifest.xml is set for an ACCESS_FINE_LOCATION" permission.
The GPS and "Wi-Fi & mobile network location" of my device is on.
Thanks in advance for help.
Here is the main part:
import android.location.Location;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import comm.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends AppCompatActivity implements
ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
protected TextView txtlat, txtlong;
// ---------------------------------------------------------------------------------------
// Create
// ---------------------------------------------------------------------------------------
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtlat = (TextView)findViewById(R.id.txtlat);
txtlong = (TextView)findViewById(R.id.txtlong);
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
createLocationRequest();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000); // 10sec
mLocationRequest.setFastestInterval(5000); // 5sec
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
// ----------------------------------------------------------------------
#Override
protected void onResume() {
super.onResume();
mGoogleApiClient.connect();
}
// ---------------------------------------------------------------------
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
// ---------------------------------------------------------------------
#Override
public void onConnected(Bundle connectionHint) {
Location location=LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} else {
displayLocation(location);
}
}
// ---------------------------------------------------------------------
public void onLocationChanged (Location location) {
displayLocation(location);
}
// ---------------------------------------------------------------------
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
}
Related
I have an android service and I'd like to do the following:
When clicking a button, I start this service, the toast in the onCreate() method always appears but after that I cannot see the longitude-latitude popping up. My main goal is to use this longitude-latitude couple in more activities.
How can I achieve this?
I implemented GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location .LocationListener because I had to wait 20-30 seconds to get the coordinates. The following code works in an activity, but not as a service.
Thanks!
EDITED:
package com.si.ou;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
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 FullAutoService extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location
.LocationListener {
private static final int PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 100;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
String loki;
#Override
public void onCreate() {
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Toast.makeText(this, "service started....", Toast.LENGTH_SHORT).show();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void startLocationUpdates() {
//noinspection MissingPermission
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission
.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat
.checkSelfPermission(this, android.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);
}
private void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
private boolean checkPermissions() {
return ContextCompat.checkSelfPermission(this, android.Manifest.permission
.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (checkPermissions() && mGoogleApiClient.isConnected()) startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
Double lati = location.getLatitude();
Double longi = location.getLongitude();
loki = String.valueOf(lati) + ":" + String.valueOf(longi);
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), loki, Toast.LENGTH_SHORT).show();
}
});
}
}
It is because you are working on Service.
Try this:
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
getString(R.string.string_id),
Toast.LENGTH_SHORT).show();
}
});
Any UI component can't be accessed from background thread.
If need be arise use handler and sen msg to UI thread and update UI components.
My app is crashing after use those lines:
LatLng curPos = new LatLng(myLocation.getLatitude(), myLocation.getLongitude());
This is the exception that I get:
`E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at ks.pinder.LocationActivity.onMapReady(LocationActivity.java:139)
at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzt$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:326)
at aai.a(:com.google.android.gms.DynamiteModulesB:82)
at maps.ad.t$5.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
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:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)
I am a beginner android programmer, and I don;t know what this it means.
What can I do in order to resolve the problem and present my location?
Here's all the code:
package ks.pinder;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class LocationActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener,
OnMapReadyCallback
{
private GoogleApiClient mGoogleApiClient;
private Location myLocation;
private LocationRequest mLocationRequest;
private int REQUEST_LOCATION = 1;
private static final String TAG = "debug";
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// buildGoogleApiClient();
}
private void buildGoogleApiClient() {
if (mGoogleApiClient == null) {
Log.i(TAG, "onCreate - mGoogleApiClient == null");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
#Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "onConnected - there is no permissions");
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION);
}
else {
Log.i(TAG, "onConnected - there is all permissions");
createLocationRequest();
myLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Log.i(TAG, String.valueOf(myLocation.getLatitude()));
Log.i(TAG, String.valueOf(myLocation == null));
// startLocationUpdates(); //this method doesn't work
}
}
protected void createLocationRequest() {
Log.i(TAG, "createLocationRequest");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
protected void onStart() {
Log.i(TAG, "onStart");
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
Log.i(TAG, String.valueOf(mGoogleApiClient.isConnected()));
}
}
#Override
protected void onPause() {
Log.i(TAG, "onPause");
super.onPause();
stopLocationUpdates();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
#Override
protected void onStop() {
Log.i(TAG,"onStop");
super.onStop();
if (mGoogleApiClient != null){
mGoogleApiClient.disconnect();
}
}
#Override
public void onLocationChanged(Location location) {
myLocation = location;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
Log.i(TAG, "onMapReady");
// Add a marker in Sydney, Australia, and move the camera.
// Log.i(TAG,String.valueOf(myLocation.getLatitude()));
LatLng curPos = new LatLng(myLocation.getLatitude(),myLocation.getLongitude());
mMap.addMarker(new MarkerOptions().position(curPos).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(curPos));
}
}
Update your code like this
#Override
public void onLocationChanged(Location location) {
myLocation = location;
String lat= ""+mylocation.getLatitude();
String longs= ""+mylocation.getLongitude();
// Do your remaining stuffs here
}
I use the code below in my project to retrieve the current location of the user. However, this seems to work on my test devices of API Level 23, but does not work on my test devices of API levels 19 to 22. The request for a location will return null and therefor place me at coordinates 0,0..
How can i get correct coordinates for API levels 19 to 22?
package be.enventorslab.pingvalue;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import be.enventorslab.pingvalue.functions.Functions;
public class NearbyLocationActivity extends AppCompatActivity
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
public static final String TAG = NearbyLocationActivity.class.getSimpleName();
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
Bundle bundle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nearby_map);
setUpMapIfNeeded();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000)
.setFastestInterval(1 * 1000)
.setSmallestDisplacement(1);
}
#Override
protected void onStart() {
super.onStart();
setUpMapIfNeeded();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
}
}
#Override
public void onConnected(Bundle bundle) {
if (Functions.Permissions.getFineLocation(this)) {
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} else {
handleNewLocation(location);
}
} else {
this.bundle = bundle;
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location) {
handleNewLocation(location);
}
private void handleNewLocation(Location location) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions options = new MarkerOptions().position(latLng).title("I am here!");
mMap.addMarker(options);
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (requestCode == Functions.Permissions.MY_PERMISSIONS_FINE_LOCATION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onConnected(bundle);
}
}
}
}
I have a route tracking app that uses GoogleMaps and Location Services. And everything worked fine until yesterday that my app crash every time with a NullPointerException and i don't know why, i haven't changed anything in the code.
Here's the code:
package com.example.rocketron.mapa.Activities;
import android.location.Location;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.rocketron.mapa.R;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends AppCompatActivity implements ConnectionCallbacks,
OnConnectionFailedListener, LocationListener, OnMapReadyCallback {
protected static final String TAG = "location-updates-sample";
// 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";
//UI Elements
protected Toolbar toolbar;
protected FloatingActionButton fab;
protected GoogleMap googleMap;
protected MapView mapView;
//Provides the entry point to Google Play services.
protected GoogleApiClient mGoogleApiClient;
//Stores parameters for requests to the FusedLocationProviderApi.
protected LocationRequest mLocationRequest;
//Represents a geographical location.
protected Location mCurrentLocation;
//Tracks the status of the location updates request. Value changes when the user presses the
//Start Updates and Stop Updates button.
protected boolean mRequestingLocationUpdates;
protected double latitude;
protected double longitude;
protected LatLng mLatLng;
protected CameraUpdate cameraUpdate;
Marker currentMarker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.appbar);
setSupportActionBar(toolbar);
fab = (FloatingActionButton) findViewById(R.id.fab);
mapView = (MapView) findViewById(R.id.mi_mapa);
mapView.getMapAsync(this);
mapView.onCreate(savedInstanceState);
mRequestingLocationUpdates = false;
updateValuesFromBundle(savedInstanceState);
buildGoogleApiClient();
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
togglePeriodicLocationUpdates();
}
});
}
#Override
public void onMapReady(GoogleMap map) {
googleMap = map;
googleMap.getUiSettings().setMapToolbarEnabled(false); //Hide Map Toolbar when marker is clicked
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onResume() {
super.onResume();
mapView.onResume();
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
protected void onPause() {
super.onPause();
mapView.onPause();
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
}
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
/**
* Updates fields based on data stored in the bundle.
*
* #param savedInstanceState The activity state saved in the Bundle.
*/
private void updateValuesFromBundle(Bundle savedInstanceState) {
Log.i(TAG, "Updating values from bundle");
if (savedInstanceState != null) {
// Update the value of mRequestingLocationUpdates from the Bundle, and make sure that
// the Start Updates and Stop Updates buttons are correctly enabled or disabled.
if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
mRequestingLocationUpdates = savedInstanceState.getBoolean(
REQUESTING_LOCATION_UPDATES_KEY);
setFabEnabledState();
}
// 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();
}
}
/*------------- Build Google API Client ----------------*/
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
/*------------- Set Up a Location Request -----------------*/
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void updateUI() {
if (currentMarker != null)
currentMarker.remove();
latitude = mCurrentLocation.getLatitude();
longitude = mCurrentLocation.getLongitude();
mLatLng = new LatLng(latitude, longitude);
cameraUpdate = CameraUpdateFactory.newLatLng(mLatLng);
googleMap.moveCamera(cameraUpdate);
currentMarker = googleMap.addMarker(new MarkerOptions()
.position(mLatLng)
.title(String.format("%f, %f", latitude, longitude))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
}
private void togglePeriodicLocationUpdates() {
if (!mRequestingLocationUpdates) {
// Changing the fab button
mRequestingLocationUpdates = true;
setFabEnabledState();
getSupportActionBar().hide();
// Starting the location updates
startLocationUpdates();
} else {
// Changing the fab button
mRequestingLocationUpdates = false;
setFabEnabledState();
getSupportActionBar().show();
// Stopping the location updates
stopLocationUpdates();
}
}
private void setFabEnabledState() {
if (mRequestingLocationUpdates) {
fab.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_stop_white_24dp));
} else {
fab.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_play_arrow_white_24dp));
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
/*-------------Override Methods from ConnectionCallbacks, OnConnectionFailedListener-------------*/
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected to GoogleApiClient");
if (mCurrentLocation == null) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
updateUI();
}
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
public void onConnectionSuspended(int i) {
// 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 connectionResult) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
/*----------------Override Methods from LocationListener ----------------------*/
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
updateUI();
Toast.makeText(this, getResources().getString(R.string.location_updated_message), Toast.LENGTH_SHORT).show();
}
/*------------------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);
}
/*----------------Toolbar Methods---------------*/
#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);
}
}
And the error:
02-15 07:02:47.675 13898-13898/com.example.rocketron.mapa
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.rocketron.mapa.Activities.MainActivity.updateUI(MainActivity.java:187)
at com.example.rocketron.mapa.Activities.MainActivity.onConnected(MainActivity.java:244)
at com.google.android.gms.common.internal.zzk.zzk(Unknown Source)
at com.google.android.gms.internal.zzmg.zzi(Unknown Source)
at com.google.android.gms.internal.zzme.zzpi(Unknown Source)
at com.google.android.gms.internal.zzme.onConnected(Unknown Source)
at com.google.android.gms.internal.zzmi.onConnected(Unknown Source)
at com.google.android.gms.internal.zzlz.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzj$zzg.zzqv(Unknown Source)
at com.google.android.gms.common.internal.zzj$zza.zzc(Unknown Source)
at com.google.android.gms.common.internal.zzj$zza.zzv(Unknown Source)
at com.google.android.gms.common.internal.zzj$zzc.zzqx(Unknown Source)
at com.google.android.gms.common.internal.zzj$zzb.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
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:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)
It looks like your mCurrentLocation is null. This line is the problem mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);. The getLastLocation does not get the last known location. You may want to look at this thread for a possible solution.
The fused location provider will only maintain background location if at least one client is connected to it. Now just turning on the location service will not gurranty to store the last known location.
Once the first client connects, it will immediately try to get a location. If your activity is the first client to connect and getLastLocation() is invoked right away in onConnected(), that might not be enough time for the first location to arrive..
Then you are setting mLocationRequest.setFastestInterval(30000); which basically means 30 seconds. so at least 30 seconds after and generally according to your setting preferred time is 120 secs, isn't it a very long time if there is no stored last known location at all? plus you are setting battery balanced priority, which will make you waiting longer time.
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
I suggest you to launch Maps app first, so that there is at least some confirmed location and then test your app.
Also, double check if you have your GPS enabled. You may put a checker whether your GPS is on/off. See this thread.
I'm unable to get a Location on my Android Wear Emulator. I've tried many tutorials but non worked and I don't understand whats wrong. Below is my sample source Code which is pretty similar to the original Android Demo from google.
onLocationChanged never gets executed and when I try to retrieve the last Location I alway got NULL
import android.app.Activity;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.view.View;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.wearable.Wearable;
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private TextView mTextView;
private static final long UPDATE_INTERVAL_MS = 2000;
private static final long FASTEST_INTERVAL_MS = 1000;
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
System.out.println("Connect to Playservices...");
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
System.out.println("onConnected");
LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL_MS)
.setFastestInterval(FASTEST_INTERVAL_MS);
LocationServices.FusedLocationApi
.requestLocationUpdates(mGoogleApiClient, locationRequest, this)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.getStatus().isSuccess()) {
System.out.println("Successfully requested location updates"+status.getStatusMessage());
} else {
System.out.println(
"Failed in requesting location updates, "
+ "status code: "
+ status.getStatusCode() + ", message: " + status
.getStatusMessage());
}
}
});
}
public void getLocation(View view)
{
Location loc=LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(loc!=null) {
System.out.println("Location: " + loc.getAltitude() + "\n" + loc.getProvider() + "\n" + loc.getLongitude());
}
else
{
System.out.println("Location null");
}
}
#Override
public void onConnectionSuspended(int i) {
System.out.println("onConnectionSuspended(): connection to location client suspended");
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
System.out.println("onConnectionFailed(): connection to location client failed");
}
#Override
public void onLocationChanged (Location location)
{
System.out.println("onLocationchanged: new location"+location.getAltitude());
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
mGoogleApiClient.disconnect();
System.out.println("onstop");
}
#Override
protected void onResume() {
super.onResume();
mGoogleApiClient.connect();
System.out.println("onresume");
}
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi
.removeLocationUpdates(mGoogleApiClient, this);
}
mGoogleApiClient.disconnect();
System.out.println("onPause");
}
}