Android remote service doesn't call service methods
- by tarantel
Hello,
I'm developing a GPS tracking software on android. I need IPC to control the service from different activities. So I decide to develop a remote service with AIDL. This wasn't a big problem but now it's always running into the methods of the interface and not into those of my service class. Maybe someone could help me?
Here my ADIL file:
package test.de.android.tracker
interface ITrackingServiceRemote {
void startTracking(in long trackId);
void stopTracking();
void pauseTracking();
void resumeTracking(in long trackId);
long trackingState();
}
And the here a short version of my service class:
public class TrackingService extends Service implements LocationListener{
private LocationManager mLocationManager;
private TrackDb db;
private long trackId;
private boolean isTracking = false;
@Override
public void onCreate() {
super.onCreate();
mNotificationManager = (NotificationManager) this
.getSystemService(NOTIFICATION_SERVICE);
mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
db = new TrackDb(this.getApplicationContext());
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public void onDestroy(){
//TODO
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent){
return this.mBinder;
}
private IBinder mBinder = new ITrackingServiceRemote.Stub() {
public void startTracking(long trackId) throws RemoteException {
TrackingService.this.startTracking(trackId);
}
public void pauseTracking() throws RemoteException {
TrackingService.this.pauseTracking();
}
public void resumeTracking(long trackId) throws RemoteException {
TrackingService.this.resumeTracking(trackId);
}
public void stopTracking() throws RemoteException {
TrackingService.this.stopTracking();
}
public long trackingState() throws RemoteException {
long state = TrackingService.this.trackingState();
return state;
}
};
public synchronized void startTracking(long trackId) {
// request updates every 250 meters or 0 sec
this.trackId = trackId;
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0, 250, this);
isTracking = true;
}
public synchronized long trackingState() {
if(isTracking){
return trackId;
} else
return -1;
}
public synchronized void stopTracking() {
if(isTracking){
mLocationManager.removeUpdates(this);
isTracking = false;
} else
Log.i(TAG, "Could not stop because service is not tracking at the moment");
}
public synchronized void resumeTracking(long trackId) {
if(!isTracking){
this.trackId = trackId;
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0, 250, this);
isTracking = true;
} else
Log.i(TAG, "Could not resume because service is tracking already track " + this.trackId);
}
public synchronized void pauseTracking() {
if(isTracking){
mLocationManager.removeUpdates(this);
isTracking = false;
} else
Log.i(TAG, "Could not pause because service is not tracking at the moment");
}
public void onLocationChanged(Location location) {
//TODO
}
For easier access from the client I wrote a ServiceManager class which sets up the ServiceConnection and you can call the service methods. Here my code for this:
public class TrackingServiceManager{
private static final String TAG = "TrackingServiceManager";
private ITrackingServiceRemote mService = null;
private Context mContext;
private Boolean isBound = false;
private ServiceConnection mServiceConnection;
public TrackingServiceManager(Context ctx){
this.mContext = ctx;
}
public void start(long trackId) {
if (isBound && mService != null) {
try {
mService.startTracking(trackId);
} catch (RemoteException e) {
Log.e(TAG, "Could not start tracking!",e);
}
} else
Log.i(TAG, "No Service bound! 1");
}
public void stop(){
if (isBound && mService != null) {
try {
mService.stopTracking();
} catch (RemoteException e) {
Log.e(TAG, "Could not stop tracking!",e);
}
} else
Log.i(TAG, "No Service bound!");
}
public void pause(){
if (isBound && mService != null) {
try {
mService.pauseTracking();
} catch (RemoteException e) {
Log.e(TAG, "Could not pause tracking!",e);
}
} else
Log.i(TAG, "No Service bound!");
}
public void resume(long trackId){
if (isBound && mService != null) {
try {
mService.resumeTracking(trackId);
} catch (RemoteException e) {
Log.e(TAG, "Could not resume tracking!",e);
}
} else
Log.i(TAG, "No Service bound!");
}
public float state(){
if (isBound && mService != null) {
try {
return mService.trackingState();
} catch (RemoteException e) {
Log.e(TAG, "Could not resume tracking!",e);
return -1;
}
} else
Log.i(TAG, "No Service bound!");
return -1;
}
/**
* Method for binding the Service with client
*/
public boolean connectService(){
mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
TrackingServiceManager.this.mService = ITrackingServiceRemote.Stub.asInterface(service);
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
if (mService != null) {
mService = null;
}
}
};
Intent mIntent = new Intent("test.de.android.tracker.action.intent.TrackingService");
this.isBound = this.mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
return this.isBound;
}
public void disconnectService(){
this.mContext.unbindService(mServiceConnection);
this.isBound = false;
}
}
If i now try to call a method from an activity for example start(trackId) nothing happens. The binding is OK. When debugging it always runs into the startTracking() in the generated ITrackingServiceRemote.java file and not into my TrackingService class. Where is the problem? I can't find anything wrong.
Thanks in advance!
Tobias