onConnected() not being called to get location updates (GooglePlayApi for location) - android

So i have this code:
package com.entu.bocterapp;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class LocationManager implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private Context mContext;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private LocationRequest mLocationRequest;
public LocationManager(Context context) {
mContext = context;
//
if (checkIfGooglePlayServicesAreAvailable()) {
//Get Access to the google service api
buildGoogleApiClient();
mGoogleApiClient.connect();
} else {
//Use Android Location Services
//TODO:
}
}
public Location getCoarseLocation() {
if (mLastLocation != null) {
return mLastLocation;
} else return null;
}
private synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private boolean checkIfGooglePlayServicesAreAvailable() {
int errorCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext);
if (errorCode != ConnectionResult.SUCCESS) {
GooglePlayServicesUtil.getErrorDialog(errorCode, (RecentSightings) mContext, 0).show();
return false;
}
return true;
}
#Override
public void onConnected(Bundle bundle) {
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location != null) {
mLastLocation = location;
Toast.makeText(mContext, location.getLongitude() + " , " + location.getLatitude() + " : " + location.getAccuracy(), Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnectionSuspended(int i) {
Toast.makeText(mContext, "suspended", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
I am trying to get location in this class, but onConnected() never gets called(i waited for 1-2 minutes). I went with the debugger, it says google play services are available.
Does anyone know what i'm doing wrong? I'm stuck here for hours, reading everything, and can't get it to work.
Cheers!

You must call
mGoogleApiClient.connect();

try this:
#Override
protected void onStart() {
if(mGoogleApiClient!=null){
mGoogleApiClient.connect();
}
super.onStart();
}
#Override
protected void onStop() {
if(mGoogleApiClient!=null){
if(mGoogleApiClient.isConnected()){
mGoogleApiClient.disconnect();
}
}
super.onStop();
}

I got the same problem just updated my grade version :10.0.1' to
compile 'com.google.android.gms:play-services-location:10.2.1'
it works.

Related

How to run geofencing app in background?

I am creating a attendance monitoring app for my campus using geofencing api.Everything else is working smoothly, but I want my app to work in the background.(Similar to a music player). Currently, it works only when the app is open. Here is the Service class code I have used:
package com.app.androidkt.geofencing;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class BackgroundService extends Service{
MainActivity main;
public int onStartCommand(Intent intent, int flags, int startId) {
main.isMonitoring = true;
main.startGeofencing();
main.startLocationMonitor();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
//use this method to communicate with your activity
return null;
}
}
And here is the MainActivity.java:
package com.app.androidkt.geofencing;
import android.Manifest;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
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.Geofence;
import com.google.android.gms.location.GeofencingRequest;
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.Circle;
import com.google.android.gms.maps.model.CircleOptions;
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
OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener{
private static final String TAG = "MainActivity";
private static final int REQUEST_LOCATION_PERMISSION_CODE = 101;
private GoogleMap googleMap;
private GeofencingRequest geofencingRequest;
public GoogleApiClient googleApiClient;
public boolean isMonitoring = false;
private MarkerOptions markerOptions;
private Marker currentLocationMarker;
private PendingIntent pendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION_PERMISSION_CODE);
}
}
public void startLocationMonitor() {
Log.d(TAG, "start location monitor");
LocationRequest locationRequest = LocationRequest.create()
.setInterval(2000)
.setFastestInterval(1000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
try {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
if (currentLocationMarker != null) {
currentLocationMarker.remove();
}
markerOptions = new MarkerOptions();
markerOptions.position(new LatLng(location.getLatitude(), location.getLongitude()));
markerOptions.title("Current Location");
currentLocationMarker = googleMap.addMarker(markerOptions);
Log.d(TAG, "Location Change Lat Lng " + location.getLatitude() + " " + location.getLongitude());
}
});
} catch (SecurityException e) {
Log.d(TAG, e.getMessage());
}
}
public void startGeofencing() {
Log.d(TAG, "Start geofencing monitoring call");
pendingIntent = getGeofencePendingIntent();
geofencingRequest = new GeofencingRequest.Builder()
.setInitialTrigger(Geofence.GEOFENCE_TRANSITION_ENTER)
.addGeofence(getGeofence())
.build();
if (!googleApiClient.isConnected()) {
Log.d(TAG, "Google API client not connected");
} else {
try {
LocationServices.GeofencingApi.addGeofences(googleApiClient, geofencingRequest, pendingIntent).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.d(TAG, "Successfully Geofencing Connected");
} else {
Log.d(TAG, "Failed to add Geofencing " + status.getStatus());
}
}
});
} catch (SecurityException e) {
Log.d(TAG, e.getMessage());
}
}
isMonitoring = true;
invalidateOptionsMenu();
}
#NonNull
public Geofence getGeofence() {
LatLng latLng = Constants.AREA_LANDMARKS.get(Constants.GEOFENCE_ID_STAN_UNI);
return new Geofence.Builder()
.setRequestId(Constants.GEOFENCE_ID_STAN_UNI)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setCircularRegion(latLng.latitude, latLng.longitude, Constants.GEOFENCE_RADIUS_IN_METERS)
.setNotificationResponsiveness(1000)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
}
public PendingIntent getGeofencePendingIntent() {
if (pendingIntent != null) {
return pendingIntent;
}
Intent intent = new Intent(this, GeofenceRegistrationService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.
FLAG_UPDATE_CURRENT);
}
private void stopGeoFencing() {
pendingIntent = getGeofencePendingIntent();
LocationServices.GeofencingApi.removeGeofences(googleApiClient, pendingIntent)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess())
Log.d(TAG, "Stop geofencing");
else
Log.d(TAG, "Not stop geofencing");
}
});
isMonitoring = false;
invalidateOptionsMenu();
}
#Override
protected void onResume() {
super.onResume();
int response = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(MainActivity.this);
if (response != ConnectionResult.SUCCESS) {
Log.d(TAG, "Google Play Service Not Available");
GoogleApiAvailability.getInstance().getErrorDialog(MainActivity.this, response, 1).show();
} else {
Log.d(TAG, "Google play service available");
}
}
#Override
protected void onStart() {
super.onStart();
googleApiClient.reconnect();
}
#Override
protected void onStop() {
super.onStop();
googleApiClient.disconnect();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.manu_map_activity, menu);
if (isMonitoring) {
menu.findItem(R.id.action_start_monitor).setVisible(false);
menu.findItem(R.id.action_stop_monitor).setVisible(true);
menu.findItem(R.id.startservice).setVisible(true);
} else {
menu.findItem(R.id.action_start_monitor).setVisible(true);
menu.findItem(R.id.action_stop_monitor).setVisible(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_start_monitor:
startGeofencing();
break;
case R.id.action_stop_monitor:
stopGeoFencing();
break;
case R.id.startservice:
startService(new Intent(this, BackgroundService.class));
break;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
public void onMapReady(GoogleMap googleMap) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
this.googleMap = googleMap;
LatLng latLng = Constants.AREA_LANDMARKS.get(Constants.GEOFENCE_ID_STAN_UNI);
googleMap.addMarker(new MarkerOptions().position(latLng).title("Stanford University"));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17f));
googleMap.setMyLocationEnabled(true);
Circle circle = googleMap.addCircle(new CircleOptions()
.center(new LatLng(latLng.latitude, latLng.longitude))
.radius(Constants.GEOFENCE_RADIUS_IN_METERS)
.strokeColor(Color.RED)
.strokeWidth(4f));
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG, "Google Api Client Connected");
isMonitoring = true;
startGeofencing();
startLocationMonitor();
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "Google Connection Suspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
isMonitoring = false;
Log.e(TAG, "Connection Failed:" + connectionResult.getErrorMessage());
}
}
When I try to run the app in background by clicking the background option i have provided in the app, the app crashes and i get a runtime error saying:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.app.androidkt.geofencing, PID: 24176
java.lang.RuntimeException: Unable to start service com.app.androidkt.geofencing.BackgroundService#52135c5 with Intent { cmp=com.app.androidkt.geofencing/.BackgroundService }: java.lang.NullPointerException: Attempt to write to field 'boolean com.app.androidkt.geofencing.MainActivity.isMonitoring' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3335)
at android.app.ActivityThread.-wrap21(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1578)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
Caused by: java.lang.NullPointerException: Attempt to write to field 'boolean com.app.androidkt.geofencing.MainActivity.isMonitoring' on a null object reference
at com.app.androidkt.geofencing.BackgroundService.onStartCommand(BackgroundService.java:13)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3318)
at android.app.ActivityThread.-wrap21(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1578) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6123) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 
Please suggest me changes in my code.
MainActivity main;
is not initialized in your BackgroundService.
Try to implement the interface instead accessing the Activity's method like this.
Check this answer to implement the interface.

