2011-12-22 5 views
2

私は、単一の場所の修正を取得するためにLocationManagerを使用しています:タイムアウトを使用して、LocationManagerから単一のロケーション修正を取得する方法は?

public class MyActivity extends Activity { 
    private LocationManager lm; 
    private ProgressDialog myDialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     LocationListener ll = new MyLocationListener(); 
     lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 1, ll); 
     myDialog = ProgressDialog.show(this, null , "Determining Your Location", true); 
    } 

    class MyLocationListener implements LocationListener { 
     public void onLocationChanged(Location location) { 
      if (location != null) { 
       ... 

       lm.removeUpdates(this); 
       myDialog.dismiss(); 
      } 
     } 
    } 
} 

をこの場所の修正が見つからない場合は、潜在的に永遠に行くことができる場所について聞いて立っています。私は60秒後に場所を聴くのを止め、場所を特定できないというエラーをユーザーに表示することでコードに堅牢性を追加したいと考えています。

どうすればいいですか?

答えて

1

ハンドラを使用し、60秒後にpostDelayedを使用してリスナーを停止する方法もあります。

Handler postDelayed

-1

あなたにもタイマーとTimerTaskを使用することができます。 postDelayedを利用するハンドラを作成するときは、ハンドラがまだ終了した後にアクティビティまたはサービスイベントを参照するため、メモリリークに注意する必要があります。 PostDelayedはメインスレッドのメッセージキューに移動します。したがって、あなたのハンドラを静的にするか弱参照を使用してください。

メモリリークを防ぐには、次のコードを検討する必要があります。

public class MyService extends Service { 

    private static class MyHandler extends Handler { 
     WeakReference<MyService> ref; 

     public MyHandler(MyService r) { 
     ref = = new WeakReference<MyService>(r); 
     } 

     public void handleMessage(Message msg) { 

     MyService service = ref.get(); 
     if (servic==null) { 
      return; 
     } 

     //Do something here 
    } 

    } 

} 
2

あなたはどちらかの可能性ユーザーHandlerTimerまたはAlarmManagerリスニングを停止するLocationManager.removeUpdatesを呼び出すことによって、タイムアウトを実装します。

Timerは、過剰なスレッドである可能性がある新しいスレッドを作成します。 AlarmManagerのドキュメントでは、「(f)または通常のタイミング操作(ティック、タイムアウトなど)は、ハンドラーを使用する方が簡単で効率的です」と示唆しています。 Handlerのドキュメントでは、Handlerの主な用途の1つが、「将来、ある時点で実行されるメッセージと実行可能ファイルをスケジュールする」ことを説明しています。

すべての符号は、タイムアウトを実装する最も適切な方法としてHandlerを指しています。

public class MyActivity extends Activity implements LocationListener { 
    private final int TIMEOUT = 60000; 

    private LocationManager myLocationManager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     myLocationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, 
      this, null); 

     Runnable myRunnable = new Runnable() { 
      public void run() { 
       myLocationManager.removeUpdates(QualityCheckActivity.this); 
       // other timeout error code 
      } 
     }; 

     Handler myHandler = new Handler(); 
     myHandler.postDelayed(myRunnable, TIMEOUT); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     // location fixed code 
    } 

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

    @Override 
    public void onProviderEnabled(String provider) { } 

    @Override 
    public void onProviderDisabled(String provider) { } 
} 

NOTES:

TIMEOUTは、当然のことながら、ミリ秒単位でタイムアウトの長さです。この場合、60,000ミリ秒、つまり60秒です。

は、がRunnableの中でアクセスしやすいように、MyActivity自体にインターフェイスを実装することを選択しました。

LocationManager.requestLocationUpdatesの代わりに、私はLocationManager.requestSingleUpdateを使用しています。これは1箇所の位置情報のみを提供します。

私は意図的にActivity.onPauseActivity.onResumeを実装していません。アクティビティが一時停止されている場合、リッスン場所とタイムアウトの両方が継続されます。

関連する問題