如何实施谷歌转弯驾驶导航?

时间:2015-03-23 06:47:42

标签: android google-maps navigation

'public class DirectionsMapFragment扩展了SherlockMapFragment {

private static final HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();

private Handler handler = new Handler();
private Random random = new Random();
private Runnable runner = new Runnable() {
    @Override
    public void run() {
        setHasOptionsMenu(true);
    }
};

private GoogleMap googleMap;
private List<Marker> markers = new ArrayList<Marker>();

public static DirectionsMapFragment newInstance(int position,String title) {
    DirectionsMapFragment fragment = new DirectionsMapFragment();
    Bundle bundle = new Bundle();
    bundle.putInt("position", position);
    bundle.putString("title", title);
    fragment.setArguments(bundle);
    return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    handler.postDelayed(runner, random.nextInt(2000));

    View view = super.onCreateView(inflater, container, savedInstanceState);
    googleMap = getMap();
    googleMap.setMyLocationEnabled(true);

    ViewUtils.initializeMargin(getActivity(), view);

    return view;
}

/**
 * Adds a list of markers to the map.
 */
public void addPolylineToMap(List<LatLng> latLngs) {
    PolylineOptions options = new PolylineOptions();
    for (LatLng latLng : latLngs) {
        options.add(latLng);
    }
    googleMap.addPolyline(options);
}   

/**
 * Clears all markers from the map.
 */
public void clearMarkers() {
    googleMap.clear();
    markers.clear();        
}

private Menu menu;
private boolean directionsFetched = false;


@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    this.menu = menu;
    //menu.clear();
    inflater.inflate(R.menu.directions_menu, menu);
    updateNavigationStopStart();
}


private void updateNavigationStopStart() {
    MenuItem startAnimation = this.menu.findItem(R.id.action_bar_start_animation);
    startAnimation.setVisible(!animator.isAnimating() && directionsFetched);
    MenuItem stopAnimation = this.menu.findItem(R.id.action_bar_stop_animation);
    stopAnimation.setVisible(animator.isAnimating());
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
      if (item.getItemId() == R.id.action_bar_directions) {
          startActivityForResult(new Intent(getActivity(), DirectionsInputActivity.class), DirectionsInputActivity.RESULT_CODE);
      } else if (item.getItemId() == R.id.action_bar_start_animation) {
          animator.startAnimation(true,latLngs);
          updateNavigationStopStart();
      } else if (item.getItemId() == R.id.action_bar_stop_animation) {
          animator.stopAnimation();
          updateNavigationStopStart();
      } else if (item.getItemId() == R.id.action_bar_toggle_style) {
          GoogleMapUtis.toggleStyle(googleMap);

      }

      return true;
}   