Fused Location always returns null

I am using Fused Location to get current location of my device, but the code that I have implemented always return NULL. I have double checked that my device Location is ON and is set to High Accuracy Mode. Please tell what is problem in my code?
My Code:
import android.app.Activity;
import android.content.Context;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
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.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStatusCodes;
public class FusedLocationTest implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static Location mLastLocation;
private static GoogleApiClient mGoogleApiClient;
private static Context context;
public Location getCurrentLocation(Context context) {
this.context = context;
buildGoogleApiClient();
mGoogleApiClient.connect();
if ((ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
}
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
return mLastLocation;
}
/*connect to fused location provider*/
synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
buildGoogleApiClient();
}
#Override
public void onConnectionSuspended(int i) {
}
}
Call on button Click:
#Override
public void onClick(View v) {
Location l = new FusedLocationTest().getCurrentLocation(this);
if(l!=null)
Toast.makeText(this,l.getLatitude()+", "+l.getLongitude(), Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"NULL LOCATION", Toast.LENGTH_LONG).show();
}
Add this code to your onConnected, thats where it would get Last Known Location.
private static Location mLastLocation;
private static GoogleApiClient mGoogleApiClient;
private static Context context;
// added
private LocationRequest mLocationRequest;
private Double latitude;
private Double longitude;
private String TAG = ""; // set your TAG
#Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
startLocationUpdates();
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation == null){
startLocationUpdates();
}
if (mLastLocation != null) {
latitude = mLocation.getLatitude();
longitude = mLocation.getLongitude();
// set your tag
Log.d(TAG, String.valueOf(latitude));
Log.d(TAG, String.valueOf(longitude));
} else {
Toast.makeText(context, "Location not Detected, Did you turn off your location?", Toast.LENGTH_SHORT).show();
}
}
protected void startLocationUpdates() {
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(30 * 1000)
.setFastestInterval(5 * 1000);
// Request location updates
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
And remove synchronized from your method, Just make it public. Something like this below:
public void buildGoogleApiClient() { }
The mGoogleApiClient.connect() function is asynchronous. You have to wait until onConnected until the last location is available. There is a clear example of this in the documentation.

unable to get current location using FusedLocationApi without Gps

I am trying to get users current location using FusedLocationApi using the following code. I am following the guide provided here: https://developer.android.com/training/location/retrieve-current.html
I have tried this so far:
package com.abhishek.locationawareapp;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
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 MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
protected void createLocationRequest(){
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("Main Activity: ","onCreate");
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();//.addApi(LocationServices.class)
}
//For Location Request
/*LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);*/
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
Log.d("Main Activity: ","onStart");
super.onStart();
}
#Override
protected void onStop() {
Log.d("Main Activity: ","onStop");
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d("Main Activity: ","onConnected");
if(Build.VERSION.SDK_INT >=23){
checkLocationPermission();
}else{
locationPermission = true;
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation !=null){
String mLatitudeText = String.valueOf(mLastLocation.getLatitude());
String mLongitudeText = String.valueOf(mLastLocation.getLongitude());
Log.d("Location: ","mLatitudeText: "+ mLatitudeText +" mLongitudeText: "+ mLongitudeText);
}
}
}
boolean locationPermission = false;
final static int LOC_REQ_CODE = 100;
private void checkLocationPermission(){
int locationPermissionCheck = ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION);
if(locationPermissionCheck == PackageManager.PERMISSION_GRANTED){
locationPermission = true;
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation !=null){
String mLatitudeText = String.valueOf(mLastLocation.getLatitude());
String mLongitudeText = String.valueOf(mLastLocation.getLongitude());
Log.d("Location: ","mLatitudeText: "+ mLatitudeText +" mLongitudeText: "+ mLongitudeText);
}
}else{
locationPermission = false;
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOC_REQ_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case LOC_REQ_CODE:
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
locationPermission = true;
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLastLocation !=null){
String mLatitudeText = String.valueOf(mLastLocation.getLatitude());
String mLongitudeText = String.valueOf(mLastLocation.getLongitude());
Log.d("Location: ","mLatitudeText: "+ mLatitudeText +" mLongitudeText: "+ mLongitudeText);
}
}else{
final Snackbar snackBar = Snackbar.make(findViewById(R.id.rl_layout), "Location access is required to get last location.",
Snackbar.LENGTH_INDEFINITE);
snackBar.setAction("Dismiss", new View.OnClickListener() {
#Override
public void onClick(View v) {
checkLocationPermission();
snackBar.dismiss();
}
});
snackBar.show();
}
break;
}
}
#Override
public void onConnectionSuspended(int i) {
Log.d("Main Activity: ","onConnectionSuspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d("Main Activity: ","onConnectionFailed");
}
}
I got the location with gps enabled but once i disable gps, mLastLocation
always returns null. Isn't it possible to get location from FusedLocationApi without using Gps? Please help!!

