'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)