Удаленная служба Android не вызывает методы службы

Я разрабатываю программное обеспечение для отслеживания GPS на Android. Мне нужен IPC для управления сервисом из разных активностей. Поэтому я решил разработать удаленный сервис с помощью AIDL. Это не было большой проблемой, но теперь она всегда работает с методами интерфейса, а не с методами моего класса обслуживания. Может быть, кто-нибудь мог бы мне помочь?

Вот мой файл AIDL:

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

И вот короткая версия моего класса обслуживания:

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
}

Для более легкого доступа с клиента я написал класс ServiceManager, который устанавливает ServiceConnection, и вы можете вызывать методы службы. Вот мой код для этого:

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

Если я сейчас попытаюсь вызвать метод из действия, например start(trackId), ничего не произойдет. Привязка в порядке. При отладке он всегда запускает startTracking() в сгенерированном файле ITrackingServiceRemote.java, а не в моем классе TrackingService. В чем проблема? Я не могу найти ничего плохого.

Заранее спасибо!

Тобиас


person tarantel    schedule 28.05.2010    source источник


Ответы (1)


Мне нужен IPC для управления сервисом из разных активностей. Поэтому я решил разработать удаленный сервис с помощью AIDL.

Вам не нужен IPC для управления сервисом из разных активностей. Вам может понадобиться IPC для управления службой из разных приложений (т. е. из отдельных APK).

При отладке он всегда запускает startTracking() в сгенерированном файле ITrackingServiceRemote.java, а не в моем классе TrackingService.

В вашей активности есть прокси-сервер на стороне клиента, представляющий интерфейс службы. Сама служба должна работать в совершенно отдельном процессе из совершенно отдельного APK.

Я рекомендую вам избавиться от AIDL и вернуться к локальному шаблону привязки, по крайней мере, на время, достаточное для того, чтобы ваша деятельность и служба заработали. Тогда и только тогда вы должны разделить их на отдельные APK, если это действительно желаемая цель.

person CommonsWare    schedule 28.05.2010