private List<LatLng> latLngs = new ArrayList<LatLng>();

 private class DirectionsFetcher extends AsyncTask<URL, Integer, Void> {


    private String origin;
    private String destination;

     public DirectionsFetcher(String origin,String destination) {
        this.origin = origin;
        this.destination = destination;
    }

     @Override
    protected void onPreExecute() {
        super.onPreExecute();
        clearMarkers();
        getActivity().setProgressBarIndeterminateVisibility(Boolean.TRUE);

    }

     protected Void doInBackground(URL... urls) {
         try {
             HttpRequestFactory requestFactory = HTTP_TRANSPORT.createRequestFactory(new HttpRequestInitializer() {
                 @Override
                 public void initialize(HttpRequest request) {
                     request.setParser(new JsonObjectParser(JSON_FACTORY));
                 }
                 });

             GenericUrl url = new GenericUrl("http://maps.googleapis.com/maps/api/directions/json");
             url.put("origin", origin);
             url.put("destination", destination);
             url.put("sensor",false);

            HttpRequest request = requestFactory.buildGetRequest(url);
            HttpResponse httpResponse = request.execute();
            DirectionsResult directionsResult = httpResponse.parseAs(DirectionsResult.class);

            String encodedPoints = directionsResult.routes.get(0).overviewPolyLine.points;
            latLngs = PolyUtil.decode(encodedPoints);
         } catch (Exception ex) {
             ex.printStackTrace();
         }
         return null;

     }

     protected void onProgressUpdate(Integer... progress) {
     }

     protected void onPostExecute(Void result) {
         directionsFetched=true;
         System.out.println("Adding polyline");
         addPolylineToMap(latLngs);
         System.out.println("Fix Zoom");
         GoogleMapUtis.fixZoomForLatLngs(googleMap, latLngs);
         System.out.println("Start anim");
         animator.startAnimation(false, latLngs);
         updateNavigationStopStart();
         getActivity().setProgressBarIndeterminateVisibility(Boolean.FALSE);
     }
 }  

  public static class DirectionsResult {

    @Key("routes")
    public List<Route> routes;

  }

  public static class Route {
      @Key("overview_polyline")
      public OverviewPolyLine overviewPolyLine;

  }

  public static class OverviewPolyLine {
      @Key("points")
      public String points;

  }

  @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode==DirectionsInputActivity.RESULT_CODE) {
        String from = data.getExtras().getString("from");
        String to = data.getExtras().getString("to");
        new DirectionsFetcher(from,to).execute();
    }
}

  private Animator animator = new Animator();
  private final Handler mHandler = new Handler();

  public class Animator implements Runnable {

        private static final int ANIMATE_SPEEED = 1500;
        private static final int ANIMATE_SPEEED_TURN = 1500;
        private static final int BEARING_OFFSET = 20;

        private final Interpolator interpolator = new LinearInterpolator();

        private boolean animating = false;

        private List<LatLng> latLngs = new ArrayList<LatLng>();

        int currentIndex = 0;

        float tilt = 90;
        float zoom = 15.5f;
        boolean upward=true;

        long start = SystemClock.uptimeMillis();

        LatLng endLatLng = null; 
        LatLng beginLatLng = null;

        boolean showPolyline = false;

        private Marker trackingMarker;

        public void reset() {
            resetMarkers();
            start = SystemClock.uptimeMillis();
            currentIndex = 0;
            endLatLng = getEndLatLng();
            beginLatLng = getBeginLatLng();

        }

        public void stopAnimation() {
            animating=false;
            mHandler.removeCallbacks(animator);

        }

        public void initialize(boolean showPolyLine) {
            reset();
            this.showPolyline = showPolyLine;

            highLightMarker(0);

            if (showPolyLine) {
                polyLine = initializePolyLine();
            }

            // We first need to put the camera in the correct position for the first run (we need 2 markers for this).....
            LatLng markerPos = latLngs.get(0);
            LatLng secondPos = latLngs.get(1);

            setInitialCameraPosition(markerPos, secondPos);

        }

        private void setInitialCameraPosition(LatLng markerPos,
                LatLng secondPos) {

            float bearing = GoogleMapUtis.bearingBetweenLatLngs(markerPos,secondPos);

            trackingMarker = googleMap.addMarker(new MarkerOptions().position(markerPos)
                     .title("title")
                     .snippet("snippet"));

            float mapZoom = googleMap.getCameraPosition().zoom >=16 ? googleMap.getCameraPosition().zoom : 16;

            CameraPosition cameraPosition =
                    new CameraPosition.Builder()
                            .target(markerPos)
                            .bearing(bearing + BEARING_OFFSET)
                            .tilt(90)
                            .zoom(mapZoom)
                            .build();

            googleMap.animateCamera(
                    CameraUpdateFactory.newCameraPosition(cameraPosition), 
                    ANIMATE_SPEEED_TURN,
                    new CancelableCallback() {

                        @Override
                        public void onFinish() {
                            System.out.println("finished camera");
                            animator.reset();
                            Handler handler = new Handler();
                            handler.post(animator); 
                        }

                        @Override
                        public void onCancel() {
                            System.out.println("cancelling camera");                                    
                        }
                    }
            );
        }       

        private Polyline polyLine;
        private PolylineOptions rectOptions = new PolylineOptions();


        private Polyline initializePolyLine() {
            //polyLinePoints = new ArrayList<LatLng>();
            rectOptions.add(latLngs.get(0));
            return googleMap.addPolyline(rectOptions);
        }

        /**
         * Add the marker to the polyline.
         */
        private void updatePolyLine(LatLng latLng) {
            List<LatLng> points = polyLine.getPoints();
            points.add(latLng);
            polyLine.setPoints(points);
        }

        public void startAnimation(boolean showPolyLine,List<LatLng> latLngs) {
            if (trackingMarker!=null) {
                trackingMarker.remove();
            }
            this.animating = true;
            this.latLngs=latLngs;
            if (latLngs.size()>2) {
                initialize(showPolyLine);
            }

        }               

        public boolean isAnimating() {
            return this.animating;
        }


        @Override
        public void run() {

            long elapsed = SystemClock.uptimeMillis() - start;
            double t = interpolator.getInterpolation((float)elapsed/ANIMATE_SPEEED);
            LatLng intermediatePosition = SphericalUtil.interpolate(beginLatLng, endLatLng, t);

            Double mapZoomDouble = 18.5-( Math.abs((0.5- t))*5);
            float mapZoom =  mapZoomDouble.floatValue();

            System.out.println("mapZoom = " + mapZoom);

            trackingMarker.setPosition(intermediatePosition);

            if (showPolyline) {
                updatePolyLine(intermediatePosition);
            }

            if (t< 1) {
                mHandler.postDelayed(this, 16);
            } else {

                System.out.println("Move to next marker.... current = " + currentIndex + " and size = " + latLngs.size());
                // imagine 5 elements -  0|1|2|3|4 currentindex must be smaller than 4
                if (currentIndex<latLngs.size()-2) {

                    currentIndex++;

                    endLatLng = getEndLatLng();
                    beginLatLng = getBeginLatLng();


                    start = SystemClock.uptimeMillis();

                    Double heading = SphericalUtil.computeHeading(beginLatLng, endLatLng);

                    highLightMarker(currentIndex);

                    CameraPosition cameraPosition =
                            new CameraPosition.Builder()
                                    .target(endLatLng)
                                    .bearing(heading.floatValue() /*+ BEARING_OFFSET*/) // .bearing(bearingL  + BEARING_OFFSET)
                                    .tilt(tilt)
                                    .zoom(googleMap.getCameraPosition().zoom)
                                    .build();

                    googleMap.animateCamera(
                            CameraUpdateFactory.newCameraPosition(cameraPosition), 
                            ANIMATE_SPEEED_TURN,
                            null
                    );

                    //start = SystemClock.uptimeMillis();
                    mHandler.postDelayed(this, 16);                 

                } else {
                    currentIndex++;
                    highLightMarker(currentIndex);
                    stopAnimation();
                }

            }
        }



        private LatLng getEndLatLng() {
            return latLngs.get(currentIndex+1);
        }

        private LatLng getBeginLatLng() {
            return latLngs.get(currentIndex);
        }

    };        

    /**
     * Highlight the marker by index.
     */
    private void highLightMarker(int index) {
        if (markers.size()>=index+1) {
            highLightMarker(markers.get(index));
        }
    }

    /**
     * Highlight the marker by marker.
     */
    private void highLightMarker(Marker marker) {

        if (marker!=null) {
            marker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
            marker.showInfoWindow();
        }

    }   

    private void resetMarkers() {
        for (Marker marker : this.markers) {
            marker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
        }
    }       

}“

