Android GoogleMaps V2 MarkerDemo IllegalStateExcep

2019-04-09 21:00发布

I am creating a customised implementation of the MarkerDemo provided for GoogleMaps V2. I have a strange error whereby I am providing LatLng values to a LatLngBounds.Builder instance and then passing it as a variable with .build. When I run the app in Debug mode through Eclipse, the Map loads. When I run it normally through Eclipse, there is an IllegalStateException thrown with "no included points" as a message. Can anyone help?

Here is some code to assist.

public class MyActivity extends android.support.v4.app.FragmentActivity
        implements OnMarkerClickListener, OnInfoWindowClickListener,
        OnMarkerDragListener {

    private HashMap<DataItem, ArrayList<DataItem>> mUserLocations = new
             HashMap<DataItem, ArrayList<DataItem>>();
    private ArrayList<DataItem> mFeedData;
    private NetworkingHandler mHandler = new NetworkingHandler("tag");
    private GoogleMap mMap;
    private final String DOWNLOAD_USER_LOCATIONS_URL =
               "http://www.myfeedurllocation.com/page.php";

    @Override
    public void onCreate(Bundle savedBundleInstance) {
        super.onCreate(savedBundleInstance);
        setContentView(R.layout.activity_myactivitylayout);
        downloadUserLocations();
        setUpMapIfNeeded();
    }

    @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 void setUpMap() {
        // Hide the zoom controls as the button panel will cover it.
        mMap.getUiSettings().setZoomControlsEnabled(false);
        mMap.getUiSettings().setRotateGesturesEnabled(true);
        mMap.getUiSettings().setCompassEnabled(true);
        // Add lots of markers to the map.
        addMarkersToMap();
        // Setting an info window adapter allows us to change the both the
        // contents and look of the
        // info window.
        mMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());
        // Set listeners for marker events. See the bottom of this class for
        // their behavior.
        mMap.setOnMarkerClickListener(this);
        mMap.setOnInfoWindowClickListener(this);
        mMap.setOnMarkerDragListener(this);
        // Pan to see all markers in view.
        // Cannot zoom to bounds until the map has a size.
        final View mapView = getSupportFragmentManager().findFragmentById(
            R.id.map).getView();
        if (mapView.getViewTreeObserver().isAlive()) {
            mapView.getViewTreeObserver().addOnGlobalLayoutListener(
                new OnGlobalLayoutListener() {

                    @SuppressLint("NewApi")
                    // We check which build version we are using.
                    @Override
                    public void onGlobalLayout() {
                        LatLngBounds.Builder bounds = new LatLngBounds.Builder();
                        for (DataItem location : mUserLocations.keySet()) {
                            bounds.include(new LatLng(
                                    Double.parseDouble(location.mData
                                            .get("latitude")), Double
                                            .parseDouble(location.mData
                                                    .get("longitude"))));
                        }
                        mapView.getViewTreeObserver()
                                .removeGlobalOnLayoutListener(this);
                        mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(
                            bounds.build(), 80));
                    }
                });
        }
    }

    private void addMarkersToMap() {
        for (DataItem location : mUserLocations.keySet()) {
            StringBuilder stringBuilder = new StringBuilder();
            for (DataItem user : mUserLocations.get(location)) {
                stringBuilder.append("\n" + user.mData.get("textToAdd"));
            }
            mMap.addMarker(new MarkerOptions()
                    .position(
                        new LatLng(Double.parseDouble(location.mData
                                .get("latitude")), Double
                                .parseDouble(location.mData.get("longitude"))))
                    .title(location.mData.get("textToAdd"))
                    .snippet(stringBuilder.toString())
                    .icon(
                        BitmapDescriptorFactory
                                .defaultMarker(BitmapDescriptorFactory.HUE_RED)));
        }
    }

    private void downloadUserLocations() {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                try {
                    mFeedData = mHandler
                            .returnDataArrayList(DOWNLOAD_USER_LOCATIONS_URL);
                    for (DataItem item : mFeedData) {
                        // create location
                        DataItem location = new DataItem();
                        location.mTags.add("locationText1");
                        location.mTags.add("latitude");
                        location.mTags.add("longitude");
                        location.mData.put("locationText1",
                            item.mData.get("locationText1"));
                        location.mData.put("latitude",
                            item.mData.get("latitude"));
                        location.mData.put("longitude",
                            item.mData.get("longitude"));
                        // create user
                        DataItem user = new DataItem();
                        user.mTags.add("userText1");
                        user.mTags.add("userText2");
                        user.mData
                                .put("userText1", item.mData.get("userText1"));
                        user.mData
                                .put("userText2", item.mData.get("userText2"));
                        if (mUserLocations.keySet().contains(location)) {
                            mUserLocations.get(location).add(user);
                        } else {
                            mUserLocations.put(location,
                                new ArrayList<DataItem>());
                            mUserLocations.get(location).add(user);
                        }
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (ParserConfigurationException e) {
                    e.printStackTrace();
                } catch (SAXException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(r).start();
    }

    @Override
    public void onMarkerDrag(Marker arg0) {}

    @Override
    public void onMarkerDragEnd(Marker arg0) {}

    @Override
    public void onMarkerDragStart(Marker arg0) {}

    @Override
    public void onInfoWindowClick(Marker arg0) {}

    @Override
    public boolean onMarkerClick(Marker arg0) {
        return false;
    }

    class CustomInfoWindowAdapter implements InfoWindowAdapter {

        private final RadioGroup mOptions;
        // These a both viewgroups containing an ImageView with id "badge" and
        // two TextViews with id
        // "title" and "snippet".
        private final View mWindow;
        private final View mContents;

        CustomInfoWindowAdapter() {
            mWindow = getLayoutInflater().inflate(R.layout.custom_info_window,
                null);
            mContents = getLayoutInflater().inflate(
                R.layout.custom_info_contents, null);
            mOptions = (RadioGroup) findViewById(R.id.custom_info_window_options);
        }

        @Override
        public View getInfoWindow(Marker marker) {
            if (mOptions.getCheckedRadioButtonId() != R.id.custom_info_window) {
                // This means that getInfoContents will be called.
                return null;
            }
            render(marker, mWindow);
            return mWindow;
        }

        @Override
        public View getInfoContents(Marker marker) {
            if (mOptions.getCheckedRadioButtonId() != R.id.custom_info_contents) {
                // This means that the default info contents will be used.
                return null;
            }
            render(marker, mContents);
            return mContents;
        }

        private void render(Marker marker, View view) {
            int badge = R.drawable.map_pin;
            // Use the equals() method on a Marker to check for equals. Do not
            // use ==.
            ((ImageView) view.findViewById(R.id.badge)).setImageResource(badge);
            String title = marker.getTitle();
            TextView titleUi = ((TextView) view.findViewById(R.id.title));
            if (title != null) {
                // Spannable string allows us to edit the formatting of the
                // text.
                SpannableString titleText = new SpannableString(title);
                titleText.setSpan(new ForegroundColorSpan(Color.RED), 0,
                    titleText.length(), 0);
                titleUi.setText(titleText);
            } else {
                titleUi.setText("");
            }
            String snippet = marker.getSnippet();
            TextView snippetUi = ((TextView) view.findViewById(R.id.snippet));
            if (snippet != null) {
                SpannableString snippetText = new SpannableString(snippet);
                snippetText.setSpan(new ForegroundColorSpan(Color.MAGENTA), 0,
                    10, 0);
                snippetText.setSpan(new ForegroundColorSpan(Color.BLUE), 12,
                    21, 0);
                snippetUi.setText(snippetText);
            } else {
                snippetUi.setText("");
            }
        }
    }
}

Here is my stack trace.

02-14 15:23:50.219: E/AndroidRuntime(8952): FATAL EXCEPTION: main
02-14 15:23:50.219: E/AndroidRuntime(8952): java.lang.IllegalStateException: no included points
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.google.android.gms.internal.at.a(Unknown Source)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.google.android.gms.maps.model.LatLngBounds$Builder.build(Unknown Source)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.mypackage.MyActivity$1.onGlobalLayout(MyActivity.java:109)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:682)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1850)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1112)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4472)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.Choreographer.doCallbacks(Choreographer.java:555)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.Choreographer.doFrame(Choreographer.java:525)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.os.Handler.handleCallback(Handler.java:615)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.os.Handler.dispatchMessage(Handler.java:92)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.os.Looper.loop(Looper.java:137)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.app.ActivityThread.main(ActivityThread.java:4898)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at java.lang.reflect.Method.invokeNative(Native Method)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at java.lang.reflect.Method.invoke(Method.java:511)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at dalvik.system.NativeStart.main(Native Method)

2条回答
【Aperson】
2楼-- · 2019-04-09 21:40

Don't bother with the builder just do.

LatLngBounds mapBounds;
for (DataItem location : mUserLocations.keySet()) {
    if (mapBounds==null) {
        LatLng point = new LatLng(Double.parseDouble(location.mData.get("latitude")), Double.parseDouble(location.mData.get("longitude")))
        mapBounds =new LatLngBounds(point, point);
    } else {
        mapBounds = mapBounds.including(new LatLng(Double.parseDouble(location.mData.get("latitude")), Double.parseDouble(location.mData.get("longitude"))));
    }
}
查看更多
Deceive 欺骗
3楼-- · 2019-04-09 21:52

I get the same error.

In the Api, it is explained this:

public LatLngBounds (LatLng southwest, LatLng northeast): IllegalArgumentException if the latitude of the northeast corner is below the latitude of the southwest corner.

With the following code, the exception is launched when the list to compute the bounds is empty:

LatLngBounds.Builder builder = LatLngBounds.builder();
for(ModelLatLngDisplay p: list){
    builder = builder.include(p.latLng);
}
return builder.build();
查看更多
登录 后发表回答