0

我正在使用谷歌地圖顯示一些標記。標記從數據庫中下載,同時,我從google api得到distancematrix,在用戶的當前位置和從數據庫中獲得的標記之間。我的用戶界面被使用AsyncTask與distancematrix和谷歌地圖屏蔽

我的問題是,我用不用彷徨這樣做,我bloking UI(我讀過,不用彷徨阻止用戶界面:

dataFromAsyncTask = testAsyncTask.get(); 

現在,我試圖做同樣的無阻塞用戶界面,但我沒有能夠得到在同一時間,或在一個好辦法,在距離該標記。

我很欣賞一些幫助,請。

這是我的代碼與我舊的和錯誤的.get:

for (City city : listCity.getData()) { 
     geoPoint = city.getLocation(); 
    nameBeach = city.getName(); 

    if (geoPoint == null) { 

    } else { 
     latitude = String.valueOf(geoPoint.getLatitude()); 
     longitude = String.valueOf(geoPoint.getLongitude()); 

     startRetrievenDistanceAndDuration(); 

     try { 
      dataFromAsyncTask = testAsyncTask.get(); 
     } catch (InterruptedException i) { 

     } catch (ExecutionException e) { 
     } 

     mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude())) 
       .title(nameCity) 
       .snippet(dataFromAsyncTask) 
       .icon(BitmapDescriptorFactory.defaultMarker())); 
    } 
} 

startRetrievenDistanceAndDuration方法:

private void startRetrievenDistanceAndDuration() { 
final String url; 

testAsyncTask = new DistanceBetweenLocations(new FragmentCallback() { 

    @Override 
    public void onTaskDone(String result) { 

    } 
}); 
url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxx"; 
testAsyncTask.execute(new String[]{url}); 
} 
public interface FragmentCallback { 
    public void onTaskDone(String result); 

的AsyncTask類:

 @Override 
     protected String doInBackground(String... params) { 
      HttpURLConnection urlConnection = null; 
      URL url = null; 
      StringBuilder result = null; 
      String duration = ""; 
      String distance = ""; 

      try { 
       url=new URL(params[0]); 
      }catch (MalformedURLException m){ 

      } 
      try { 
       urlConnection = (HttpURLConnection) url.openConnection(); 
      }catch (IOException e){} 

      try { 
       InputStream in = new BufferedInputStream(urlConnection.getInputStream()); 
       BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
       result = new StringBuilder(); 
       String line; 
       while((line = reader.readLine()) != null) { 
        result.append(line); 
       } 
      }catch (IOException e){ 

      } finally { 
       urlConnection.disconnect(); 
      } 

      try { 
       JSONObject jsonObject = new JSONObject(result.toString()); 
       JSONArray jsonArray = jsonObject.getJSONArray("rows"); 
       JSONObject object_rows = jsonArray.getJSONObject(0); 
       JSONArray jsonArrayElements = object_rows.getJSONArray("elements"); 
       JSONObject object_elements = jsonArrayElements.getJSONObject(0); 
       JSONObject object_duration = object_elements.getJSONObject("duration"); 
       JSONObject object_distance = object_elements.getJSONObject("distance"); 

       duration = object_duration.getString("text"); 
       distance = object_distance.getString("text"); 

      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 

      return distance + ", " + duration; 

     } 

     @Override 
     protected void onPostExecute(String result) { 
      mFragmentCallback.onTaskDone(result); 
     } 
} 

我試圖做到這一點,但我只是表達我的列表的最後一個標記:

在電話循環方法:

startRetrievenDistanceAndDuration(); 

而在onTaskDone儘量把盯防,但是隻拿到我名單的最後一個標記

@Override 
      public void onTaskDone(String result) { 
       mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude())) 
         .title(nameBeach) 
         .snippet(result) 
         .icon(BitmapDescriptorFactory.defaultMarker())); 

      } 

修訂更改後:(仍然不工作) 我可以的AsyncTask解析數據併發送它onPostExecute,但我只得到一個值,而不是9個價值觀,我有....

主要活動:

