onLocationChanged never called , GoogleApiClient - android

I am trying to get continuous location updates by running a background service. While I debug the code onConnected(Bundle b) is called and location update request is called. But onLocationChanged(Location location) is never called. Below is my code:
public class LocationUpdateService extends Service implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleApiClient googleApiClient;
private LocationRequest mLocationRequest;
Location mCurrentLocation;
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
double lat = mCurrentLocation.getLatitude();
double lng = mCurrentLocation.getLongitude();
}
//GoogleApiClient
#Override
public void onConnectionFailed(ConnectionResult bundle) {
}
#Override
public void onConnected(Bundle bundle) {
Log.i("onConnected", "GoogleApiClient");
Toast.makeText(this, "Location service connected", Toast.LENGTH_SHORT).show();
createLocationRequest();
startLocationUpdate();
}
#Override
public void onConnectionSuspended(int i) {
}
//Service
#Override
public void onCreate() {
super.onCreate();
buildGoogleApiClient();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY; // run until explicitly stopped.
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void startLocationUpdate() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
googleApiClient, mLocationRequest, this);
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
}
void buildGoogleApiClient() {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
void createLocationRequest() {
mLocationRequest = new LocationRequest().create()
.setInterval(5000)
.setFastestInterval(5000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
}
I can't understand where I am making mistake, while I have followed android docs. I am testing on real device and app has location permissions.
service in menifest:
<service
android:name=".locations.LocationUpdateService"
android:enabled="true"
android:exported="false"></service>
Call of service in activity:
startService(new Intent(BaseActivity.this, LocationUpdateService.class));

What is your android phone SDK and how are you asking for the permissions on the manifest file?
If your phone SDK is 23 or higher the way you ask for permissions is different.

It was just a stupid debugging issue. I found my device location Access was off in advance settings.

Related

Can not get accurate location while travelling in bus without internet

I am developing offline car tracker android application. It will update location after 5 min and stores it in SQLite.I used FusedLocationAPI but can not get accurate location while travelling in bus without Internet. I am getting accuracy 999m and getting same location after every 5 minutes.
I set alarm manager to 5 minutes.
public static void startAlarmManager(Context context)
{
preferences =context.getSharedPreferences(Constant.SHARED_PREF_NAME, Context.MODE_PRIVATE);
int duration= Integer.parseInt(preferences.getString(Constant.DURATION_SHARED_PREF,Constant.CONSTANT_DURATION_SHARED_PREF));
Log.d("duration",duration+"");
alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
gpsTrackerIntent = new Intent(context, GpsTrackerAlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(context, 0, gpsTrackerIntent, 0);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(),
5*60000,
pendingIntent);
}
It will fire broadcast receiver.
public class GpsTrackerAlarmReceiver extends WakefulBroadcastReceiver {
private static final String TAG = "GpsTrackerAlarmReceiver";
#Override
public void onReceive(Context context, Intent intent) {
LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE );
boolean statusOfGPS = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(statusOfGPS) {
context.startService(new Intent(context, LocationService.class));
}
}
}
This is location service. I am getting location with this way.
public class LocationService extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG = "LocationService";
public static GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
public Context context;
private DatabaseHelper db;
private boolean currentlyProcessingLocation = false;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
if (!currentlyProcessingLocation) {
currentlyProcessingLocation = true;
startTracking();
}
return START_NOT_STICKY;
}
private void startTracking() {
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) {
googleApiClient.connect();
}
} else {
Log.e(TAG, "unable to connect to google play services.");
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG, "onConnected");
locationRequest = LocationRequest.create();
locationRequest.setInterval(1000); // milliseconds
locationRequest.setFastestInterval(1000); // the fastest rate in milliseconds at which your app can handle location updates
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
googleApiClient, locationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "GoogleApiClient connection has been suspend");
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged");
startupdate(location);
}
private void startupdate(Location location) {
if (location != null) {
db=new DatabaseHelper(this);
db.insertLocation(location.getLatitude(), location.getLongitude(), "FusedApi Provider", location.getAccuracy());
stopLocationUpdates();
stopSelf();
}
}
public void stopLocationUpdates() {
if (googleApiClient != null && googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed");
stopLocationUpdates();
stopSelf();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Please help...if i am wrong. Thanks in advance.
When GPS is not practical you can use LocationManager.NETWORK_PROVIDER, this is location from the phone carrier that is less accurate than GPS but is available everywhere the carrier has a tower. The way I do it is a set a flag isGpsAvailable() to see if that is true I use GPS otherwise I use network provided location. This Google's doc provides detailed solutions including code snippets that you can use and change the way you it fits your needs.

get location using GoogleAPIClient in Service

I want to get location in background so that I can fetch location from any activity/fragment. problem is I'm not getting the latitude and longitude in Service. Is there something I'm doing wrong here?
public class LocationService extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG = "sammy_";
private boolean currentlyProcessingLocation = false;
private LocationRequest locationRequest;
private Location mCurrentLocation;
private GoogleApiClient googleApiClient;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTracking();
return START_NOT_STICKY;
}
private void startTracking() {
Log.d(TAG, "startTracking");
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
System.out.println("Current LAT: "+mCurrentLocation.getLatitude()+ " Current LANG: "+mCurrentLocation.getLongitude());
}
private void stopLocationUpdates() {
if (googleApiClient != null && googleApiClient.isConnected()) {
googleApiClient.disconnect();
}
}
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected");
locationRequest = LocationRequest.create();
locationRequest.setInterval(1000);
locationRequest.setFastestInterval(1000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
/*if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}*/
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed");
stopLocationUpdates();
stopSelf();
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "GoogleApiClient connection has been suspend");
}
}
Take a look at Using GoogleApiClient in a service
It looks like you need to connect to the Google API (and should also move GoogleApi code to onCreate() ).

