Android远程服务不调用服务方法

发布于 2024-09-03 17:14:33 字数 6133 浏览 4 评论 0原文

我正在 Android 上开发 GPS 跟踪软件。我需要 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) ,则不会发生任何事情。绑定正常。调试时,它总是会遇到生成的 ITrackingServiceRemote.java 文件中的 startTracking(),而不是我的 TrackingService 类。问题出在哪里?我找不到什么不妥的地方。

提前致谢!

托比亚斯

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 AIDL 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仅冇旳回忆 2024-09-10 17:14:33

我需要 IPC 来控制服务
不同的活动。所以我决定
使用 AIDL 开发远程服务。

您不需要 IPC 来控制来自不同活动的服务。您可能需要 IPC 来控制来自不同应用程序(即单独的 APK)的服务。

调试时总是遇到
生成的startTracking()
ITrackingServiceRemote.java 文件和
不进入我的 TrackingService 类。

您的活动有一个代表服务接口的客户端代理。该服务本身应该在与完全独立的 APK 完全独立的进程中运行。

我建议您摆脱 AIDL 并切换回本地绑定模式,至少足够长的时间以使您的活动和服务正常工作。然后,只有到那时,您才应该将它们分成单独的 APK(如果这确实是所需的结果)。

I need IPC to control the service from
different activities. So I decide to
develop a remote service with AIDL.

You do not need IPC to control the service from different activities. You may need IPC to control the service from different applications (i.e., separate APKs).

When debugging it always runs into the
startTracking() in the generated
ITrackingServiceRemote.java file and
not into my TrackingService class.

Your activity has a client-side proxy representing the service interface. The service itself is supposed to be running in a completely separate process from a completely separate APK.

I recommend that you get rid of the AIDL and switch back to the local binding pattern, at least long enough to get your activity and service working. Then, and only then, should you pull them apart into separate APKs, if that is indeed the desired end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文