Удаленный сервис Android не вызывает методы сервиса - PullRequest
2 голосов
/ 28 мая 2010

Я разрабатываю программное обеспечение для отслеживания 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. В чем проблема? Я не могу найти ничего плохого.

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

Tobias

1 Ответ

2 голосов
/ 28 мая 2010

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

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

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

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

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

...