2011-04-15 55 views
3

我正在试图找到一个很好的解决方案来解决这个问题。我做了我的应用程序,以便找到我的位置。看起来过于复杂但很容易。然而,下面的谷歌推荐我现在试图运行这个代码作为异步任务,所以它不会绑定用户界面。然而,我甚至无法弄清楚如何让编译的代码放在实际运行的位置。错误是,当我引用它去除侦听器时,locationManager无法解析。我尝试使用这里发布的代码Android find GPS location once, show loading dialog。然而,在这个例子中,currentLocation似乎没有被引用到任何东西,我遇到了问题,试图将其排除。我已经浪费了将近一整天的时间来尝试解决这个问题,所以如果有人能指出我正确的方向,我将不胜感激。如何使用AsyncTask获取位置

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 requestsLocationUpdates时遇到运行时错误。这是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 

回答

25
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"); 

      } 

     } 

    } 

} 
+4

@All这是完美的代码片段,用于在使用Aysnc任务和进度对话框时获取位置(GPS坐标)。 – SALMAN 2011-07-22 10:15:13

+0

+1。这是避免Loopers的一个很好的例子,这可能会让人困惑。 – rmigneco 2014-03-24 00:44:59

+4

此代码不会在后台运行位置管理器,但会在UI线程中运行的onPreExecute()方法中运行。 – 2014-05-06 17:02:39

1

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

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

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

LocationManager不必位于AsyncTask中。它不捆绑用户界面,所有更新已经是异步的。这只会给您的项目增加不必要的复杂性。

您可能只需将useLocation移动到onLockationChanged。

+0

谢谢,这工作,但我现在有一个运行时错误 – jiduvah 2011-04-15 13:05:23

+0

我建议摆脱AsyncTask。运行时错误可能会消失。 – 2011-04-15 13:07:45

+0

这就是我原本应用程序的工作原理,但我有一个启动画面,我想在显示位置时显示一个对话框。这样做时对话框冻结了。因此需要asyntask。 – jiduvah 2011-04-15 13:13:17

0
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; 
} 
3

调用locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0, 0, locationListener); 记住()之后调用Looper.loop前只需添加Looper.prepare()

+0

omg它的工作原理。谢谢。 – Anderson 2016-08-02 02:40:23

+0

如果我想停止这个循环呢? – Anderson 2016-08-02 03:02:44