2016-06-02 1 views
0

Ich implementiere Google Maps in meinem Android-Projekt, die JSON-Daten aus einer URL zum Zeichnen von Markierungen in der Karte abruft, auch hat eine Suchoption mit Autovervollständigen-Adressen von Google Places API Hier sind meine Codes.Verwenden von JSON und Erstellen von Markierungen für Android Maps API-Ladezeit

import android.content.Context; 
import android.content.Intent; 
import android.location.Address; 
import android.location.Geocoder; 
import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.util.Log; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.AutoCompleteTextView; 
import android.widget.Button; 
import android.widget.Filter; 
import android.widget.Filterable; 
import android.widget.TextView; 

import com.google.android.gms.appindexing.AppIndex; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.maps.CameraUpdate; 
import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.SupportMapFragment; 
import com.google.android.gms.maps.model.BitmapDescriptorFactory; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.Marker; 
import com.google.android.gms.maps.model.MarkerOptions; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.net.URLEncoder; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 


public class MapsActivity extends FragmentActivity implements AdapterView.OnItemClickListener { 

    LocationAddress add=new LocationAddress(); 
    DashboardActivity dObj=new DashboardActivity(); 

    public void onClickHome (View v) 
    { 
     final Intent intent = new Intent(getApplicationContext(), DashboardActivity.class); 
     startActivity(intent); 
    } 

    class MyInfoWindowAdapter implements GoogleMap.InfoWindowAdapter { 

     private final View myContentsView; 

     MyInfoWindowAdapter(){ 
      myContentsView = getLayoutInflater().inflate(R.layout.custom_info_contents, null); 
     } 

     @Override 
     public View getInfoContents(Marker arg0) { 
      displayView(arg0); 
      return myContentsView; 
     } 

     @Override 
     public View getInfoWindow(Marker arg0) { 

      return null; 
     } 

     public void displayView(Marker arg0) { 

      String[] contents=arg0.getTitle().split("@"); 
      String title=contents[0]; 
      String address=contents[1]; 

      ((TextView)myContentsView.findViewById(R.id.title)).setText(title); 
      ((TextView)myContentsView.findViewById(R.id.snippet)).setText(address); 

     } 

    } 

    private static final String LOG_TAG = "myApp"; 
    private static final String SERVICE_URL = "JSON_DATA_URL"; 
    private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place"; 
    private static final String TYPE_AUTOCOMPLETE = "/autocomplete"; 
    private static final String OUT_JSON = "/json"; 

    //------------ make your specific key ------------ 
    private static final String API_KEY = "AIzaSyDKUpzHkox5q5-pcNYmRS-UT7izEvd6WtQ"; 

