Android 从外部JSON获取Google地图标记

Android 从外部JSON获取Google地图标记,android,json,api,google-maps-android-api-2,Android,Json,Api,Google Maps Android Api 2,我正在为android开发一个地图应用程序(谷歌地图API 2),我的目标是两件事。在那里,我设法做了一些 1:居中并跟随用户的位置。(成功) 2:从外部JSON源获取标记并显示在地图上。以及不断更新自己的位置 我在这里找到了一段代码: 我把代码和来自1的代码放在一起。 函数1仍然有效,但是logcat说它找不到我指定的文件。那是因为它不存在。 我不知道JSON结构应该是什么样子,服务器端启用CORS来获取JSON应该不会有任何危险 然而,我想知道是否有人知道JSON结构应该是什么样子,因为我不

我正在为android开发一个地图应用程序(谷歌地图API 2),我的目标是两件事。在那里,我设法做了一些

1:居中并跟随用户的位置。(成功) 2:从外部JSON源获取标记并显示在地图上。以及不断更新自己的位置

我在这里找到了一段代码:

我把代码和来自1的代码放在一起。 函数1仍然有效,但是logcat说它找不到我指定的文件。那是因为它不存在。 我不知道JSON结构应该是什么样子,服务器端启用CORS来获取JSON应该不会有任何危险

然而,我想知道是否有人知道JSON结构应该是什么样子,因为我不知道如何理解它。此外,这段代码可能不起作用,因此,如果JSON结构完整,则可以更新问题,例如,标记不出现

JSON会是什么样子?我想不出来。

MainActivity.java

package com.billstrom.yolo;

import android.annotation.TargetApi;
import android.app.Dialog;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.widget.TextView;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
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.LatLng;
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.URL;

/**
 * 
 */

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class MainActivity extends FragmentActivity implements LocationListener {

    private static final String LOG_TAG = "Example";

    private static final String SERVICE_URL = "http://codele.se/app/blackcab/drivers.json";

    protected GoogleMap map;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setUpMapIfNeeded();

        // Getting Google Play availability status
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());

        // Showing status
        if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available

            int requestCode = 10;
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
            dialog.show();

        }else { // Google Play Services are available   

            // Getting reference to the SupportMapFragment of activity_main.xml
            SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

            // Getting GoogleMap object from the fragment
            map = fm.getMap();

            // Enabling MyLocation Layer of Google Map
            map.setMyLocationEnabled(true); 



             // Getting LocationManager object from System Service LOCATION_SERVICE
            LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

            // Creating a criteria object to retrieve provider
            Criteria criteria = new Criteria();

            // Getting the name of the best provider
            String provider = locationManager.getBestProvider(criteria, true);

            // Getting Current Location
            Location location = locationManager.getLastKnownLocation(provider);

            if(location!=null){
                    onLocationChanged(location);
            }

            locationManager.requestLocationUpdates(provider, 20000, 0, this);
        }

    }

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

     private void setUpMapIfNeeded() {
            if (map == null) {
                map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                        .getMap();
                if (map != null) {
                    setUpMap();
                }
            }
        }
     private void setUpMap() {
            // Retrieve the city data from the web service
            // In a worker thread since it's a network operation.
            new Thread(new Runnable() {
                public void run() {
                    try {
                        retrieveAndAddCities();
                    } catch (IOException e) {
                        Log.e(LOG_TAG, "Cannot retrive cities", e);
                        return;
                    }
                }
            }).start();
        }

        protected void retrieveAndAddCities() throws IOException {
            HttpURLConnection conn = null;
            final StringBuilder json = new StringBuilder();
            try {
                // Connect to the web service
                URL url = new URL(SERVICE_URL);
                conn = (HttpURLConnection) url.openConnection();
                InputStreamReader in = new InputStreamReader(conn.getInputStream());

                // Read the JSON data into the StringBuilder
                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();
                }
            }

            // Create markers for the city data.
            // Must run this on the UI thread since it's a UI operation.
            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 {
            // De-serialize the JSON string into an array of city objects
            JSONArray jsonArray = new JSONArray(json);
            for (int i = 0; i < jsonArray.length(); i++) {
                // Create a marker for each city in the JSON data.
                JSONObject jsonObj = jsonArray.getJSONObject(i);
                map.addMarker(new MarkerOptions()
                    .title(jsonObj.getString("name"))
                    .snippet(Integer.toString(jsonObj.getInt("population")))
                    .position(new LatLng(
                            jsonObj.getJSONArray("latlng").getDouble(0),
                            jsonObj.getJSONArray("latlng").getDouble(1)
                     ))
                );
            }
        }

    @Override
    public void onLocationChanged(Location location) {

        TextView tvLocation = (TextView) findViewById(R.id.tv_location);

        // Getting latitude of the current location
        double latitude = location.getLatitude();

        // Getting longitude of the current location
        double longitude = location.getLongitude();     

        // Creating a LatLng object for the current location
        LatLng latLng = new LatLng(latitude, longitude);

        // Showing the current location in Google Map
        map.moveCamera(CameraUpdateFactory.newLatLng(latLng));

        // Zoom in the Google Map
        map.animateCamera(CameraUpdateFactory.zoomTo(15));      


        // Setting latitude and longitude in the TextView tv_location
        tvLocation.setText("Latitude:" +  latitude  + ", Longitude:"+ longitude );      

    }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub      
    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub      
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub      
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}
最后答覆:

首先,作为一个建议,在Java中使用它非常容易,特别是如果您使用的是。因此,不要担心让服务器端数据与您在其他地方找到的代码样本完全匹配——在客户端上更改内容确实容易得多

