GoogleMap android API v2:https://developers.google.com/maps/documentation/android/start?hl=zh-CN
链接里是官方给出的向导,我只是照着模拟做了一遍,希望E文不好的同学可以通过本文获取一些地图开发知识,同时记录自己的心得,仅此而已。
1,创建一个新的Project,在project.properties里添加googlePlayServices服务:
2,google play service lib在 android自带SDK下就有,这个我就不再赘述了,相当于添加一个第三方的lib库,有关此知识请网络搜索。
3,activityMain.xml里添加 GoogleMap 组件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="14dp" android:text="路径规划" /> <fragment android:id="@+id/mgooglemap" android:name="com.google.android.gms.maps.MapFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/button1" > </fragment> </RelativeLayout>
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGoogleMap = ((MapFragment) getFragmentManager().findFragmentById( R.id.mgooglemap)).getMap(); routeBtn = (Button) findViewById(R.id.button1); routeBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { LatLng start = new LatLng(40.036675, 116.32885); LatLng end = new LatLng(40.056675, 116.38885); String url = getDirectionsUrl(start, end); googleMapRouteTask task = new googleMapRouteTask(url); task.execute(); } }); }
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> <!-- The following two permissions are not required to use Google Maps Android API v2, but are recommended. --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />6,这一步最重要,在配置文件添加Googl Map Key,现在地图开发都需要申请相应的key,googleMap比较麻烦,除了申请好key,还要上传MD5校验码生成一个专用的keystore,debug时有debug专用的key 和 keystore;release(发布)时需要使用release 的key 和keystore。
所以看到这里时,你一定是申请好了debug 和release的两个key,并且验证好了各自专用的keystroe,如果没有请点击本文开头的链接,阅读一下如何申请key和keystore。(如果是多人开发,已有他人申请并创建了google map,请找他索要 key 和keystore,自己替换之)
7,以上都搞定的话,就运行吧,如果mapviw显示一片空白,则看log把,肯定是google Map服务验证出错了,查看自己的key和keystore
/** * 组合成googlemap direction所需要的url * * @param origin * @param dest * @return url */ private String getDirectionsUrl(LatLng origin, LatLng dest) { // Origin of route String str_origin = "origin=" + origin.latitude + "," + origin.longitude; // Destination of route String str_dest = "destination=" + dest.latitude + "," + dest.longitude; // Sensor enabled String sensor = "sensor=false"; // Travelling Mode String mode = "mode=driving"; // String waypointLatLng = "waypoints="+"40.036675"+","+"116.32885"; // 如果使用途径点,需要添加此字段 // String waypoints = "waypoints="; String parameters = null; // Building the parameters to the web service parameters = str_origin + "&" + str_dest + "&" + sensor + "&" + mode; // parameters = str_origin + "&" + str_dest + "&" + sensor + "&" // + mode+"&"+waypoints; // Output format // String output = "json"; String output = "xml"; // Building the url to the web service String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters; System.out.println("getDerectionsURL--->: " + url); return url; }
/** * 自定义class通过AsyncTask机制异步请求获取导航数据 * * @author Administrator * */ private class googleMapRouteTask extends AsyncTask<String, Void, List<LatLng>> { HttpClient client; String url; List<LatLng> routes = null; public googleMapRouteTask(String url) { this.url = url; } @Override protected List<LatLng> doInBackground(String... params) { HttpGet get = new HttpGet(url); try { HttpResponse response = client.execute(get); int statusecode = response.getStatusLine().getStatusCode(); System.out.println("response:" + response + " statuscode:" + statusecode); if (statusecode == 200) { String responseString = EntityUtils.toString(response .getEntity()); int status = responseString.indexOf("<status>OK</status>"); System.out.println("status:" + status); if (-1 != status) { int pos = responseString.indexOf("<overview_polyline>"); pos = responseString.indexOf("<points>", pos + 1); int pos2 = responseString.indexOf("</points>", pos); responseString = responseString .substring(pos + 8, pos2); routes = decodePoly(responseString); } else { // 错误代码, return null; } } else { // 请求失败 return null; } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println("doInBackground:"+routes); return routes; } @Override protected void onPreExecute() { client = new DefaultHttpClient(); client.getParams().setParameter( CoreConnectionPNames.CONNECTION_TIMEOUT, 15000); client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 15000); super.onPreExecute(); } @Override protected void onPostExecute(List<LatLng> routes) { super.onPostExecute(routes); if (routes == null) { // 导航失败 Toast.makeText(getApplicationContext(), "没有搜索到线路", Toast.LENGTH_LONG).show(); } else{ //地图描点 PolylineOptions lineOptions = new PolylineOptions(); lineOptions.addAll(routes); lineOptions.width(3); lineOptions.color(Color.BLUE); mGoogleMap.addPolyline(lineOptions); //定位到第0点经纬度 mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(routes.get(0))); } } }
/** * 解析返回xml中overview_polyline的路线编码 * * @param encoded * @return List<LatLng> */ private List<LatLng> decodePoly(String encoded) { List<LatLng> poly = new ArrayList<LatLng>(); int index = 0, len = encoded.length(); int lat = 0, lng = 0; while (index < len) { int b, shift = 0, result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lat += dlat; shift = 0; result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lng += dlng; LatLng p = new LatLng((((double) lat / 1E5)), (((double) lng / 1E5))); poly.add(p); } return poly; }
public String routeWithHttpURLConnection() { LatLng start = new LatLng(40.036675, 116.32885); LatLng end = new LatLng(40.056675, 116.38885); String url = getDirectionsUrl(start, end); // 保存请求结果 String result = ""; try { URL requestUrl = new URL(url); // 此处的urlConnection对象实际上是根据URL的,请求协议(此处是http)生成的 // URLConnection类,的子类HttpURLConnection,故此处最好将其转化 // 为HttpURLConnection类型的对象,以便用到HttpURLConnection更多的API.如下: HttpURLConnection connection = (HttpURLConnection) requestUrl .openConnection(); // ***********************************************************************// // 设定传送的内容类型是可序列化的java对象 // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException) connection.setRequestProperty("Content-type", "application/x-java-serialized-object"); //设置超时时间 connection.setConnectTimeout(3000); // 设定请求的方法为"POST",默认是GET connection.setRequestMethod("POST"); // Post 请求不能使用缓存 connection.setUseCaches(false); // ***********************************************************************// connection.connect(); // 调用HttpURLConnection连接对象的getInputStream()函数, // 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。 InputStream is = connection.getInputStream();// <===注意,实际发送请求的代码段就在这里 BufferedReader br = new BufferedReader(new InputStreamReader(is)); StringBuffer buffer = new StringBuffer(); String line = null; if ((line = br.readLine()) != null) { buffer.append(line); } result = buffer.toString(); br.close(); is.close(); connection.disconnect(); } catch (IOException e) { e.printStackTrace(); } return result; }