user2763829 user2763829 - 2 months ago 53
Android Question

Updating Activity TextView from service using Service binding

I have a service for reading GPS latitude and longitude. I would like to update the activity from the service's

locationlistener
's
onLocationChanged
.

How can I achieve it? I have been reading on Service Bound but it looks like it is only for activity to invoke the methods in service but not service invoke textView in Activity. Is binding service is not possible to achieve it?

Answer

You should use the LocalBroadcastManager class from within your Service to send an Intent back to the Activity.

For Example, An Activity containing a single TextView can set up a BroadcastReceiver like such:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TextView textView = (TextView) findViewById(R.id.main_activity_text_view);

        LocalBroadcastManager.getInstance(this).registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        double latitude = intent.getDoubleExtra(LocationBroadcastService.EXTRA_LATITUDE, 0);
                        double longitude = intent.getDoubleExtra(LocationBroadcastService.EXTRA_LONGITUDE, 0);
                        textView.setText("Lat: " + latitude + ", Lng: " + longitude);
                    }
                }, new IntentFilter(LocationBroadcastService.ACTION_LOCATION_BROADCAST)
        );
    }

    @Override
    protected void onResume() {
        super.onResume();
        startService(new Intent(this, LocationBroadcastService.class));
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopService(new Intent(this, LocationBroadcastService.class));
    }
}

And a basic Service can broadcast all location changes as follows:

public class LocationBroadcastService extends Service {

    public static final String
            ACTION_LOCATION_BROADCAST = LocationBroadcastService.class.getName() + "LocationBroadcast",
            EXTRA_LATITUDE = "extra_latitude",
            EXTRA_LONGITUDE = "extra_longitude";

    private static final int
            MIN_TIME = 2000,
            MIN_DISTANCE = 1;

    @Override
    public void onCreate() {
        super.onCreate();
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        sendBroadcastMessage(locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER));
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME, MIN_DISTANCE,
                new LocationListener() {
                    @Override
                    public void onLocationChanged(Location location) {
                        sendBroadcastMessage(location);
                    }

                    @Override
                    public void onStatusChanged(String provider, int status, Bundle extras) {

                    }

                    @Override
                    public void onProviderEnabled(String provider) {

                    }

                    @Override
                    public void onProviderDisabled(String provider) {

                    }
                }
        );
    }

    private void sendBroadcastMessage(Location location) {
        if (location != null) {
            Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
            intent.putExtra(EXTRA_LATITUDE, location.getLatitude());
            intent.putExtra(EXTRA_LONGITUDE, location.getLongitude());
            LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
        }
    }


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