    protected GoogleMap map; 
    private GoogleApiClient client; 
    TextView latlongLocation; 
    Marker marker; 
    Button clear; 
    AutoCompleteTextView autoCompView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_maps); 
     setUpMapIfNeeded(); 
     setTitleFromActivityLabel(R.id.title_text); 

     client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build(); 

     autoCompView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView); 
     autoCompView.setAdapter(new GooglePlacesAutocompleteAdapter(this, R.layout.list_item)); 
     autoCompView.setOnItemClickListener(this); 

     clear=(Button)findViewById(R.id.clear); 
     clear.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       autoCompView.setText(""); 
      } 
     }); 

    } 


    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { 
     String str = (String) adapterView.getItemAtPosition(position); 
     Geocoder geocoder = new Geocoder(getApplicationContext()); 
     List<Address> addresses = null; 
     try 
     { 

     // removeSearchMarker(); 
      addresses = geocoder.getFromLocationName(str, 3); 
      if (addresses != null && !addresses.equals("")) 
       search(addresses); 

     } 
     catch (Exception e) { 

     } 
    } 

    public static ArrayList<String> autocomplete(String input) { 
     ArrayList<String> resultList = null; 

     HttpURLConnection conn = null; 
     StringBuilder jsonResults = new StringBuilder(); 
     try { 
      StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON); 
      sb.append("?key=" + API_KEY); 
      sb.append("&language" + "fa"); 
      sb.append("&components=country:af"); 
      sb.append("&input=" + URLEncoder.encode(input, "utf8")); 

      URL url = new URL(sb.toString()); 

      System.out.println("URL: "+url); 
      conn = (HttpURLConnection) url.openConnection(); 
      InputStreamReader in = new InputStreamReader(conn.getInputStream()); 

      int read; 
      char[] buff = new char[1024]; 
      while ((read = in.read(buff)) != -1) { 
       jsonResults.append(buff, 0, read); 
      } 
     } catch (MalformedURLException e) { 
      Log.e(LOG_TAG, "Error processing Places API URL", e); 
      return resultList; 
     } catch (IOException e) { 
      Log.e(LOG_TAG, "Error connecting to Places API", e); 
      return resultList; 
     } finally { 
      if (conn != null) { 
       conn.disconnect(); 
      } 
     } 

     try { 
      JSONObject jsonObj = new JSONObject(jsonResults.toString()); 
      JSONArray predsJsonArray = jsonObj.getJSONArray("predictions"); 
      resultList = new ArrayList<String>(predsJsonArray.length()); 
      for (int i = 0; i < predsJsonArray.length(); i++) { 
       System.out.println(predsJsonArray.getJSONObject(i).getString("description")); 
       System.out.println("============================================================"); 
       resultList.add(predsJsonArray.getJSONObject(i).getString("description")); 
      } 
     } catch (JSONException e) { 
      Log.e(LOG_TAG, "Cannot process JSON results", e); 
     } 

     return resultList; 
    } 

    class GooglePlacesAutocompleteAdapter extends ArrayAdapter<String> implements Filterable { 
     private ArrayList<String> resultList; 

     public GooglePlacesAutocompleteAdapter(Context context, int textViewResourceId) { 
      super(context, textViewResourceId); 
     } 

     @Override 
     public int getCount() { 
      return resultList.size(); 
     } 

     @Override 
     public String getItem(int index) { 
      return resultList.get(index); 
     } 

     @Override 
     public Filter getFilter() { 
      Filter filter = new Filter() { 
       @Override 
       protected FilterResults performFiltering(CharSequence constraint) { 
        FilterResults filterResults = new FilterResults(); 
        if (constraint != null) { 
         resultList = autocomplete(constraint.toString()); 
         filterResults.values = resultList; 
         filterResults.count = resultList.size(); 
        } 
        return filterResults; 
       } 

       @Override 
       protected void publishResults(CharSequence constraint, FilterResults results) { 
        if (results != null && results.count > 0) { 
         notifyDataSetChanged(); 
        } else { 
         notifyDataSetInvalidated(); 
        } 
       } 
      }; 
      return filter; 
     } 
    } 

    protected void search(List<Address> addresses) { 

    Address address = (Address) addresses.get(0); 
    LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude()); 

    // String addressText = String.format("%s, %s", address.getMaxAddressLineIndex() > 0 ? address.getAddressLine(0) : "", address.getCountryName()); 

    map.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 
    map.animateCamera(CameraUpdateFactory.zoomTo(14)); 
    latlongLocation.setText("Latitude:" + address.getLatitude() + ", Longitude:" + address.getLongitude()); 
    // map.setInfoWindowAdapter(new MyInfoWindowAdapter()); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     setUpMapIfNeeded(); 
    } 

    @Override 
    protected void onPause() { 
     setUpMapIfNeeded(); 
     super.onPause(); 
    } 

    @Override 
    protected void onRestart() { 
     setUpMapIfNeeded(); 
     super.onRestart(); 
    } 

    @Override 
    protected void onDestroy() { 
     map=null; 
     super.onDestroy(); 
    } 


    private void setUpMapIfNeeded() { 
     if (map == null) { 
      map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) 
        .getMap(); 
      if (map != null) { 
       setUpMap(); 
      } 
     } 
    } 

    private void setUpMap() { 
     LatLng origin = new LatLng(34.520299, 69.179912); 
     CameraUpdate panToOrigin = CameraUpdateFactory.newLatLng(origin); 
     map.moveCamera(panToOrigin); 
     map.animateCamera(CameraUpdateFactory.zoomTo(13), 400, null); 
     map.getUiSettings(); 
     map.getUiSettings().setZoomControlsEnabled(true); 
     map.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
     map.setMyLocationEnabled(true); 
     map.setInfoWindowAdapter(new MyInfoWindowAdapter()); 

     new Thread(new Runnable() { 
      public void run() { 
       try { 
        retrieveLocations(); 
       } catch (IOException e) { 
        Log.e(LOG_TAG, "Cannot retrive locations", e); 
        return; 
       } 
      } 
     }).start(); 
    } 

    protected void retrieveLocations() throws IOException { 
     HttpURLConnection conn = null; 
     final StringBuilder json = new StringBuilder(); 
     try { 
      URL url = new URL(SERVICE_URL); 
      conn = (HttpURLConnection) url.openConnection(); 
      InputStreamReader in = new InputStreamReader(conn.getInputStream()); 

      int read; 
      char[] buff = new char[1024]; 
      while ((read = in.read(buff)) != -1) { 
       json.append(buff, 0, read); 
      } 
     } catch (IOException e) { 
      Log.e(LOG_TAG, "Error connecting to service", e); 
      throw new IOException("Error connecting to service", e); 
     } finally { 
      if (conn != null) { 
       conn.disconnect(); 
      } 
     } 

     runOnUiThread(new Runnable() { 
      public void run() { 
       try { 
        createMarkersFromJson(json.toString()); 
       } catch (JSONException e) { 
        Log.e(LOG_TAG, "Error processing JSON", e); 
       } 
      } 
     }); 
    } 

    void createMarkersFromJson(String json) throws JSONException { 

     JSONArray jsonArray = new JSONArray(json); 
     for (int i = 0; i < jsonArray.length(); i++) { 
      JSONObject jsonObj = jsonArray.getJSONObject(i); 
      String address=add.getAddressFromLocation(jsonObj.getDouble("geolat"), jsonObj.getDouble("geolng"), getApplicationContext()); 

      String date=jsonObj.getString("posted_date"); 
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
      Date testDate=null; 
      try{ 
       testDate=sdf.parse(date); 
      }catch (Exception ex){ 
       ex.printStackTrace(); 
      } 
      sdf=new SimpleDateFormat("EEE, d MMM yyyy HH:mm aa"); 
      date=sdf.format(testDate); 
      map.addMarker(new MarkerOptions() 
          .title(address.toString()+"@"+date) 
          .position(new LatLng(jsonObj.getDouble("geolat"), jsonObj.getDouble("geolng") 
          )) 
          .icon(BitmapDescriptorFactory.fromResource(R.drawable.icon3)) 
      ); 

     } 
    } 

    public void setTitleFromActivityLabel (int textViewId) 
    { 
     TextView tv = (TextView) findViewById (textViewId); 
     if (tv != null) tv.setText (getTitle()); 
    } 

} 

