Panduka Wedisinghe
Panduka Wedisinghe

Reputation: 153

FusedLocationApi returns null

I am developing and android application which has a broadcast receiver to broadcast incoming sms from a certain number. If the message is from that number and is in a specific format, application replies with the current Longitude and Latitude of the user.

But when the reply message is generated, location becomes null always.I am using GoogleApiClient object and FusedLocationApi.

mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleAPIClient);

always returns null and my message contains null values in places of Longitude and Latitude. Here is the Service which is called by the broadcast receiver when a message comes in asking for the location.

public class ReplyWithLocationService extends Service implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedList, LocationListener{

private BroadcastReceiver senderBroadcastReceiver, deliverBroadcastReceiver;
private String SENT = "SMS_SENT";
private String DELIVERED = "SMS_DELIVERED";
private String latitude, longitude;
private LocationRequest locationRequest;
private LocationManager locationManager;
private ConnectivityManager connectivityManager;
private GoogleApiClient googleAPIClient;
private boolean isConnected;
private Location mLastLocation;
private NetworkInfo activeNetwork;
private boolean isConnectedInternet;
private boolean connectivity = true;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();

    setUpGoogleAPIClient();
    setUpLocationRequest();
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);

    senderBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "SMS Sent", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show();
                    break;
            }

        }
    };

    deliverBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "SMS Delivered", Toast.LENGTH_SHORT).show();
                    break;
                case Activity.RESULT_CANCELED:
                    Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };

    registerReceiver(senderBroadcastReceiver, new IntentFilter(SENT));
    registerReceiver(deliverBroadcastReceiver, new IntentFilter(DELIVERED));

    //setUpGoogleAPIClient();
    //setUpLocationRequest();
}

private void setUpGoogleAPIClient() {
    Log.e("APIClient", String.valueOf(googleAPIClient));
    if (googleAPIClient == null) {
        this.googleAPIClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API).build();
    }
    Log.d("APIClient", String.valueOf(googleAPIClient));
}

private void setUpLocationRequest() {
    locationRequest = LocationRequest.create().setInterval(1000).setFastestInterval(1000).setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    //setUpGoogleAPIClient();
    activeNetwork = connectivityManager.getActiveNetworkInfo();
    if (activeNetwork != null && activeNetwork.isConnectedOrConnecting()) {
        isConnectedInternet = true;
    }

    connectivity = checkConnectivity();

    if (connectivity) {
        if (!googleAPIClient.isConnected() || !googleAPIClient.isConnecting()) {
            googleAPIClient.connect();
            Log.e("APICLient", "Connect");
        }
        if (googleAPIClient.isConnected()) {
            isConnected = true;
            Log.e("APICLient", "Connected");
        }

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, 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 TODO;
        }
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleAPIClient);
        Log.d("LastLocation", String.valueOf(mLastLocation));
        if (mLastLocation != null) {
            latitude = String.valueOf(mLastLocation.getLatitude());
            longitude = String.valueOf(mLastLocation.getLongitude());
            Log.e("Latitude", latitude);
            Log.e("Longitude", longitude);
            mLastLocation = null;
        }
    } else {
        TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
        CellLocation cellLocation = tm.getCellLocation();
        GsmCellLocation gsmLocation = (GsmCellLocation) cellLocation;
    }

    if (intent.getStringExtra("Pin1") != null && intent.getStringExtra("Pin2") != null) {
        String pin1 = intent.getStringExtra("Pin1");
        String pin2 = intent.getStringExtra("Pin2");
        Log.e("PIN1", pin1);
        Log.e("PIN2", pin2);

        sendLocationSMS(pin1, pin2);
    }
    return START_STICKY;
}

private boolean checkConnectivity() {
    if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !isConnectedInternet) {
        connectivity = false;
    } else if (!isConnectedInternet) {
        connectivity = false;
    } else if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        connectivity = false;
    }
    return connectivity;
}

private void sendLocationSMS(String pin1, String pin2) {
    String message = "FIND Location:" + pin1 + ":" + latitude + ":" + longitude + ":" + pin2;
    Log.e("LocationMessage", message);
    String number = "77131";

    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);
    SmsManager sms = SmsManager.getDefault();
    sms.sendTextMessage(number, null, message, sentPI, deliveredPI);
}

@Override
public void onDestroy() {
    super.onDestroy();
    unregisterReceiver(senderBroadcastReceiver);
    unregisterReceiver(deliverBroadcastReceiver);
    googleAPIClient.disconnect();
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    locationRequest = LocationRequest.create().setInterval(1000).setFastestInterval(1000).setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    Log.e("LocationRequest", String.valueOf(locationRequest));
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onLocationChanged(Location location) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

}

Upvotes: 0

Views: 203

Answers (1)

Sith
Sith

Reputation: 134

There is no guarantee that getLastLocation() method will return an actual Location (see Google Documentation). That method is usually invoked when you need a first location as soon as possible but, in this specific context, the FusedLocation Provider maintains some Locations in background only if there is at least one client connected to it (i.e. there won't be any Location available when the client connects for the first time). You should subscribe to location updated calling requestLocationUpdates instead, wait for the callback to be called for the first time and then remove location updates.

You can find more information here and on Android Developers

Upvotes: 0

Related Questions