Search code examples
androidandroid-fragmentsservicebroadcastreceiverfragment

Fragment BroadCast receiver not working


I'm making an app where I need to get constant location updates from a Service on a fragment, the problem is that the fragment is not getting the updates and I'm not sure what is the problem, here is the service:

public class GPService extends Service
{
 private LocationManager locMan;
 private Boolean locationChanged;
 private Handler handler = new Handler();
 static final int REQUEST_LOCATION = 1;

public static Location curLocation;
public static boolean isService = true;
public LocalBroadcastManager broadcast;


LocationListener gpsListener = new LocationListener() {
    public void onLocationChanged(Location location) {
        if (curLocation == null) {
            curLocation = location;
            locationChanged = true;
            Intent intent= new Intent("GPSLocationUpdates");
            intent.putExtra("latitud",curLocation.getLatitude());
            intent.putExtra("latitud",curLocation.getLongitude());
            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);

        }else if (curLocation.getLatitude() == location.getLatitude() && curLocation.getLongitude() == location.getLongitude()){
            locationChanged = false;
            return;
        }else
            locationChanged = true;

        curLocation = location;

        if (locationChanged)
            locMan.removeUpdates(gpsListener);

    }
    public void onProviderDisabled(String provider) {
    }

    public void onProviderEnabled(String provider) {
    }

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

    }

};

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

    curLocation = getBestLocation();

    if (curLocation == null)
        Toast.makeText(getBaseContext(),"Unable to get your location", Toast.LENGTH_SHORT).show();
    else{
        //Toast.makeText(getBaseContext(), curLocation.toString(), Toast.LENGTH_LONG).show();
    }

    isService =  true;
    broadcast= LocalBroadcastManager.getInstance(this);

}
final String TAG="LocationService";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return super.onStartCommand(intent, flags, startId);
}
@Override
public void onLowMemory() {
    super.onLowMemory();
}

@Override
public void onStart(Intent i, int startId){
    handler.postDelayed(GpsFinder,1);
}

@Override
public void onDestroy() {
    handler.removeCallbacks(GpsFinder);
    handler = null;
    Toast.makeText(this, "Stop services", Toast.LENGTH_SHORT).show();
    isService = false;
}

public IBinder onBind(Intent arg0) {
    return null;
}

public Runnable GpsFinder = new Runnable(){
    public void run(){

        Location tempLoc = getBestLocation();
        if(tempLoc!=null)
            curLocation = tempLoc;
        tempLoc = null;
        handler.postDelayed(GpsFinder,1000);
    }
};

private Location getBestLocation() {
    Location gpslocation = null;
    Location networkLocation = null;

    if(locMan==null){
        locMan = (LocationManager) getApplicationContext() .getSystemService(Context.LOCATION_SERVICE);
    }
    try {
        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) {

            //ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
        }
        else {
            if(locMan.isProviderEnabled(LocationManager.GPS_PROVIDER)){


                locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000, 1, gpsListener);
                gpslocation = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                Intent intent= new Intent("GPSLocationUpdates");
                intent.putExtra("latitud",gpslocation.getLatitude());
                intent.putExtra("longitud",gpslocation.getLongitude());
                Log.wtf("COORDENATES TO SEND",gpslocation.getLatitude()+" "+gpslocation.getLongitude());
                LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);

            }
            if(locMan.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
                locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000, 1, gpsListener);
                networkLocation = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                Intent intent= new Intent("GPSLocationUpdates");
                Log.wtf("LAS COORDENADAS a enviar SON",networkLocation.getLatitude()+" "+networkLocation.getLongitude());

                intent.putExtra("latitud",networkLocation.getLatitude());
                intent.putExtra("longitud",networkLocation.getLongitude());
                LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
            }
        }

The service is initiated in the activity like this

 startService(new Intent(this, GPService.class));

In the fragment this is how I create it and register it

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    receiver= new GPSReceiver();
    //this.getActivity().registerReceiver(receiver, new IntentFilter());

    db=Database.getInstance(this.getContext());


}
@Override
public void onResume() {
    super.onResume();
    IntentFilter filter = new IntentFilter("GPSLocationUpdates");
    getActivity().registerReceiver(receiver,filter);
}

@Override
public void onPause() {
    getActivity().unregisterReceiver(receiver);
    super.onPause();
}

Finally this is the reciever in the Fragment, I can't get it to get the info from the service, any ideas? I don't know what I'm doing wrong.

private class GPSReceiver extends BroadcastReceiver {


    private LatLng changed;

    public GPSReceiver()
    {
        changed= new LatLng(0,0);
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.wtf("RECIEVE", "IT IS IN BROADCAST");
        if (intent.getAction().equals("GPSLocationUpdates"))
        {
            Log.wtf("RECIEVE1", "INTENT ARRIVES");
            double lat= intent.getDoubleExtra("latitud",1);
            double longi= intent.getDoubleExtra("longitud",1);
            changed= new LatLng(lat,longi);

        }
       // String text = intent.getStringExtra("position");

    }
    public LatLng getChanged()
    {
        return changed;
    }
}

The service seems to be working fine, I can see the coordinates in the console being send.


Solution

  • You're not registering you BroadcastReceiver to the LocalBroadcastManager. You're registering it to the global broadcast manager, but sending on the local.

    Change:

    @Override
    public void onResume() {
        super.onResume();
        IntentFilter filter = new IntentFilter("GPSLocationUpdates");
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver,filter);
    }
    
    @Override
    public void onPause() {
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(receiver);
        super.onPause();
    }