Requesting permission at run time - Android

I was trying to create one demo app using Google Play services location. It's working fine in my mobile phone but it shows the location for short period of time. However, the emulator didn't display any location. Any suggestion is appreciated..
The current version of my Emulator - 6.0 and targetSdkVersion 24
Here is the MainActivity Code
package com.example.android.mylocation;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
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 java.io.IOException;
import java.util.jar.Manifest;
import android.Manifest.permission;
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener{
private final String LOG_TAG = "MyLocation";
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private TextView mTextView;
public static final int MY_PERMISSION_REQUEST_LOCATION = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/** Create Google Api Client */
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Log.v(LOG_TAG, "Google Api Client Created");
mTextView = (TextView) findViewById(R.id.location);
}
/** This method will connect the Google Api Client */
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
Log.v(LOG_TAG, "Connect the Google Play Services");
}
/** This method will disconnect the Google Api Client */
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.v(LOG_TAG, "Google Play Services Connected");
try{
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
Log.v(LOG_TAG, "Priority High Accuracy");
mLocationRequest.setInterval(5000);
/** Request the permissions you need */
if (ContextCompat.checkSelfPermission(this, permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
Log.v(LOG_TAG, "Self Permission is not Granted");
//Request the permission
ActivityCompat.requestPermissions(this, new String[] {permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_REQUEST_LOCATION);
}
}
catch(Exception e){
Log.v(LOG_TAG, e.toString());
}
/* try {
//mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
catch(SecurityException e){
Log.v(LOG_TAG, e.toString());
}*/
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
Log.v(LOG_TAG, "User permission");
switch (requestCode) {
case MY_PERMISSION_REQUEST_LOCATION: {
Log.v(LOG_TAG, "Check the User Response");
//If request is cancelled, the request arrays are empty
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
try {
Log.v(LOG_TAG, "Check the user location");
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
//mTextView.setText(location.toString());
}
catch(SecurityException e){
Log.v(LOG_TAG, e.toString());
}
}
else {
Log.v(LOG_TAG, "Permission denied");
}
return;
}
}
}
#Override
public void onConnectionSuspended(int i) {
/*if (!mGoogleApiClient.isConnected()){
mGoogleApiClient.connect();
}*/
Log.v(LOG_TAG, "Connection Suspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.v(LOG_TAG, connectionResult.getErrorMessage());
}
#Override
public void onLocationChanged(Location location) {
Log.v(LOG_TAG, "Location Change Detected");
mTextView.setText(location.toString());
}
}

