使用异步任务获取当前位置

时间:2012-10-01 16:57:32

标签: android location

我试图使用异步任务获取当前位置此代码在没有异步任务的情况下工作正常但是当我尝试使用异步任务时它显示没有找到位置并且抱歉没有找到地址。这是我的代码plz帮我提前谢谢< / p>

public class MainActivity extends Activity {
/** Called when the activity is first created. */
String addressString;    
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
        new Getlocation().execute();    

}

//开始ASYNC任务

class Getlocation extends AsyncTask<String, String, String> {


    ProgressDialog p;

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub

       p = new ProgressDialog(MainActivity.this);                   
         p.setMessage("Please Wait Retrieving data..");     
         p.setTitle(" ");                                       
         p.setIcon(R.drawable.settings2);                       
         p.show();                                               
    }
    @Override
    protected String doInBackground(String... params) {
        Looper.prepare();

          LocationManager locationManager; 

            String context = Context.LOCATION_SERVICE; 
            locationManager = (LocationManager)getSystemService(context); 

            Criteria crta = new Criteria(); 
            crta.setAccuracy(Criteria.ACCURACY_FINE); 
            crta.setAltitudeRequired(false); 
            crta.setBearingRequired(false); 
            crta.setCostAllowed(true); 
            crta.setPowerRequirement(Criteria.POWER_LOW); 
            String provider = locationManager.getBestProvider(crta, true); 

         //String provider = LocationManager.GPS_PROVIDER; 
            Location location = locationManager.getLastKnownLocation(provider); 
            updateWithNewLocation(location); 
           LocationListener locationListener = new LocationListener() 
         { 

         @Override 
         public void onLocationChanged(Location location) { 
         updateWithNewLocation(location); 
         } 

         @Override 
         public void onProviderDisabled(String provider) { 
         updateWithNewLocation(null); 
         } 

         @Override 
         public void onProviderEnabled(String provider) { 
         } 

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

         };
         locationManager.requestLocationUpdates(provider, 2000, 10, locationListener); 
         Looper.loop();

        return addressString;
    }
     @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result); 
            p.dismiss();                    

    }   }
 private void updateWithNewLocation(Location location) { 
     String latLong;
     TextView myLocation; 
      addressString = "Sorry  No Address Found"; 
     if(location!=null) { 
    double lat = location.getLatitude(); 
     double lon = location.getLongitude(); 
     latLong = "Lat:" + lat + "\nLong:" + lon; 
     double lattitude = location.getLatitude(); 
     double longitude = location.getLongitude(); 
     Geocoder gc = new Geocoder(this,Locale.getDefault()); 
     try { 
     List<Address> addresses= gc.getFromLocation(lattitude, longitude, 1); 
     StringBuilder sb = new StringBuilder(); 
     if(addresses.size()>0) { 
     Address address=addresses.get(0);
     for(int i=0;i<address.getMaxAddressLineIndex();i++)
     sb.append(address.getAddressLine(i)).append("\n");
     sb.append(address.getLocality()).append("\n"); 
     sb.append(address.getPostalCode()).append("\n"); 
     sb.append(address.getCountryName()); 

     } 
     addressString = sb.toString(); 
     } 
     catch (Exception e) { 
     } 
     } else { 
     latLong = " NO Location Found "; 
     } 
Toast.makeText(getApplicationContext(), "Current Position is :\n"+ latLong + "\n"+  addressString ,Toast.LENGTH_LONG).show();
  //  myLocation.setText("Current Position is :\n"+ latLong + "\n"+  addressString ); 
        }

}

//这是我的logcat

    10-01 22:34:13.720: E/WindowManager(2868): Activity com.example.sc.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@411dd3c8 that was originally added here
