如何在获取XML文件中实现AsyncTask以在Google Maps Android API v2中显示自定义标记?

时间:2013-02-04 10:24:24

标签: android google-maps google-maps-markers google-maps-android-api-2 google-maps-mobile

我目前正在开发一款使用Google Maps API v2的Android应用。我正在显示外部XML文件中的自定义标记:http://dds.orgfree.com/DDS/landmarks_genxmlv2.php,它将在地图中显示一些地标。

正如您在下面的代码中所看到的,我在实际手机中测试此应用时使用StrictMode来避免NetworkOnMainThreadException。我知道使用这种方法是不可取的。它应该通过AsyncTask在单独的线程和后台完成。我尝试在这个应用程序中实现AsyncTask但我没有运气。任何人都可以帮我提供我的代码或提供一些有用的建议吗?非常感谢。

public class MapViewActivity extends android.support.v4.app.FragmentActivity {

    static final LatLng CITYHALL = new LatLng(07.0644444, 125.6077778);
    private GoogleMap mMap;

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

        setUpMapIfNeeded();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mapview_options_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.normal_mapstyle) {
            mMap.setMapType(MAP_TYPE_NORMAL);
        } else if (item.getItemId() == R.id.hybrid_mapstyle) {
            mMap.setMapType(MAP_TYPE_HYBRID);
        } else if (item.getItemId() == R.id.satellite_mapstyle) {
            mMap.setMapType(MAP_TYPE_SATELLITE);
        } else if (item.getItemId() == R.id.terrain_mapstyle) {
            mMap.setMapType(MAP_TYPE_TERRAIN);
        }

        return super.onOptionsItemSelected(item);
    }

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

    private void setUpMapIfNeeded() {

        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map)).getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    private void setUpMap() {

        Document doc = null;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            doc = builder
                    .parse("http://dds.orgfree.com/DDS/landmarks_genxmlv2.php");
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        NodeList markers = doc.getElementsByTagName("marker");

        try {
            for (int i = 0; i < markers.getLength(); i++) {
                Element item = (Element) markers.item(i);
                String name = item.getAttribute("name");
                String address = item.getAttribute("address");
                String stringLat = item.getAttribute("lat");
                String stringLng = item.getAttribute("lng");
                String icon = item.getAttribute("icon");
                Double lat = Double.valueOf(stringLat);
                Double lng = Double.valueOf(stringLng);

                mMap = ((SupportMapFragment) getSupportFragmentManager()
                        .findFragmentById(R.id.map)).getMap();

                mMap.addMarker(new MarkerOptions()
                        .position(new LatLng(lat, lng))
                        .title(name)
                        .snippet(address)
                        .icon(BitmapDescriptorFactory.fromAsset(new String(icon
                                + ".png"))));

                // Move the camera instantly to City Hall with a zoom of 15.
                mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CITYHALL, 15));
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
    }
}

这是我尝试过的。

public class MapViewActivity extends android.support.v4.app.FragmentActivity {

    static final LatLng CITYHALL = new LatLng(07.0644444, 125.6077778);
    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_mapview);
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                .permitAll().build();

        StrictMode.setThreadPolicy(policy);
        setUpMapIfNeeded();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mapview_options_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.map_menu_showlegend) {
            Log.d("MENU", "Show Legend was CLICKED!");
        } else if (item.getItemId() == R.id.map_menu_maptype) {
            Log.d("MENU", "Map Type was CLICKED!");
        } else if (item.getItemId() == R.id.normal_mapstyle) {
            Log.d("MENU", "MAP_TYPE_NORMAL was CLICKED!");
            mMap.setMapType(MAP_TYPE_NORMAL);
        } else if (item.getItemId() == R.id.hybrid_mapstyle) {
            Log.d("MENU", "MAP_TYPE_HYBRID was CLICKED!");
            mMap.setMapType(MAP_TYPE_HYBRID);
        } else if (item.getItemId() == R.id.satellite_mapstyle) {
            Log.d("MENU", "MAP_TYPE_SATELLITE was CLICKED!");
            mMap.setMapType(MAP_TYPE_SATELLITE);
        } else if (item.getItemId() == R.id.terrain_mapstyle) {
            Log.d("MENU", "MAP_TYPE_TERRAIN was CLICKED!");
            mMap.setMapType(MAP_TYPE_TERRAIN);
        }

        return super.onOptionsItemSelected(item);
    }

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

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the
        // map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map)).getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    private Boolean isOnline() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        if (ni != null && ni.isConnected())
            return true;

        return false;
    }

    private void setUpMap() {
        new ParseXML().execute();
    }

    private class ParseXML extends AsyncTask<Void, Void, Document> {
        Document doc = null;

        @Override
        protected Document doInBackground(Void... params) {

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }

            if (isOnline()) {

                try {
                    DocumentBuilderFactory factory = DocumentBuilderFactory
                            .newInstance();
                    DocumentBuilder builder = factory.newDocumentBuilder();
                    doc = builder
                            .parse("http://dds.orgfree.com/DDS/landmarks_genxmlv2.php");
                } catch (ParserConfigurationException e) {
                    e.printStackTrace();
                } catch (SAXException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                NodeList markers = doc.getElementsByTagName("marker");

                try {
                    for (int i = 0; i < markers.getLength(); i++) {
                        Element item = (Element) markers.item(i);
                        String name = item.getAttribute("name");
                        String address = item.getAttribute("address");
                        String stringLat = item.getAttribute("lat");
                        String stringLng = item.getAttribute("lng");
                        String icon = item.getAttribute("icon");
                        Double lat = Double.valueOf(stringLat);
                        Double lng = Double.valueOf(stringLng);

                        mMap = ((SupportMapFragment) getSupportFragmentManager()
                                .findFragmentById(R.id.map)).getMap();

                        mMap.addMarker(new MarkerOptions()
                                .position(new LatLng(lat, lng))
                                .title(name)
                                .snippet(address)
                                .icon(BitmapDescriptorFactory
                                        .fromAsset(new String(icon + ".png"))));

                        // Move the camera instantly to City Hall with a zoom of
                        // 15.
                        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
                                CITYHALL, 15));
                    }
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }
            } else {
                Toast.makeText(MapViewActivity.this, "No connection..",
                        Toast.LENGTH_LONG).show();
            }

            return doc;
        }

        @Override
        protected void onPostExecute(Document doc) {
            super.onPostExecute(doc);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您无法从后台线程更改UI 因此,将更改UI的所有内容移至onPostExecute()方法。 我今天已经用代码示例回答了同样的问题:Android disable button on successful doinbackground call