2012-10-01 71 views
0

我試圖使用異步任務獲取當前位置此代碼工作正常,沒有異步任務,但是當我嘗試與異步任務它顯示沒有找到位置和對不起沒有地址found.here是我的代碼PLZ幫我在此先感謝使用異步任務獲取當前位置

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();  

}

//起動異步任務

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 [email protected] 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 [email protected] 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) 
+0

LogCat說什麼? –

+0

您需要發佈LogCat錯誤以便任何人都能夠爲您提供幫助。我的第一個猜測是,你沒有添加在你的Android清單中使用位置的權限xml –

+0

@ PaulD'Ambra我已經添加了所有需要的權限,它在工作我一般的主線程,它涉及到異步它不工作 –

回答

1

這看起來像經典的「在非Looper線程中創建處理程序」異常。基本上,您正在創建一個處理程序,它接收位置消息到您自己的線程中創建的LocationListener對象。只要方法返回,運行doInBackground()的線程就會死亡。因此,LocationManager正在將數據發送到死線程中的死對象,並且您會收到異常。

上活套一個很好的樣本是在這裏:

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(); 
    } 
} 
+0

我認爲將AsynTask更改爲Service或IntentService以強制更新位置會更好。您仍然可以使用上面的代碼來獲取getLastKnownLocation,如果任何位置提供程序與您的Criteria不匹配,您也必須添加check not null。 –

+0

即時通訊沒有得到plz發佈的代碼與所需的修改PLZ,看到我的新的未決問題 –

+0

即時檢查(位置!=空) –

0

您的LocationManager和LocationListener不需要在AsyncTask中。他們應該在Activity中(或者如果你想在活動之間分享它們的活動所引用的某個其他類)。

在AsyncTask中註冊LocationListener不是正確的方法,因爲該偵聽器與AsyncTask一起死亡,所以不會在監聽更新。

順便提一句,您的updateWithNewLocation()方法正在創建一個它未使用的TextView。

通過在updateWithNewLocation()中調用Toast,您可以在doInBackground中有效地調用它,因爲它並未在UI線程上運行,所以除非您在實例化AsyncTask時傳遞上下文,否則Toast將很難設置。

如果它是一個緩慢的過程,那麼你可以通過將doInBackground結果反向地理編碼在的AsyncTask反向地理當你的活動捕獲的位置變化,然後顯示一個麪包(或更新的TextView),以onPostExecute它不運行在UI線程上,因此可以安全,方便地更新視圖並顯示Toast。

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     
    } 
} 
+0

對不起,我沒有得到你會請你張貼代碼與所需的修改thnaku –