记住
FileNotFoundException
。如果将来出现问题,即使在修复了你的页面之后,也会抛出并使你的应用程序崩溃。我个人不喜欢那个客户这样做,我更喜欢自己处理状态码。永远不要假设在QA中工作的http通信在生产过程中会一直保持完美:要防御性

在所有这些限制条件之后,您的json可能看起来像:
[{“name”:“bobbins driver”,“latlng”:[90180],“population”:“012345”},{“name”:“barbara”,“latlng”:[0,-180],“population”:“65432”}……]

有关
LatLng
是什么,请参见

至于你的后续行动,这个话题太宽泛了。现在,使用latlng参数执行许多地图分幅请求,并让服务器只发送附近的地图分幅。随着事情变得越来越有趣,如果你需要实时更新,有一些协议是为此设计的,或者你可以使用谷歌地图的“磁贴服务器”模式,以高磁贴刷新率-0作为开始,或者这可能是一个未来的问题

祝你好运。

最终答案:

首先,作为一个建议,在Java中使用它非常容易,特别是如果您使用的是。因此,不要担心让服务器端数据与您在其他地方找到的代码样本完全匹配——在客户端上更改内容确实容易得多

记住
FileNotFoundException
。如果将来出现问题,即使在修复了你的页面之后,也会抛出并使你的应用程序崩溃。我个人不喜欢那个客户这样做,我更喜欢自己处理状态码。永远不要假设在QA中工作的http通信在生产过程中会一直保持完美:要防御性

在所有这些限制条件之后,您的json可能看起来像:
[{“name”:“bobbins driver”,“latlng”:[90180],“population”:“012345”},{“name”:“barbara”,“latlng”:[0,-180],“population”:“65432”}……]

有关
LatLng
是什么,请参见

至于你的后续行动,这个话题太宽泛了。现在,使用latlng参数执行许多地图分幅请求,并让服务器只发送附近的地图分幅。随着事情变得越来越有趣,如果你需要实时更新,有一些协议是为此设计的,或者你可以使用谷歌地图的“磁贴服务器”模式,以高磁贴刷新率-0作为开始,或者这可能是一个未来的问题


祝你好运。

你能再说一遍你的问题吗,这样问题就清楚了?(顺便说一句,输出是完全正确的——正如您自己承认的那样,这段代码应该在这种情况下做到这一点。)谢谢。完成了,完成了!粗体字,现在不应该错过。哦,对了!我明白了,您已经复制了客户端的代码,现在希望相应地实现服务器端。嗯,这是一种新颖的方法;)。看起来有点像(“…”的意思是等等):
[{“name”:“bobbins driver”,“latlng”:[90180],“population”:“012345”},{“name”:“barbara”,“latlng”:[0,-180],“population”:“65432”}……]
但显然,如果你愿意,你可以在代码中更改它!不要害怕!LatLng的医生看起来很好,太好了D关于如何使其“实时”,从而使插针不断更新其位置,有什么想法吗?当然,但人们可以就此写一本书,对吗?通常,客户机和MapAPI的文档和教程可能会给出一些示例?从每n秒发出一次请求并刷新地图开始,然后也许是时候开始考虑更时髦的协议等了(事实上,这对以后的人来说是个不错的问题;)!)。你能再说一遍你的问题吗,这样就清楚了?(顺便说一句,输出是完全正确的——正如您自己承认的那样,这段代码应该在这种情况下做到这一点。)谢谢。完成了,完成了!粗体字,现在不应该错过。哦,对了!我明白了,您已经复制了客户端的代码,现在希望相应地实现服务器端。嗯,这是一种新颖的方法;)。看起来有点像(“…”的意思是等等):
[{“name”:“bobbins driver”,“latlng”:[90180],“population”:“012345”},{“name”:“barbara”,“latlng”:[0,-180],“population”:“65432”}……]
但显然,如果你愿意,你可以在代码中更改它!不要害怕!LatLng的医生看起来很好,太好了D关于如何使其“实时”,从而使插针不断更新其位置,有什么想法吗?当然,但人们可以就此写一本书,对吗?通常是客户和地图的文档和教程
07-01 16:27:40.787: E/Black Cab(17968): Error connecting to service
07-01 16:27:40.787: E/Black Cab(17968): java.io.FileNotFoundException: http://codele.se/app/blackcab/drivers.json
07-01 16:27:40.787: E/Black Cab(17968):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity.retrieveAndAddCities(MainActivity.java:133)
07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity$1.run(MainActivity.java:117)
07-01 16:27:40.787: E/Black Cab(17968):     at java.lang.Thread.run(Thread.java:856)
07-01 16:27:40.787: E/Black Cab(17968): Cannot retrive cities
07-01 16:27:40.787: E/Black Cab(17968): java.io.IOException: Error connecting to service
07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity.retrieveAndAddCities(MainActivity.java:143)
07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity$1.run(MainActivity.java:117)
07-01 16:27:40.787: E/Black Cab(17968):     at java.lang.Thread.run(Thread.java:856)
07-01 16:27:40.787: E/Black Cab(17968): Caused by: java.io.FileNotFoundException: http://codele.se/app/blackcab/drivers.json
07-01 16:27:40.787: E/Black Cab(17968):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
07-01 16:27:40.787: E/Black Cab(17968):     at com.billstrom.yolo.MainActivity.retrieveAndAddCities(MainActivity.java:133)
07-01 16:27:40.787: E/Black Cab(17968):     ... 2 more