DistanceBetweenLocations task = new DistanceBetweenLocations(mlatituDouble, mlongitudeDouble){ 
        @Override 
        protected void onPostExecute(HashMap<String, String> result) { 
         super.onPostExecute(result); 

         String name = result.get("beachName"); 
         String distance = result.get("distance"); 
         String duration = result.get("duration"); 
         String latitue = result.get("latitude"); 
         String longitude = result.get("longitude"); 

         Double mlatituDouble = Double.parseDouble(latitue); 
         Double mlongitudeDouble = Double.parseDouble(longitude); 


         if (mMap == null) { 

          mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapView)) 
            .getMap(); 

           Toast.makeText(getActivity(), "mMap NO null", Toast.LENGTH_SHORT).show(); 
           mMap.addMarker(new MarkerOptions().position(new LatLng(mlatituDouble, mlongitudeDouble)) 
             .title(name) 
             .snippet(distance + " " + duration) 
             .icon(BitmapDescriptorFactory.defaultMarker())); 
         } 
        } 
       }; 

       task.execute(); 

的AsyncTask類:。

public class DistanceBetweenLocations extends AsyncTask<String, String, HashMap<String, String>> { 

    Double currentLatitude; 
    Double currentlongitude; 
    public BeachMap beachMap; 
    public BackendlessCollection<Beach> dataBeach; 
    public GoogleMap mMap; 
    String latitude; 
    String longitude; 
    HashMap<String, String> map; 

    public DistanceBetweenLocations(Double currentLatitude, Double currentlongitude){ 
     this.currentLatitude = currentLatitude; 
     this.currentlongitude = currentlongitude; 
    } 

