package org.pyneo.tabulae.locus; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.location.Location; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; import org.mapsforge.map.android.view.MapView; import org.pyneo.tabulae.Base; import org.pyneo.tabulae.R; import org.pyneo.tabulae.Tabulae; import static org.pyneo.tabulae.locus.Constants.*; public class Locus extends Base { Messenger mService = null; boolean mIsBound; ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mService = new Messenger(service); try { Message msg = Message.obtain(null, R.id.message_locus_register_client); msg.replyTo = mMessenger; mService.send(msg); msg = Message.obtain(null, R.id.message_locus_set_value, this.hashCode(), 0, new Bundle()); mService.send(msg); } catch (RemoteException ignore) { } Log.d(TAG, "Sample.ServiceConnection.onServiceConnected: remote service connected"); } public void onServiceDisconnected(ComponentName className) { mService = null; Log.d(TAG, "Sample.ServiceConnection.onServiceDisconnected: remote service disconnected"); } }; private ThreeStateLocationOverlay myLocationOverlay; final Messenger mMessenger = new Messenger(new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case R.id.message_locus_set_value: //if (DEBUG) Log.d(TAG, "Locus.handleMessage event=" + msg.arg1 + ", extra=" + msg.obj); ((Tabulae) getActivity()).inform(msg.arg1, (Bundle) msg.obj); break; default: super.handleMessage(msg); } } }); public static Location toLocation(Bundle location) { Location ret = null; if (location != null) { ret = new Location(location.getString("provider")); ret.setElapsedRealtimeNanos(location.getLong("elapsed")); ret.setLatitude(location.getDouble("latitude")); ret.setLongitude(location.getDouble("longitude")); ret.setTime(location.getLong("time")); if (location.containsKey("speed")) { ret.setSpeed((float) (location.getDouble("speed") / 3.6)); } if (location.containsKey("accuracy")) { ret.setAccuracy((float) location.getDouble("accuracy")); } if (location.containsKey("altitude")) { ret.setAltitude(location.getDouble("altitude")); } if (location.containsKey("bearing")) { ret.setBearing((float) location.getDouble("bearing")); } } return ret; } @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); if (DEBUG) Log.d(TAG, "Locus.onCreate"); MapView mapView = ((Tabulae) getActivity()).getMapView(); myLocationOverlay = new ThreeStateLocationOverlay(getActivity()); } @Override public void onResume() { super.onResume(); if (DEBUG) Log.d(TAG, "Locus.onResume"); MapView mapView = ((Tabulae) getActivity()).getMapView(); mapView.getLayerManager().getLayers().add(myLocationOverlay); myLocationOverlay.enable(); doBindService(); } @Override public void onPause() { super.onPause(); if (DEBUG) Log.d(TAG, "Locus.onPause"); MapView mapView = ((Tabulae) getActivity()).getMapView(); mapView.getLayerManager().getLayers().remove(myLocationOverlay); doUnbindService(); } void doBindService() { getActivity().bindService(new Intent(getActivity(), LocusService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } void doUnbindService() { if (mIsBound) { mIsBound = false; if (mService != null) { try { Message msg = Message.obtain(null, R.id.message_locus_unregister_client); msg.replyTo = mMessenger; mService.send(msg); } catch (RemoteException ignore) { } } getActivity().unbindService(mConnection); } } public void inform(int event, Bundle extra) { //if (DEBUG) Log.d(TAG, "Locus.inform event=" + event + ", extra=" + extra); switch (event) { case R.id.event_notify_location: { //if (DEBUG) Log.d(TAG, "Locus.inform event=" + event + ", extra=" + extra); if (myLocationOverlay != null) { myLocationOverlay.onLocationChanged(toLocation(extra)); } } break; } } }