2010-12-28 5 views
2

グリーティング、Android:Timer in Background Service

私は10秒ごとに自分のサーバーにGPS座標を送信するタイマーを実装しようとしています。ここで

は私が実装してるサービスからコードスニペットです:

@Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Timer timer=new Timer(); 
     TimerTask tt=new TimerTask(){ 
      @Override 
      public void run() { 
       Location loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
       sendCoords(String.valueOf(loc.getLatitude()), String.valueOf(loc.getLongitude())); 
       Toast.LENGTH_SHORT).show(); 
       Log.i("EOH",String.valueOf(loc.getLatitude())); 
      } 
     }; 
     timer.schedule(tt,0,10000); 

     return START_STICKY; 
    } 

さて問題は、実行内部の何かが()私のアプリを閉じ、強制的に引き起こすことがあります。ここ

LogCatダンプである:

12-28 18:44:18.284: ERROR/AndroidRuntime(6537):FATAL EXCEPTION:タイマー0 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): java.lang.RuntimeException: を持っているスレッド内でハンドラを作成していない することはできませんと呼ばれるLooper.prepare()12-28 18:44:18.284: ERROR/AndroidRuntime(6537): android.os.Handler(Handler.java:121) 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): prestocab.driver.Background $ 2(Background.java:83) 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): prestocab.driver.Background。 sendCoords(Background.java:83) 12-28 18:44:18.284: ERROR/AndroidRuntime(6537): prestocab.driver.Background $ 3.run(Background.java:114) 12-28 18:44 :18.284: ERROR/AndroidRuntime(6537):44:18.554: java.util.Timer $ TimerImpl.run(Timer.java:289) 12-28 18時 ERROR /ウィンドウマネージャ(1310):リターン でremoveWindowLocked

誰にでもこれに対する修正を提案できますか?

locationManager onLocationChanged()関数を使用しようとしましたが、間隔を10秒に設定できません。明らかに指定された時間はガイダンスに過ぎず、OSによって最適なものが決定されます。間隔を100秒に設定しても、1秒ごとに位置がわかります。それで私がタイマーを使う理由。

誰かが何か提案できることを願っています。事前に

おかげで、

+0

「lm.requestLocationUpdates(LocationManager.GPS_PROVIDER、5000、1、lr);」というメッセージが表示されます。助けにならない ? 3番目のパラメータは別の場所の更新をトリガする最小距離ですが、2番目のパラメータは更新後の最小時間です。どちらの条件が最初に満たされても、場所の更新が得られます。 – kellogs

+0

@kellogs明らかに、この投稿からhttp://stackoverflow.com/questions/4418018/android-locationmanager-requestlocationupdates-doesnt-respect-paramsパラメータは指標に過ぎず、個々のデバイスごとに最適なものが決まります。 – Eamorr

答えて

7

私はGPSが私のサーバーに10秒ごとに座標送信タイマーを実装しようとしています。

これは非現実的です。あなたは何の修正も全く得られないかもしれません。あなたは10秒を超えるまで修正を得ることはできません。たとえば、開発者が場所の更新をもっと低い頻度で(たとえば1時間に1回)投票するのに役立つように設計されたサービスをテスト中です。電話からでも簡単に修正を得ることができます窓に座っている。欠陥がある

:ここ

は私が実装してるサービスからコードスニペットです。 getLastKnownLocation()は、おおよそ nullを返します。 Timer/ TimerTaskの問題を超えています。

私は誰かが何か提案することを願っています。

難しい要件として10秒の概念を取り除くために、あなたのアプリを再設計することから始めます。

次に、requestLocationUpdates()を使用してください。読み取り値が多すぎる場合は、不要なものを無視し、サーバーに送信しないでください。もちろん、GPSラジオの電源をオンにしておくと、電池の消耗を考慮して、短い時間だけ、ユーザーからの肯定的なリクエスト(例:アプリを明示的に実行)に基づいて実行してください。

requestLocationUpdates()のドキュメントは、明らかにタイミングフロントを混乱させています。私は最近、最低限の時間が必ずしも尊重されないことを最近知っただけです。

+0

ねえ、ごめんなさい遅れた返事のために。私はあなたのアドバイスを受けて、あまりにも頻繁に来ている読書を無視しました。このタイマーよりもはるかに簡単です! – Eamorr

+1

@CommonsWareは丁寧に同意しない。元のユーザーは、タイムドイベントが必要ではないと判断しましたが、その質問が参照するアプリケーションは、まったく役に立たないものではありません。ユーザーがXX秒ごとにどこにいるかを知る必要があると言いましょう(私は10が誇張されていることに同意します)。 10秒ごとにロケーションクエリを起動する必要がある場合は、ロケーションフィックスがないかもしれませんが、コールする前にロケーションキャッシュを保存する必要があります。 Reto MeierのDeep Dive in Locationをチェックしてください。 retoMeierは彼のことを知っています。彼はGoogleのTech Leadです。 –

1

スタックトレースで、「スレッドの種類のエラーまたは状況を思い出させるLooper.prepare().......を呼び出していないスレッド内のハンドラを作成できません」というメッセージが表示されましたこれによりオブジェクトはまだその状態を設定し終えていない。

私はビデオを数週間前に見ましたが、プレゼンターは何か似たようなことをしていました...タイマーに基づいてGPSからデータを送信していましたが、今すぐ見つけられないようです。それを検索してみてください...それは約1時間のビデオでしたが、時間の価値があります。

1

MainUIスレッドがトーストや他のUIコンポーネントの呼び出し中に例外がこれを使用するようになりますので、あなたが外部のスレッドでメインUIエレメントを呼び出していると: -

次のようにハンドラを作成します -

これはあなたを助ける

Thread background = new Thread (new Runnable() { 
    @Override 
    public void run() { 
     // this will be done in the Pipeline Thread 
     /* Do your GPS task here */ 
     // active the update handler 
     progressHandler.sendMessage(progressHandler.obtainMessage()); 
    } 
}); 

// start the background thread 
background.start(); 

・ホープ - :

Handler progressHandler = new Handler() { 
    public void handleMessage(Message msg) { 
     // display UI , Update UI 
     /* To do your UI updation here */ 
    } 
}; 

は今、このようなあなたのスレッドを作ります。