【问题标题】:How To Get Location Using AsyncTask如何使用 AsyncTask 获取位置
【发布时间】:2011-04-15 12:23:13
【问题描述】:

我正在努力寻找解决这个问题的好方法。我制作了我的应用程序,以便它找到我的位置。它似乎过于复杂,但很容易。但是,按照谷歌的建议,我现在尝试将此代码作为异步任务运行,这样它就不会占用 UI。但是我什至无法弄清楚如何让代码编译更不用说实际运行了。错误是当我引用它来删除侦听器时,无法解析 locationManager。我尝试使用此处发布的代码Android find GPS location once, show loading dialog。然而,在这个例子中 currentLocation 似乎没有被任何东西引用,我在试图解决这个问题时遇到了问题。我已经浪费了将近一整天的时间来解决这个问题,所以如果有人能指出我正确的方向,我将不胜感激。

private class LocationControl extends AsyncTask<Context, Void, Location> {
    public Location alocation;
    private LocatoinManager locationManager;

    @Override
    public Location doInBackground(Context... params) {
         locationManager = (LocationManager) params[0].getSystemService(Context.LOCATION_SERVICE);        
          locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0, 0, locationListener);
        return alocation;
    }

    public LocationListener locationListener = new LocationListener() {

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

            public void onLocationChanged(android.location.Location mlocation) {
                saveLocation(mlocation);
                locationManager.removeUpdates(locationListener);
            }
    };  

    void saveLocation(android.location.Location location){
        alocation = location;   
    }

    @Override
    protected void onPostExecute(Location result) {
        useLocation(result);
        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        dialog.show(WasserSportLotse.this, " ", "Finding location...");

        super.onPreExecute();
    }
}   

所以我根据您的建议更改了代码,现在可以编译了。我已经更新了这里的代码来代表我正在运行的内容。当 locationManager 请求LocationUpdates 时出现运行时错误。这是logCat。有什么想法吗?

04-15 14:57:56.742: ERROR/AndroidRuntime(18328): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
04-15 14:57:56.942: ERROR/AndroidRuntime(18328): java.lang.RuntimeException: An error occured while executing doInBackground()
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:234)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:258)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.FutureTask.run(FutureTask.java:122)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:648)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:673)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.lang.Thread.run(Thread.java:1060)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.os.Handler.<init>(Handler.java:121)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:128)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:126)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.location.LocationManager._requestLocationUpdates(LocationManager.java:697)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.location.LocationManager.requestLocationUpdates(LocationManager.java:619)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at com.WasserSportLotse.WasserSportLotse$LocationControl.doInBackground(WasserSportLotse.java:62)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at com.WasserSportLotse.WasserSportLotse$LocationControl.doInBackground(WasserSportLotse.java:1)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:256)
04-15 14:57:56.942: ERROR/AndroidRuntime(18328):     ... 4 more
04-15 14:58:23.451: ERROR/AndroidRuntime(18356): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
04-15 14:58:23.642: ERROR/AndroidRuntime(18356): java.lang.RuntimeException: An error occured while executing doInBackground()
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:234)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:258)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.FutureTask.run(FutureTask.java:122)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:648)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:673)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.lang.Thread.run(Thread.java:1060)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.os.Handler.<init>(Handler.java:121)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:128)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:126)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.location.LocationManager._requestLocationUpdates(LocationManager.java:697)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.location.LocationManager.requestLocationUpdates(LocationManager.java:619)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at com.WasserSportLotse.WasserSportLotse$LocationControl.doInBackground(WasserSportLotse.java:62)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at com.WasserSportLotse.WasserSportLotse$LocationControl.doInBackground(WasserSportLotse.java:1)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:256)
04-15 14:58:23.642: ERROR/AndroidRuntime(18356):     ... 4 more