10-01 22:34:13.720: E/WindowManager(2868): android.view.WindowLeaked: Activity com.example.sc.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@411dd3c8 that was originally added here
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:374)
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:292)
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.Window$LocalWindowManager.addView(Window.java:547)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.Dialog.show(Dialog.java:277)
10-01 22:34:13.720: E/WindowManager(2868):  at com.example.sc.MainActivity$Getlocation.onPreExecute(MainActivity.java:68)
10-01 22:34:13.720: E/WindowManager(2868):  at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
10-01 22:34:13.720: E/WindowManager(2868):  at android.os.AsyncTask.execute(AsyncTask.java:534)
10-01 22:34:13.720: E/WindowManager(2868):  at com.example.sc.MainActivity.onCreate(MainActivity.java:51)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.Activity.performCreate(Activity.java:5008)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
10-01 22:34:13.720: E/WindowManager(2868):  at android.os.Handler.dispatchMessage(Handler.java:99)
10-01 22:34:13.720: E/WindowManager(2868):  at android.os.Looper.loop(Looper.java:137)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread.main(ActivityThread.java:4745)
10-01 22:34:13.720: E/WindowManager(2868):  at java.lang.reflect.Method.invokeNative(Native Method)
10-01 22:34:13.720: E/WindowManager(2868):  at java.lang.reflect.Method.invoke(Method.java:511)
10-01 22:34:13.720: E/WindowManager(2868):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
10-01 22:34:13.720: E/WindowManager(2868):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-01 22:34:13.720: E/WindowManager(2868):  at dalvik.system.NativeStart.main(Native Method)

2 个答案:

答案 0 :(得分:1)

这看起来像经典的“在非Looper线程中创建处理程序”例外。基本上,您正在创建一个Handler,用于接收LocationListener对象的位置消息,该对象是在其自己的线程中创建的。方法返回后,运行doInBackground()的线程将立即死亡。因此,LocationManager将数据发送到死线程中的死对象,并且您将获得异常。

Loopers的一个好样本就在这里:

What is the purpose of Looper and how to use it?

如果您将Looper.prepare()放在doInBackground()的顶部并将Looper.loop()放在底部,则可以继续使用AsyncTask。 Looper.loop()只是一个空的while循环,可以让你的线程永远打开。

为了让它死掉,你必须在你的线程中调用Looper.myLooper()。quit()来杀死它。最简单的方法是在Looper.prepare()之后立即执行此操作。 ,通过调用Looper.myLoop()保存Looper。然后在要停止更新时要调用的方法中将其终止。

class LooperAsyncTask extends AsyncTask<Void, Void, Void> {

    private mThreadLooper;

    @Override
    protected String doInBackground(String... params) {
      Looper.prepare();
      mThreadLooper = Looper.myLooper();
      **setup code**
      Looper.loop();
    }

    public void stopUpdates() {
      **cleanup code**
      if(mThreadLooper != null)
        mThreadLooper.quit();
    }
}

答案 1 :(得分:0)

您的LocationManager和LocationListener不需要位于AsyncTask中。它们应该在Activity中(如果你想在Activity之间共享它们,那么它应该是Activity引用的其他类。)

在AsyncTask中注册LocationListener并不是正确的方法,因为该侦听器会因AsyncTask而死,因此无法监听更新。

顺便提一下,你的updateWithNewLocation()方法正在创建一个它没有使用的TextView。

通过在updateWithNewLocation()中调用Toast,你有效地在doInBackground中调用它而不在UI线程上运行,所以除非你在实例化AsyncTask时传入一个上下文,否则Toast将很难设置

如果这是一个缓慢的过程,那么当您的Activity捕获位置更改然后通过将doInBackground反向地理编码的结果传递给onPostExecute来显示Toast(或更新TextView)时,您可以在AsyncTask中反转地理编码它可以在UI线程上运行,因此可以安全轻松地更新视图并显示Toasts。

class ReverseGeocodeAsyncTask extends AsyncTask<Void, Void, Void> {

    private Location location;

    public ReverseGeocodeAsyncTask(Location l) { location = l; }

    @Override
    protected String doInBackground(String... params) {
     //do reverse geocoding and return the result
    }

     @Override
     protected void onPostExecute(String result) {
        // update the UI with the result of the reverse geocoding                   
    }
}