0

私はキャップストーンに取り組んでおり、ユーザーの場所を取得して地図上にプロットするアプリを開発しています。x 変数 (x は、5、10、15、30、および 60 分の選択からユーザーが入力した設定) ごとに場所を取得し、後で共有するために最適な場所をデータベースに送信しようとしています。アプリの基本的な流れは、ユーザーがアプリを開くたびにマップが表示され、現在の場所ができるだけ早く表示されるというものです。場所はデータベースに送信され、他のユーザーと共有されます。彼らが場所を取得した後、タイマーが開始され、30分ごとに場所を取得し、その場所をDBに送信してタイマーを再度開始します。アプリを起動するとすぐに位置情報が取得されるため、ユーザーがアプリケーションにアクセスするたびにタイマーをリセットする必要があります。私が抱えている問題は、バックグラウンドでタイマーを作成し、アプリにいない間に位置を取得して DB に送信することです。また、位置情報を取得した後、更新のリッスンを短時間停止するロジックも実装したいと考えています。

私は現在 requestLocationUpdates() メソッドを理解しており、ユーザーがアプリにアクセスすると、GPS とネットワークの両方から場所を取得し、最小時間が 60 秒、距離が 100 フィートまたは 30.48 メートルになるように実装しました。これは、ユーザーがアプリを一時停止すると停止し、ユーザーがアプリに戻ると開始します。すでに更新を受け取っているにもかかわらず、更新を要求し続けていることに気付きました。これにより、 requestLocationUpdates は更新の変更をリッスンしているため、バッテリー寿命を使い続けていると私は信じています。

場所を受信した後に更新を停止し、一定時間後に場所のリッスンを開始するこのロジックを作成するにはどうすればよいですか? requestLocationUpdates の現在の Android メソッドを読み取ると、minTime と minDistance は単なる「ヒント」ですが、それらには従いません。設定されたパラメーターに従うには、locationUpdater が必要です。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /** Session Creation and Checker */
    session = new SessionManagement(getApplicationContext());
    // Check if the user is logged in
    session.checkLogin();

    /** Setup basic session and content view */
    // Set the Content View
    setContentView(R.layout.activity_main);
    /** Start of the MapView Elements */
    // extract MapView from layout
    mapView = (MapView) findViewById(R.id.mapview);
    // Set a mapController
    mapController = mapView.getController();
    // set the map to have built in zoom controls
    mapView.setBuiltInZoomControls(true);

    /** Getting the device location */
    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    geoCoder = new Geocoder(this);

    isEnabled = locationManager
            .isProviderEnabled(LocationManager.GPS_PROVIDER);
    // Check if the GPS is enabled
    if (!isEnabled) {
        alert.showAlertDialog(MainActivity.this, 12);
    }

    // Retrieve a list of location providers that have fine accuracy, no
    // monetary cost, etc
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_HIGH);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    provider = locationManager.getBestProvider(criteria, true);

    // If no suitable provider is found, null is returned.
    if (provider != null) {
        provider = locationManager.getBestProvider(criteria, false);
        BCT = (session.getBCT() * 60000);
        // Initialize with last known location
        locationManager.requestLocationUpdates(provider, BCT, 31,
                locationListener);

        // Check the map settings
        if (session.isSatellite()) {
            SatelliteChecked = true;
            mapView.setSatellite(true);
        }
        if (session.isTraffic()) {
            TrafficChecked = true;
            mapView.setTraffic(true);
        }
    } else {
        alert.showAlertDialog(getApplicationContext(), 15);
        locationManager.removeUpdates(locationListener);
    }

}

// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
        // Called when a new location is found by the network location
        // provider.

            Toast.makeText(getApplicationContext(), location.toString(),
                    Toast.LENGTH_LONG).show();

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    public void onProviderEnabled(String provider) {
        Toast.makeText(getApplicationContext(), provider.toUpperCase() + " enabled.", Toast.LENGTH_SHORT).show();
    }

    public void onProviderDisabled(String provider) {
        Toast.makeText(getApplicationContext(), provider.toUpperCase() + " disabled.", Toast.LENGTH_SHORT).show();
    }
};
@Override
protected void onResume() {
    super.onResume();
    BCT = (session.getBCT() * 60000);
    // when our activity resumes, we want to register for location updates
    locationManager.requestLocationUpdates(
            provider, BCT, 31, locationListener);
}

@Override
protected void onPause() {
    super.onPause();
    // when our activity pauses, we want to remove listening for location
    // updates
    locationManager.removeUpdates(locationListener);
}
4

2 に答える 2

0

必要なのは、タイマーのバックグラウンドスレッドです。

あなたは試すことができます:

  1. アラームマネージャーを使用してx分ごとにスケジュールします。この質問の回答を参照してください:Android:AlarmManagerの使用方法
  2. http://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable、longpostDelayedのように、x分までにAsyncTaskまたはHandlerを使用します

これはあなたの絶頂プロジェクトなので、あまり多くのコードを提供したくありませんでした。しかし、私はバックグラウンドスレッドをより詳細に説明することができます:

現在のタイミングはすべてフォアグラウンドで行われています。つまり、アプリを開かない限り、タイマーは刻々と過ぎていません。あなたがする必要があるのは、バックグラウンドスレッドにタイマーを置くことです。これは、オペレーティングシステムによって管理され、アプリが実行されていなくても実行されているスレッドです。これは商用プロジェクトではなくプロジェクトに対して行っているので、ハンドラーアプローチを使用することをお勧めします。このような:

//make instance variable of the time the user chose, say... delayInMinutes
int delayInMinutes;
...
//then whenever you want to start the timer...
final Runnable updateLocation = new Runnable() {
    public void run() {
        //
        ... do your update location here
        //
    }
};

handler.postDelayed(updateLocation, delayInMinutes * 60 * 1000);

そしてそれはうまくいくはずです

于 2012-11-12T18:24:19.220 に答える
0

これは、アラームIntentServiceを使用するのに最適な状況です。ユーザーが希望する間隔に設定された繰り返しアラームで IntentService を起動し、IntentService に位置情報の更新を処理させます。

これはすべてバックグラウンドで行われ、必要のないときに実行する必要はありません。

于 2012-11-12T19:01:48.190 に答える