    @Override 
    protected HashMap<String, String> doInBackground(String... params) { 

     dataBeach = beachMap.listBeach; 

     for (Beach city : dataBeach.getData()) { 
      GeoPoint geoPoint = city.getLocation(); 
      String nameBeach = city.getName(); 

      if (geoPoint == null) { 

      } else { 
       latitude = String.valueOf(geoPoint.getLatitude()); 
       longitude = String.valueOf(geoPoint.getLongitude()); 

       HttpURLConnection urlConnection = null; 
       URL url = null; 
       StringBuilder result = null; 
       String duration = ""; 
       String distance = ""; 

       try { 
        url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxxx"); 
       } catch (MalformedURLException m) { 

       } 
       try { 
        urlConnection = (HttpURLConnection) url.openConnection(); 
       } catch (IOException e) { 
       } 

       try { 
        InputStream in = new BufferedInputStream(urlConnection.getInputStream()); 
        BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
        result = new StringBuilder(); 
        String line; 
        while ((line = reader.readLine()) != null) { 
         result.append(line); 
        } 
       } catch (IOException e) { 

       } finally { 
        urlConnection.disconnect(); 
       } 

       try { 
        JSONObject jsonObject = new JSONObject(result.toString()); 
        JSONArray jsonArray = jsonObject.getJSONArray("rows"); 
        JSONObject object_rows = jsonArray.getJSONObject(0); 
        JSONArray jsonArrayElements = object_rows.getJSONArray("elements"); 
        JSONObject object_elements = jsonArrayElements.getJSONObject(0); 
        JSONObject object_duration = object_elements.getJSONObject("duration"); 
        JSONObject object_distance = object_elements.getJSONObject("distance"); 

        duration = object_duration.getString("text"); 
        distance = object_distance.getString("text"); 


        map = new HashMap<String, String>(); 
        map.put("beachName", nameBeach); 
        map.put("distance", distance); 
        map.put("duration", duration); 
        map.put("latitude", latitude); 
        map.put("longitude", longitude); 


       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     return map; 
    } 

} 

回答

1

我將使用您的上一個代碼(「 UPDATED OF CHANGES「),好嗎?

如果我把它做對,你的距離之間的位置結果將是一個海灘地理定位數據列表。因此,在for循環的每次迭代中,您正在替換「map」變量的值,這是您的問題。

解決你的問題,你可以有的HashMap的列表或POJO的的像這樣的列表:

public class BeachPojo { 
    private String beachName; 
    private String distance; 
    private String duration; 
    private String latitude; 
    private String longitude; 

    public String getBeachName() { 
     return beachName; 
    } 

    public void setBeachName(String beachName) { 
     this.beachName = beachName; 
    } 

    public String getDistance() { 
     return distance; 
    } 

    public void setDistance(String distance) { 
     this.distance = distance; 
    } 

    public String getDuration() { 
     return duration; 
    } 

    public void setDuration(String duration) { 
     this.duration = duration; 
    } 

    public String getLatitude() { 
     return latitude; 
    } 

    public void setLatitude(String latitude) { 
     this.latitude = latitude; 
    } 

    public String getLongitude() { 
     return longitude; 
    } 

    public void setLongitude(String longitude) { 
     this.longitude = longitude; 
    } 
} 

使用POJO的,您的AsyncTask將是這樣的:

public class DistanceBetweenLocations extends AsyncTask<String, String, List<BeachPojo>> { 

    Double currentLatitude; 
    Double currentlongitude; 
    public BeachMap beachMap; 
    public BackendlessCollection<Beach> dataBeach; 
    public GoogleMap mMap; 
    String latitude; 
    String longitude; 


    public DistanceBetweenLocations(Double currentLatitude, Double currentlongitude){ 
     this.currentLatitude = currentLatitude; 
     this.currentlongitude = currentlongitude; 
    } 

    @Override 
    protected List<BeachPojo> doInBackground(String... params) { 
     List<BeachPojo> list = new ArrayList<BeachPojo>(); 
     BeachPojo pojo; 

     dataBeach = beachMap.listBeach; 

     for (Beach city : dataBeach.getData()) { 
      GeoPoint geoPoint = city.getLocation(); 
      String nameBeach = city.getName(); 

      if (geoPoint == null) { 
      } else { 
       latitude = String.valueOf(geoPoint.getLatitude()); 
       longitude = String.valueOf(geoPoint.getLongitude()); 

       HttpURLConnection urlConnection = null; 
       URL url = null; 
       StringBuilder result = null; 
       String duration = ""; 
       String distance = ""; 

       try { 
        url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxxx"); 
       } catch (MalformedURLException m) { 

       } 

       try { 
        urlConnection = (HttpURLConnection) url.openConnection(); 
       } catch (IOException e) { 
       } 

       try { 
        InputStream in = new BufferedInputStream(urlConnection.getInputStream()); 
        BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
        result = new StringBuilder(); 
        String line; 
        while ((line = reader.readLine()) != null) { 
         result.append(line); 
        } 
       } catch (IOException e) { 

       } finally { 
        urlConnection.disconnect(); 
       } 

       try { 
        JSONObject jsonObject = new JSONObject(result.toString()); 
        JSONArray jsonArray = jsonObject.getJSONArray("rows"); 
        JSONObject object_rows = jsonArray.getJSONObject(0); 
        JSONArray jsonArrayElements = object_rows.getJSONArray("elements"); 
        JSONObject object_elements = jsonArrayElements.getJSONObject(0); 
        JSONObject object_duration = object_elements.getJSONObject("duration"); 
        JSONObject object_distance = object_elements.getJSONObject("distance"); 

        duration = object_duration.getString("text"); 
        distance = object_distance.getString("text"); 

        pojo = new BeachPojo(); 
        pojo.setBeachName(nameBeach); 
        pojo.setDistance(distance); 
        pojo.setDuration(duration); 
        pojo.setLatitude(latitude); 
        pojo.setLongitude(longitude); 

        list.add(pojo); 

       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     return list; 
    } 
} 

現在你有一個List來迭代。我已經調整了代碼一點點實現這一目標:

DistanceBetweenLocations task = new DistanceBetweenLocations(mlatituDouble, mlongitudeDouble){ 
    @Override 
    protected void onPostExecute(List<BeachPojo> result) { 
     super.onPostExecute(result); 

     if (mMap == null) { 
      mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapView)) 
        .getMap(); 
     } 

     Double beachLatitude; 
     Double beachLongitude; 

     for (BeachPojo pojo : result) { 
      beachLatitude = Double.parseDouble(pojo.getLatitude()); 
      beachLongitude = Double.parseDouble(pojo.getLongitude()); 

      mMap.addMarker(new MarkerOptions().position(new LatLng(beachLatitude, beachLongitude)) 
       .title(pojo.getBeachName()) 
       .snippet(pojo.getDistance() + " " + pojo.getDuration()) 
       .icon(BitmapDescriptorFactory.defaultMarker())); 
     } 
    } 
}; 

task.execute(); 

我希望你能理解您的AsyncTask和循環throught結果上onPostExecute方法返回一個列表的想法。

注意:這是一個不知道真實代碼的實現,那麼你應該適應你的實際。

0

我不完全確定你想要做什麼,但我認爲你已經使這更復雜,那麼它必須是。

據我所知,你有一個City對象的列表,你用它們來構造一些URL,從中檢索一個用來構造MarkerOptions對象的JSON對象。

你可以做到這一點使用AsyncTask這樣的:

public class Task extends AsyncTask<City, Void, Markers> { 

    String currentLatitude; 
    String currentlongitude; 

    public Task(String currentLatitude, String currentlongitude){ 
     this.currentLatitude = currentLatitude; 
     this.currentlongitude = currentlongitude; 
    } 

    @Override 
    protected String doInBackground(City... cities) { 
     final Markers mMap = ...; 
     for (City city : cities) { 
      GeoPoint geoPoint = city.getLocation(); 
      String nameBeach = city.getName(); 

      if (geoPoint != null) { 
       String latitude = String.valueOf(geoPoint.getLatitude()); 
       String longitude = String.valueOf(geoPoint.getLongitude()); 

       HttpURLConnection urlConnection = null; 
       BufferedReader reader = null; 
       try { 
        URL url = new URL("https://maps.googleapis.com/maps/api/distancematrix/json?origins=" + currentLatitude + "," + currentlongitude + "&destinations=" + latitude + "," + longitude + "&key=xxx";); 
        urlConnection = (HttpURLConnection) url.openConnection(); 
        reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); 
        StringBuilder result = new StringBuilder(); 
        String line; 
        while ((line = reader.readLine()) != null) { 
         result.append(line); 
        } 
        JSONObject jsonObject = new JSONObject(result.toString()).getJSONArray("rows").getJSONObject(0).getJSONArray("elements").getJSONObject(0); 
        String duration = jsonObject.getJSONObject("duration").getString("text"); 
        String distance = jsonObject.getJSONObject("distance").getString("text"); 

        mMap.addMarker(new MarkerOptions().position(new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude())) 
          .title(nameBeach) 
          .snippet(distance + ", " + duration) 
          .icon(BitmapDescriptorFactory.defaultMarker())); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } finally { 
        if(reader!=null){ 
         try { 
          reader.close(); 
         }catch (Exception e){ 
          e.printStackTrace(); 
         } 
        } 
        if (urlConnection != null) { 
         try { 
          urlConnection.disconnect(); 
         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
        } 
       } 
      } 
     } 

     return mMap; 
    } 
} 

這裏是你可以使用此任務。

public class Login extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(...); 
     Task task = new Task(currentLatitude, currentlongitude){ 
      @Override 
      protected void onPostExecute(Markers markers) { 
       super.onPostExecute(markers); 
       //This runs on the UI thread and "markers" is the "mMap" object that was create on the background thread. 
      } 
     }; 
     List<City> cities = .... 
     task.execute(cities.toArray(new City[cities.size()])); 
    } 
} 

的想法是,你需要在AsyncTaskdoInBackground(...)方法來執行所有的長時間運行的操作。另外,您不需要創建其他對象來處理AsyncTask響應,您可以在您創建任務的類中覆蓋任務的onPostExecute(...)

+0

感謝您的回答。有道理!但是,我的代碼出現了一個問題。可以返回Asynctask類一個GoogleMap對象(可以添加一個我需要創建一個Gmap對象的標記)我在doinbackground的返回中得到這個錯誤:必需的'String'創建'com.android ... GoogleMap'。 super.onPostExecute(markers)中的同樣問題;謝謝 – Simpson

+0

在onPostExecute(GoogleMaps標記)裏面還有一個問題,我不需要添加任何代碼?假定當任務完成這個方法時,把標記放在地圖上? – Simpson

+0

@Simpson我認爲你提到的第一個問題是因爲你沒有將類聲明爲'public class Task extends AsyncTask ',你可能使用過'public class Task extends AsyncTask <字符串,無效,字符串>'。 – Titus

相關問題