当我点击操作栏中的方向按钮时,此方法调用animator.startAnimation(true,latLngs); 那个时候得到例外。

我曾为用户制作谷歌地图和路线创建,并希望向用户提供驾驶方向,但不知道,如何通过谷歌导航等语音创建转弯驾驶方向。 谷歌提供谷歌地图意图,但现在想要使用那个想创建单独的。

![当我点击行动栏中的路线时,应用程序正在关闭。]

03-23 15:32:41.701: E/AndroidRuntime(22675): FATAL EXCEPTION: main
03-23 15:32:41.701: E/AndroidRuntime(22675): Process: com.ecs.google.maps.v2.actionbarsherlock, PID: 22675
03-23 15:32:41.701: E/AndroidRuntime(22675): java.lang.NoSuchMethodError: android.support.v4.view.ViewGroupCompat.getLayoutMode
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Bounds.include(GridLayout.java:2294)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.computeGroupBounds(GridLayout.java:1205)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.getGroupBounds(GridLayout.java:1214)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.createLinks(GridLayout.java:1223)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.getForwardLinks(GridLayout.java:1249)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.createArcs(GridLayout.java:1374)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.getArcs(GridLayout.java:1407)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.solve(GridLayout.java:1587)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.computeLocations(GridLayout.java:1694)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.getLocations(GridLayout.java:1718)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.getMeasure(GridLayout.java:1739)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout$Axis.getMeasure(GridLayout.java:1750)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.support.v7.widget.GridLayout.onMeasure(GridLayout.java:951)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.View.measure(View.java:16540)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5137)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.View.measure(View.java:16540)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5137)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:327)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.View.measure(View.java:16540)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5137)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2291)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.View.measure(View.java:16540)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1942)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1132)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1321)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1019)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5725)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.Choreographer.doCallbacks(Choreographer.java:574)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.Choreographer.doFrame(Choreographer.java:544)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.os.Handler.handleCallback(Handler.java:733)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.os.Handler.dispatchMessage(Handler.java:95)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.os.Looper.loop(Looper.java:136)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at android.app.ActivityThread.main(ActivityThread.java:5086)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at java.lang.reflect.Method.invokeNative(Native Method)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at java.lang.reflect.Method.invoke(Method.java:515)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
03-23 15:32:41.701: E/AndroidRuntime(22675):    at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)