【问题讨论】:

    标签: android location android-asynctask


    【解决方案1】:
    public class FastMainActivity extends Activity {
    
        Button searchBtn = null;
        Intent locatorService = null;
        AlertDialog alertDialog = null;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            searchBtn = (Button) findViewById(R.id.searchBtn);
    
            searchBtn.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
    
                    if (!startService()) {
                        CreateAlert("Error!", "Service Cannot be started");
                    } else {
                        Toast.makeText(FastMainActivity.this, "Service Started",
                                Toast.LENGTH_LONG).show();
                    }
    
                }
            });
    
        }
    
        public boolean stopService() {
            if (this.locatorService != null) {
                this.locatorService = null;
            }
            return true;
        }
    
        public boolean startService() {
            try {
                // this.locatorService= new
                // Intent(FastMainActivity.this,LocatorService.class);
                // startService(this.locatorService);
    
                FetchCordinates fetchCordinates = new FetchCordinates();
                fetchCordinates.execute();
                return true;
            } catch (Exception error) {
                return false;
            }
    
        }
    
        public AlertDialog CreateAlert(String title, String message) {
            AlertDialog alert = new AlertDialog.Builder(this).create();
    
            alert.setTitle(title);
    
            alert.setMessage(message);
    
            return alert;
    
        }
    
        public class FetchCordinates extends AsyncTask<String, Integer, String> {
            ProgressDialog progDailog = null;
    
            public double lati = 0.0;
            public double longi = 0.0;
    
            public LocationManager mLocationManager;
            public VeggsterLocationListener mVeggsterLocationListener;
    
            @Override
            protected void onPreExecute() {
                mVeggsterLocationListener = new VeggsterLocationListener();
                mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    
                mLocationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER, 0, 0,
                        mVeggsterLocationListener);
    
                progDailog = new ProgressDialog(FastMainActivity.this);
                progDailog.setOnCancelListener(new OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        FetchCordinates.this.cancel(true);
                    }
                });
                progDailog.setMessage("Loading...");
                progDailog.setIndeterminate(true);
                progDailog.setCancelable(true);
                progDailog.show();
    
            }
    
            @Override
            protected void onCancelled(){
                System.out.println("Cancelled by user!");
                progDialog.dismiss();
                mLocationManager.removeUpdates(mVeggsterLocationListener);
            }
    
            @Override
            protected void onPostExecute(String result) {
                progDailog.dismiss();
    
                Toast.makeText(FastMainActivity.this,
                        "LATITUDE :" + lati + " LONGITUDE :" + longi,
                        Toast.LENGTH_LONG).show();
            }
    
            @Override
            protected String doInBackground(String... params) {
                // TODO Auto-generated method stub
    
                while (this.lati == 0.0) {
    
                }
                return null;
            }
    
            public class VeggsterLocationListener implements LocationListener {
    
                @Override
                public void onLocationChanged(Location location) {
    
                    int lat = (int) location.getLatitude(); // * 1E6);
                    int log = (int) location.getLongitude(); // * 1E6);
                    int acc = (int) (location.getAccuracy());
    
                    String info = location.getProvider();
                    try {
    
                        // LocatorService.myLatitude=location.getLatitude();
    
                        // LocatorService.myLongitude=location.getLongitude();
    
                        lati = location.getLatitude();
                        longi = location.getLongitude();
    
                    } catch (Exception e) {
                        // progDailog.dismiss();
                        // Toast.makeText(getApplicationContext(),"Unable to get Location"
                        // , Toast.LENGTH_LONG).show();
                    }
    
                }
    
                @Override
                public void onProviderDisabled(String provider) {
                    Log.i("OnProviderDisabled", "OnProviderDisabled");
                }
    
                @Override
                public void onProviderEnabled(String provider) {
                    Log.i("onProviderEnabled", "onProviderEnabled");
                }
    
                @Override
                public void onStatusChanged(String provider, int status,
                        Bundle extras) {
                    Log.i("onStatusChanged", "onStatusChanged");
    
                }
    
            }
    
        }
    
    }
    

    【讨论】:

    • @All 这是完美的代码 sn-p,用于在使用 Aysnc 任务和进度对话框时获取位置(GPS 坐标)。
    • +1。这是一个很好的例子,可以避免 Loopers,这可能会造成混淆。
    • 这段代码不在后台运行位置管理器,而是在 UI 线程中运行的 onPreExecute() 方法中。
    • @SpinalTapFan11 同意,它用一个简单的循环替换它,while (this.lati == 0.0) {}
    • @SALMAN 你能解释一下当 doInBackground() 方法只是循环(等待)什么都不做时异步任务的用途......并且所有工作负载都在 Ui 线程上
    【解决方案2】:

    在调用locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0, 0, locationListener);之前添加Looper.prepare() 之后记得调用 Looper.loop()。

    【讨论】:

    • 如果我想停止这个循环怎么办?
    【解决方案3】:

    首先解决您的编译问题, 移动

    LocationManager locationManager = (LocationManager)params[0].getSystemService(Context.LOCATION_SERVICE);        
    

    所以它是类的私有成员变量。

    LocationManager 不必在 AsyncTask 中。它不会占用 UI,所有更新都已经是异步的。这只会给您的项目增加不必要的复杂性。

    您可能只需将 useLocation 移至 onLockationChanged。

    【讨论】:

    • 我建议摆脱 AsyncTask。运行时错误可能会消失。
    • 这就是我最初让应用程序工作的方式,但是我有一个启动屏幕,我想在获得位置时显示一个对话框。执行此操作时对话框冻结。因此需要异步任务。
    • @Mike 你有解释LocationManager 如何异步工作的参考吗?我在参考页面上找不到任何关于它的内容。
    【解决方案4】:
    public Location getLocation() 
    {
    
        try 
        {
            locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
    
            // getting GPS status
            isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    
            // getting network status
            isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    
            if (!isGPSEnabled && !isNetworkEnabled) 
            {
                // no network provider is enabled
                Log.w("DOCOMO-2","Network Connection failed");
            } 
            else 
            {
                this.canGetLocation = true;
                // First get location from Network Provider
                if (isNetworkEnabled) 
                {
    
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    if (locationManager != null) 
                    {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) 
                        {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) 
                {
                    if (location == null) 
                    {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        if (locationManager != null) 
                        {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) 
                            {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
    
                        }
                    }
                }
            }
            locationManager=null;
            location=null;
    
        } 
        catch (Exception e) 
        {
            locationManager=null;
            location=null;
            e.printStackTrace();
        }
        return location;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 2011-06-25
      • 2016-10-02
      • 1970-01-01
      相关资源
      最近更新 更多