Using LocationServices.FusedLocationApi.requestLocationUpdates in an Android background service...onLocationChanged never called

I've searched for days and days and somehow the answer to why onLocationChanged isn't being called has eluded me. I've read the documentation extensively and I MUST be missing something crucial. I simply want a service that runs in the background, when location has changed, I want to log the location.
Here's my service...
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.annotation.Nullable;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
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;
public class BackgroundLocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private final String TAG = ((Object) this).getClass().getSimpleName();
IBinder mBinder = new LocalBinder();
GoogleApiAvailability googleAPI;
PowerManager.WakeLock mWakeLock;
private boolean mInProgress;
private Boolean servicesAvailable = false;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
private Intent mIntentService;
private PendingIntent mPendingIntent;
public class LocalBinder extends Binder {
public BackgroundLocationService getServerInstance() {
return BackgroundLocationService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
googleAPI = GoogleApiAvailability.getInstance();
mInProgress = false;
mIntentService = new Intent(this,BackgroundLocationService.class);
mPendingIntent = PendingIntent.getService(this, 1, mIntentService, PendingIntent.FLAG_UPDATE_CURRENT);
servicesAvailable = servicesConnected();
/*
* Create a new google api client, using the enclosing class to handle callbacks.
*/
buildGoogleApiClient();
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = googleAPI.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
return true;
} else {
return false;
}
}
protected void startLocationUpdates() {
Log.i(TAG, "Started Location Updates");
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
}
protected void stopLocationUpdates() {
Log.i(TAG,"Stopped Location Updates");
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
}
protected void createLocationRequest() {
Log.i(TAG, "createLocationRequest()");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(1000);
//mLocationRequest.setMaxWaitTime(10000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
PowerManager mgr = (PowerManager) getSystemService(Context.POWER_SERVICE); //*** added this
if (this.mWakeLock == null) {
mWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "aWakeLock"); //*** added this
}
if (!this.mWakeLock.isHeld()) {
mWakeLock.acquire(); //*** added this
}
if (!servicesAvailable || mGoogleApiClient.isConnected() || mInProgress)
return START_STICKY;
if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting() && !mInProgress) {
Log.e(TAG, "Location Client not connected, connecting...");
mInProgress = true;
mGoogleApiClient.connect();
}
Log.e(TAG, "Location Client: onStartCommand");
return START_STICKY;
}
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
if (mGoogleApiClient == null) {
this.mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
createLocationRequest();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onDestroy() {
// Turn off the request flag
this.mInProgress = false;
if (this.mWakeLock != null) {
this.mWakeLock.release();
this.mWakeLock = null;
}
Log.e(TAG, "Location Client: ON DESTROY");
super.onDestroy();
stopLocationUpdates();
}
#Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
Log.e(TAG, "Location Receiver [Location Changed]: " + location.getLatitude() + ", " + location.getLongitude());
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "Location Client: ON CONNECTED");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
mInProgress = false;
Log.e(TAG, "Location Client: ON CONNECTION FAILED");
if (connectionResult.hasResolution()) {
// If no resolution is available, display an error dialog
} else {
}
}
}
I'm starting the service like this...
Intent BackgroundLocationService = new Intent(this, BackgroundLocationService.class);
startService(BackgroundLocationService);
I have the following permission in the manifest as well...
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
The requestLocationUpdates uses a pendingintent currently which is fired to start the service again. This is not calling the OnLocationchanged callback. Try using the requestLocationUpdates with location listener (3rd parameter). It should call OnLocationchanged.

Categories

Resources