0

I have TrackingService component to track the location of the buses in my city based on Crowdsourcing. In the TrackingService class I have variable pLong, pLat to stored the latitude and longitude when they are calaculated in the onLocatiochChanged(). The TrackingService is operating in the background, where the data is transmitted to the server. I have an Map Activity to display the location of the buses, the user selected in the MainActivity( as Filter).

I am trying to build TrackingServiceCallback functionality to notify the Map Activity when the pLat, pLong were updated in the onLocationChanged() in the TrackingService class to Display his current Location too. Currently I am getting the error below.

How can I get it to work?

Error:

08-27 13:02:29.157: E/AndroidRuntime(6438): FATAL EXCEPTION: main
08-27 13:02:29.157: E/AndroidRuntime(6438): Process: com.bustracker, PID: 6438
08-27 13:02:29.157: E/AndroidRuntime(6438): java.lang.RuntimeException: Unable to instantiate service com.bustracker.TrackingService: java.lang.InstantiationException: class com.bustracker.TrackingService has no zero argument constructor
08-27 13:02:29.157: E/AndroidRuntime(6438):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:3135)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at android.app.ActivityThread.access$1900(ActivityThread.java:177)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1531)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at android.os.Handler.dispatchMessage(Handler.java:102)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at android.os.Looper.loop(Looper.java:145)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at android.app.ActivityThread.main(ActivityThread.java:5944)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at java.lang.reflect.Method.invoke(Native Method)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at java.lang.reflect.Method.invoke(Method.java:372)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1389)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1184)
08-27 13:02:29.157: E/AndroidRuntime(6438): Caused by: java.lang.InstantiationException: class com.bustracker.TrackingService has no zero argument constructor
08-27 13:02:29.157: E/AndroidRuntime(6438):     at java.lang.Class.newInstance(Class.java:1641)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:3132)
08-27 13:02:29.157: E/AndroidRuntime(6438):     ... 9 more
08-27 13:02:29.157: E/AndroidRuntime(6438): Caused by: java.lang.NoSuchMethodException: <init> []
08-27 13:02:29.157: E/AndroidRuntime(6438):     at java.lang.Class.getConstructor(Class.java:531)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at java.lang.Class.getDeclaredConstructor(Class.java:510)
08-27 13:02:29.157: E/AndroidRuntime(6438):     at java.lang.Class.newInstance(Class.java:1639)
08-27 13:02:29.157: E/AndroidRuntime(6438):     ... 10 more

TrackingService class:

public class TrackingService extends Service implements
        LocationListener {
    public double pLong;
    public double pLat;
    private TrackingServiceCallback callback;

public TrackingService(TrackingServiceCallback callback) {
    this.callback = callback;
}
    ...
        @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        detectLocation();
        return START_STICKY;
    }
    private void detectLocation() {
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 0,
                this);
    }
    @Override
    public void onLocationChanged(Location location) {

        if (location != null) {
            pLong = location.getLongitude();
            pLat = location.getLatitude();
                   callback.retrieveLatLng(pLat, pLong);
           .....

     }  

}

Map activity:

public class Map extends FragmentActivity implements OnMapReadyCallback,    TrackingServiceCallback{
  Marker myLocatMarker;
  .....
@Override
public void retrieveLatLng(double lat, double lng) {
 LatLng ll = new LatLng(lng,lat);
     MarkerOptions markerOpt = new MarkerOptions().title("My Location")
                .position(ll);
     myLocatMarker = map.addMarker(markerOpt);

}
  ...

  }

TrackingServiceCallback Interface:

public interface TrackingServiceCallback {
    void retrieveLatLng(double lat, double lng);

}
MrPencil
  • 934
  • 8
  • 17
  • 36

1 Answers1

0

Use an EventBus library, preferably this one. With it, you register an EventBus object which lets you pass Messages (including data if needed) between various application components. It is threadsafe, easy to use and fast.

You may also use other Android components, like Handlers or even AIDL interface, if your service is remote. But EventBus wraps those and uses the best one for the situation, so there is no need to reinvent the wheel, is there?

EDIT:

Alternatively, you can simply prepare an Intent in the Service, put the data in the Extras of the Intent and broadcast it, then receive in the Activity. See this answer.

Community
  • 1
  • 1
Kelevandos
  • 7,024
  • 2
  • 29
  • 46
  • In general, you should never connect Android app components with things like callback, because of memory leaks. However, there is also another solution, I will update the answer in a sec. – Kelevandos Aug 27 '15 at 11:36