2010-05-28 8 views
2

Je développe un logiciel de suivi GPS sur android. J'ai besoin d'IPC pour contrôler le service de différentes activités. Je décide donc de développer un service à distance avec AIDL. Ce n'était pas un gros problème mais maintenant il est toujours en cours dans les méthodes de l'interface et non dans ceux de ma classe de service. Peut-être que quelqu'un pourrait m'aider?Le service distant Android n'appelle pas les méthodes de service

Voici mon fichier AIDL:

package test.de.android.tracker 
interface ITrackingServiceRemote { 
void startTracking(in long trackId); 
void stopTracking(); 
void pauseTracking(); 
void resumeTracking(in long trackId); 
long trackingState(); 
} 

Et ici une version courte de ma classe de service:

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 
} 

Pour faciliter l'accès du client j'ai écrit une classe ServiceManager qui met en place la ServiceConnection et vous pouvez appeler les méthodes de service. Voici mon code pour cela:

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; 
} 
} 

Si j'essaie maintenant d'appeler une méthode d'une activité par exemple début (TrackID) rien ne se passe. La liaison est OK. Lors du débogage, il s'exécute toujours dans startTracking() dans le fichier ITrackingServiceRemote.java généré et non dans ma classe TrackingService. Où est le problème? Je ne peux rien trouver de mal.

Merci d'avance!

Tobias

Répondre

2

J'ai besoin IPC pour contrôler le service de différentes activités. Donc, je décide de développer un service à distance avec AIDL.

Vous n'avez pas besoin d'IPC pour contrôler le service à partir de différentes activités. Vous pouvez avoir besoin d'IPC pour contrôler le service à partir de différentes applications (c'est-à-dire des fichiers APK séparés).

Lors du débogage, il fonctionne toujours dans le startTracking() dans le fichier généré ITrackingServiceRemote.java et pas dans ma classe TrackingService.

Votre activité dispose d'un proxy côté client représentant l'interface de service. Le service lui-même est supposé fonctionner dans un processus complètement séparé d'un APK complètement séparé.

Je vous recommande de vous débarrasser de l'AIDL et de revenir au mode de liaison local, au moins suffisamment longtemps pour que votre activité et votre service fonctionnent. Ensuite, et seulement alors, devriez-vous les séparer dans des fichiers APK séparés, si c'est bien la fin désirée.