1

そこで、ロケーショントラッカーの作成を依頼されました。アプリがオフになっている場合でも、ロケーショントラッカーは追跡する必要があります...私の考えは、startService(intent); を呼び出して、アクティビティから独自のサービス (TrackingService と呼びましょう) を開始することです。そのため、サービスは永久に実行され (推測します..)、自分で作成した TrackingService から Location Service に接続します。アプリがオフになった後、TrackingService は場所の変更をリッスンする必要があります。コードを書き、TrackingService を開始し、新しいスレッドで位置情報の更新をリクエストしました。とにかく、アプリを終了すると位置情報の更新が停止しますが、サービスはまだ実行されています。

編集: わかりましたので、コードを少し改善することができたので、アプリが実行されているときに、スレッド (別のサービスで実行されている) が実行されていることと、場所の更新を受信したことをログに記録します。アプリを終了しても、スレッドが実行されているというログが表示されますが、場所の更新を受信しません...誰でも理由を指摘できますか? 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) スレッドで呼び出しを実行することをお勧めします。呼び出しが別のスレッドから発信された場合、ハンドラーを使用してそれを実現できます。

ところで、サービスを別のスレッドで実行したい場合は、IntentServiceを拡張してメソッドをオーバーライドすることをお勧めしますonHandleIntent()。その方が簡単です。

さらなるアドバイス:

Service電話がスリープモードのときでも実行したい場合は、ウェイクロックが必要です。

ヒント: 不必要に大量のバッテリーを消費するため、連続して実行する必要はありません。収集Serviceを単一の場所にして、ローカル データベースに保存するか、バインドされたアクティビティに配信してから停止しServiceAlarmManager.

次のようになります: a をAlarmManager呼び出し、WakefulBroadcastReceiverそれが順番に your を呼び出しますService

WakefulBroadcastReceiverのドキュメントを読むことをお勧めします。これにより、サービスのウェイクロックが自動的に提供されます (サービスが停止する前に手動で解除する必要があります)。

于 2013-10-21T19:26:02.940 に答える