1

所以,我被要求制作一个位置跟踪器。即使应用程序关闭,位置跟踪器也应该跟踪......我的想法是通过调用 startService(intent); 从活动中启动我自己的服务(我们称之为 TrackingService);所以该服务将永远运行(我猜..),然后从我自己创建的 TrackingService 连接到位置服务。TrackingService 应该在应用关闭后监听位置变化。我编写了一些代码,启动了 TrackingService,并在一个新线程中请求了位置更新。无论如何,我退出应用程序后位置更新停止,但服务仍在运行。

编辑:好的,所以我设法改进了我的代码,所以现在当我的应用程序运行时,我得到日志表明我的线程(在单独的服务中运行)正在运行并且它接收位置更新。当我退出 y 应用程序时,我仍然会收到日志,表明我的线程正在运行,但它没有收到位置更新……任何人都可以指出我的原因吗?PS我知道可能有更好的方法来完成工作,但我真的希望修复我的代码。服务课来了

    public class TrackingService extends Service {
// DEBUG
public final static String TAG = "TrackingService";
public final static boolean D = true;
 // Global constants
private static final long UPDATE_INTERVAL = 10000;  // Update frequency in milliseconds
private static final long FASTEST_INTERVAL = 4000;  // A fast frequency ceiling in milliseconds    
//
int mStartMode;       // indicates how to behave if the service is killed
private final IBinder mBinder = new LocalBinder();      // interface for clients that bind
boolean mAllowRebind; // indicates whether onRebind should be used
private int number; // testavimui
LocationThread mLocationThread;


@Override
public void onCreate() {
    if (D) {Log.d(TAG, "service - onCreated started");};
    mLocationThread = new LocationThread(this); 
    mLocationThread.start();
   // mLocationThread.run();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (D) {Log.d(TAG, "service - onStartCommand started");};
    // The service is starting, due to a call to startService()
    return mStartMode;
}
@Override
public IBinder onBind(Intent intent) {
    if (D) {Log.d(TAG, "service - onBind started");};
    // A client is binding to the service with bindService()
    return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
    if (D) {Log.d(TAG, "service - onUnBind started");};
    // All clients have unbound with unbindService()
    return mAllowRebind;
}
@Override
public void onRebind(Intent intent) {
    if (D) {Log.d(TAG, "service - onReBind started");};
    // A client is binding to the service with bindService(),
    // after onUnbind() has already been called
}
@Override
public void onDestroy() {
    if (D) {Log.d(TAG, "service - onDestroy started");};
    // The service is no longer used and is being destroyed
    mLocationThread.cancel();
}

public class LocalBinder extends Binder {
    TrackingService getService() {
        // Return this instance of LocalService so clients can call public methods
        return TrackingService.this;
    }
}

public int number(){
    number += 1;
    return number;
}



private class LocationThread extends Thread implements
                        GooglePlayServicesClient.ConnectionCallbacks,
                        GooglePlayServicesClient.OnConnectionFailedListener,
                        LocationListener{ 


    private boolean keepOn;
    private Context mContext;
    private LocationClient mLocationClient; 
    private LocationRequest mLocationRequest;

    public LocationThread (Context context){
        mContext = context;
        keepOn = true;

    }

    public void cancel() {
        keepOn = false;
        if (D){Log.d(TAG, "thread was canceled");};


    }

    public void run(){
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // Use high accuracy 
        mLocationRequest.setInterval(UPDATE_INTERVAL); // Set the update interval to 5 seconds 
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL); // Set the fastest update interval to 1 second
        mLocationClient = new LocationClient(mContext, this, this);
        mLocationClient.connect();

        while (keepOn){
            try {
                Thread.sleep(10000);
                if(D){Log.d(TAG, "thread running");};
            } catch (Exception e){

            }
        }

    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        if(D){Log.d(TAG, "connection failed");};
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        if(D){Log.d(TAG, "connected to location service");};
        mLocationClient.requestLocationUpdates(mLocationRequest, this);
    }

    @Override
    public void onDisconnected() {
        if(D){Log.d(TAG, "disconnected from location service");};
    }

    @Override
    public void onLocationChanged(Location location) {
        if(D){Log.d(TAG, "Location changed");};

    }
}

}

4

1 回答 1

0

虽然文档没有具体说明,但我建议您LocationManager.requestLocationUpdates()在主(UI)线程中执行调用。如果调用来自单独的线程,您可以使用Handler来完成此操作。

顺便说一句,如果您希望您的服务在单独的线程中运行,我建议您扩展IntentService并覆盖该onHandleIntent()方法,这样更容易。

进一步的建议:

如果你想让你Service的手机即使在睡眠模式下也能运行,你需要一个唤醒锁。

提示:您不必让它连续运行,这会不必要地消耗大量电池。使您的Service收集单个位置,将其保存到本地数据库或将其传递到绑定活动然后停止,然后Service使用AlarmManager.

它是这样的:AlarmManager调用 a WakefulBroadcastReceiver,然后调用 your Service

我建议您阅读WakefulBroadcastReceiver文档,它会自动为您的服务提供唤醒锁(您必须在服务停止之前手动释放)。

于 2013-10-21T19:26:02.940 回答