Diese Codes korrekt funktionieren Marker von JSON-Daten in Karten zu zeichnen, aber das Problem ist, dass wenn ich diese Tätigkeit beginnen, es zu viel Zeit in Anspruch nimmt ist die Karte und Markierungen und während dieser Zeit alles angezeigt werden wie gefrorene i kann nicht zurück gehen oder nach Hause und wenn ich viele Male auf irgendwelche screan Komponenten klicke, stürzt seine Anwendung ab.

Die Anzahl der JSON-Datensätze, die createMarkersFromJson-Methode durchläuft, um Marker zu erstellen, z. B. 40-50 Datensätze, und es gibt Erweiterungsmöglichkeiten. Also meine Frage ist, was ist der Grund für dieses Problem und gibt es andere Möglichkeit, Markierungen in der Karte schnell ohne Absturz der Anwendung anzuzeigen ?.

Ich sollte erwähnen, dass ich neu Android-Entwicklung bin, Jede Hilfe wäre sehr geschätzt. Vielen Dank im Voraus!

+0

Ich sehe, dass Sie immer noch 'getMap()' verwenden. Sie implementieren Ihren Code mit veralteten Funktionen. Ich schlage vor, den [Android Google Maps Quickstart] (https://developers.google.com/maps/documentation/android-api/start#step_1_download_android_studio) zu durchlaufen, dort sehen Sie, dass [getMapAsync()] (https://developers.google.com/android/reference/com/google/android/gms/maps/MapFragment.html#public-methods) ist die neue Version. Sie können auch in der Community nach ähnlichen Posts suchen. Prost! –

+0

Vielen Dank für Ihre Antwort @ McAwesomville, ich würde mich freuen, wenn Sie mir ein Beispiel dazu liefern könnten. – Angel

+0

Der Schnellstart, den ich verlinkt habe, enthält die offiziellen Beispielcodes. –

Antwort

1

Wie in der Android guidelines Ich glaube, Sie sollten AsyncTask für "retrieveLocations" anstelle der Erstellung eines Threads auf eigene connect to a network..

+0

+1 Einfach und vor Ort zu beantworten. Gut gemacht. Es wäre auch gut, wenn Sie die *** Android Richtlinien *** verbinden könnten, die Sie in Ihrem Beitrag erwähnt haben –

+0

danke für Ihre Antwort @Amit werde ich die Richtlinien befolgen und versuchen, AsyncTask zu implementieren, wenn Sie mir den Link zur Verfügung stellen könnten von irgendeinem Beispiel, das Standortinformationen vom Server abruft und als Markierungen auf diese Weise anzeigt, die Sie erwähnten, würde fantastisch sein. – Angel

+0

Ich verwendete AsyncTask, aber es dauert immer noch die gleiche Zeit zum Laden von Markern @Amit – Angel

Verwandte Themen