Getting Incorrect current GPS location in FusedLocationProviderApi

I have following LocationService.java service class.
public class LocationService extends Service
implements LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final long INTERVAL = 1000 * 60;
private static final long FASTEST_INTERVAL = 1000 * 5;
Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
String lat, lon;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mGoogleApiClient.connect();
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
lat = String.valueOf(mLastLocation.getLatitude());
lon = String.valueOf(mLastLocation.getLongitude());
Util.WriteSharePrefrence(getApplicationContext(), "track_lat", "" + lat);
Util.WriteSharePrefrence(getApplicationContext(), "track_lng", "" + lon);
}
}
#Override
public void onCreate() {
int permissionCheck = ContextCompat.checkSelfPermission(LocationService.this, Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
//Execute location service call if user has explicitly granted ACCESS_FINE_LOCATION..
buildGoogleApiClient();
}
}
#Override
public void onConnectionSuspended(int i) {
}
synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
Util.WriteSharePrefrence(getApplicationContext(), "track_lat", "" + location.getLatitude());
Util.WriteSharePrefrence(getApplicationContext(), "track_lng", "" + location.getLongitude());
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
buildGoogleApiClient();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
In the above location service what I am doing is.
1. Set fastest interval to refresh the location every 5 sec.
2. Once location availabe onLocationChanged() will be take place. Inside onLocationChanged() method I am writing current latitude and longitude in the shared preference.
3. This service will be running 24 hours in the background to get current location.
I have Mentioned both location condition in my manifest like below:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
My Issue is :
Some times onLocationChanged() method taking wrong latitude longitude
for example : user device in India and it taking USA address. The device version is Xolo - 4.2.1.(India)
Is it device specific issue? Or something I need to change in my code?
What should I do to make my location service better ?
Use Network or GPS providers or Passive if you want
public void Request_LocationUpdate(String type)
{
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}, 12);
}
else
{
LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
switch (type)
{
case "Passive":
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,10000,10,locationListener);
break;
case "GPS":
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,10000,10,locationListener);
break;
case "Network":
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,10000,10,locationListener);
break;
}
}
}

Update google map using location service

I have a LocationService that gets the user location in the background and sends a broadcast to an activity with the Latitude and Longitude.
It is the code found in the accepted answer to this question Background service with location listener in android
I created the project with the Google Maps Activity provided by Android Studio. In the MapsActivity I get the broadcast extras like this
public class newMessage extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase(LocationService.BROADCAST_ACTION)) {
Bundle extra = intent.getExtras();
latitude = extra.getDouble("Latitude");
longitude = extra.getDouble("Longitude");
System.out.println("Latitude: "+latitude);
System.out.println("Longitude: "+longitude);
LatLng newLocation = new LatLng(latitude,longitude);
}
}
}
I now want to update the map with the new location but I have no idea how to do this. Is it possible with my current setup?
declare Broadcast receiver in activity and show marker to current location
public BroadcastReceiver locationUpdateReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
//show current location marker
mMap.addMarker(new MarkerOptions().position(/*your lat long*/).title("My Location")));
}
};
You need to create a locationService where you can obtain your current location. Check this example:
public class LocationService extends Service implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = LocationService.class.getSimpleName();
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
protected Location mCurrentLocation;
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
buildGoogleApiClient();
mGoogleApiClient.connect();
return START_NOT_STICKY;
}
#Override
public void onConnected(Bundle bundle) {
Log.i("fixedrec", TAG + ">Connected to GoogleApiClient");
if (mCurrentLocation == null) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
}
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onDestroy() {
super.onDestroy();
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
Log.d("fixedrec", TAG+ ">StoppingService");
mNM.cancel(NOTIFICATION);
stopForeground(true);
}
#Override
public void onLocationChanged(Location location) {
//plase where you get your locations
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("fixedrec", TAG + "> Connection failed: ConnectionResult.getErrorCode() = "
+ connectionResult.getErrorCode());
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.i("fixedrec", TAG + "> StartLocationUpdates");
}
protected synchronized void buildGoogleApiClient() {
Log.i("fixedrec", TAG + "> Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
}
To broadcast you location across application you can use BroadCastReceiver or EventBus like Otto.
Then just create a googleMap and add a marker with obtained location to it.
Don't forget yo write locationPermissions inside your manifest file and inside your code if you are dealing with SDK >=23
Also you can study this project. Fixedrec3
Everything you need is there.

Google api client disconnect when the app destroyed

In my project i create background service which is get location using google api client.
my problem is when app destroyed,service is running but google api client automatically disconnected and cannot get lat-lang. i don't want lost a connection.
This is my service class code
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
String lat, lon;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}else{
mGoogleApiClient.connect();
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(100); // Update location every second
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
lat = String.valueOf(mLastLocation.getLatitude());
lon = String.valueOf(mLastLocation.getLongitude());
}
updateUI();
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
lat = String.valueOf(location.getLatitude());
lon = String.valueOf(location.getLongitude());
updateUI();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
buildGoogleApiClient();
}
synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
//setUpLocationClientIfNeeded();
if(!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting())
{
mGoogleApiClient.connect();
}
return START_STICKY;
}
void updateUI() {
Log.d("LatLongGPS", lat + "==========" + lon);
Toast.makeText(getApplicationContext(), "Service"+lat + "==========" + lon, Toast.LENGTH_LONG).show();
}
}

Categories

Resources