1

座標を取得して画面に表示する簡単な GPS プログラムを実装しました。この設計を改良して非同期タスクを実装しようとしたところ、何らかの理由で GPS が機能しないようです。GPS で非同期タスクを使用することに関して問題はありますか? これが私のコードです:

private class DownloadTask extends AsyncTask<String, Void, Object> {
        protected Object doInBackground(String... args) {
            Log.i("MyApp", "Background thread starting");

            LocationManager mLocationManager;
            Gpslistener Gpslistener;

            Gpslistener = new Gpslistener();

            try{

               mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

               mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,Gpslistener);

            }catch (Exception e) {

                test_gps = true;
           }


        return null;
    }

    protected void onPostExecute(Object result) {

        if(test_gps == true){
            if (ParkingActivity.this.progressDialog != null) {
                ParkingActivity.this.progressDialog.dismiss();
            }               
            AlertMessage("GPS Error", "Unable to get location");
        }



public class Gpslistener implements LocationListener
{
        @Override
        public void onLocationChanged(Location loc)
        {
            loc.getLatitude();
            loc.getLongitude();
        }

        @Override
        public void onProviderDisabled(String provider)
        {       
        }

        @Override
        public void onProviderEnabled(String provider)
        {
        }

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

実行するたびに、常に例外がキャッチされます。GPS のアクセス許可はマニフェストに設定されており、私は常に別のアプリケーションを使用して GPS 接続がオンラインであることを確認しているので、潜在的なエラーとしてそれらを排除しました。正直なところ、非同期タスクがなければ完全に機能します。どんな助けでも大歓迎です、ありがとう!

編集 された私の例外logcat:

05-09 22:56:20.199: E/EXCEPTION:(8874): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-09 22:56:20.199: E/EXCEPTION:(8874): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-09 22:56:20.199: E/EXCEPTION:(8874):     at android.os.Handler.<init>(Handler.java:121)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:173)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:173)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at android.location.LocationManager._requestLocationUpdates(LocationManager.java:579)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at android.location.LocationManager.requestLocationUpdates(LocationManager.java:446)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at stefan.testservice.ParkingActivity$DownloadTask.doInBackground(ParkingActivity.java:163)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at stefan.testservice.ParkingActivity$DownloadTask.doInBackground(ParkingActivity.java:1)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
05-09 22:56:20.199: E/EXCEPTION:(8874):     at java.lang.Thread.run(Thread.java:1019)
4

3 に答える 3

4

そんなことはできません。スレッドdoInBackground()は戻るとすぐに終了します。LooperGPS リスナーは、操作にスレッドを必要とする Handlerです。最初doInBackground()に呼び出す必要がありLooper.prepare()、最後に呼び出す必要がありますLooper.loop()quit()スレッドのLooperオブジェクトを呼び出すまで、永遠にループします。

AsyncTaskただし、実際にはワンショット一時スレッド用に設計されているため、これには通常のスレッドを使用します。とはいえ、あなたができない理由はないと思います。ループを終了することを100%確認する必要があります。そうしないと、ユーザーがアプリを閉じた後でもループが永久に実行されます.

Java は、Looper.prepare() を呼び出していないスレッド内でハンドラーを作成できません

于 2012-05-09T21:16:35.430 に答える
1

他の多くのものと同様に、gpsリスナーは(uiスレッドのような)ループスレッドによってのみリッスンできます。最も簡単な方法は、UIスレッドを介して行うことです。

また、gpsリスナーは理由もなくこのように名前が付けられていません。場所を取得した場合(および時間がかかる場合があります)にのみ、メソッド「onLocationChanged」を呼び出します。「requestLocationUpdates」へのすべての呼び出しはとにかく非同期であるため、これにasyncTaskを設定する必要はありません...

于 2012-05-09T21:11:51.353 に答える
0

汚くて官能的ではない方法が必要な場合:

mLocationManager = (LocationManager)getActivity().getSystemService(Context.LOCATION_SERVICE);
Looper.prepare();
Looper.loop();
if(mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){    
  mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_MINIMUM_TIME, GPS_MINIMUM_DISTANCE, MyFragment.this);
}
Looper.myLooper().quit();

基本的に、現在のスレッドをメッセージが実行されるメイン スレッドにし、このスレッドをメイン スレッドにすることをすぐにあきらめます。この結果がどうなるかはわかりません。

于 2014-02-19T04:30:52.293 に答える