找回密码
 注册
搜索
查看: 2054|回复: 4

Google地图应用开发

[复制链接]
发表于 2014-12-28 17:34:37 | 显示全部楼层 |阅读模式
从2012年12月开始,Google map API v1已停止开放密钥申请,同期Google推出v2版本的android map API,与v1不同的是,v2版本的地图应用开发不再需要单独的Google API SDK 支持,可以使用普通的SDK直接开发,但需要引用Google play services的库来支持,所以在没有安装Google Play Service的手机中,程序无法正常运行,需要按要求安装该服务。因为Google map API v1已关闭密钥申请,所以接下来我们基于v2版本进行教学。 同v1一样,使用v2的第一步便是申请Google API 的密钥。
1、 申请地图密钥
1) 在申请地图密钥之前,请先申请好自己的Google帐号,也就是Gmail邮箱;
2) 得到Gmail邮箱之后前往Google API控制台,链接地址:,并在左侧菜单中选择API Access。

3) 点击Create New Android Key,并在弹出窗口中输入SHA-1 fingerprint及应用包名,格式如下:
C6:DB:D4:30:E9:95:A8:05:18:09:4D:59:7B:BC:F1:B2:E4:19:B3:8F;com.magic.googleuniversity 注意:SHA-1 fingerprint可以在Eclipse中Window-Preference-Android-Build中找到

4) 点击Create 之后即可获得API Key,如笔者API Key为:AIzaSyCqeTfwjOBZ47cQopVTEcevq3y13002UwY
5) 在API管理页面中默认已经存在了一个API,那个是不要删除,在之后对Google地图数据调用时需要提供,如笔者API Key为:AIzaSyBYHW0vQ5RHPCrh8Zc7uBks8KSTibntcs
 楼主| 发表于 2014-12-28 17:35:32 | 显示全部楼层

2、 使用Google地图

2.1 建立一个新的工程,由于可以是使用android-support-v4.jar,所以目标SDK无需一定要在4.0以上。

2.2 导入Google Play Services的library项目,在Eclipse里面选择:File > Import > Android > Existing Android Code Into Workspace然后点击Next.之后Browse..., 找到路径下的<android-sdk-folder>/extras/google/google_play_services/libproject/google-play-services_lib, 然后选择Finish。(如果没有这个库请在Android SDK Manager更新,在底端的Extras里面更新Google Play services)。导入完成后,在Map工程属性的Android标签内,引用该library。

2.3添加AndroidManifest.xml中相应属性及内容。
2.3.1在<application>元素中加入子标签
  1. <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="your_api_key"/>
复制代码
其中your_api_key置换成自己申请的API Key。

2.3.2添加专属权限
  1. <permission android:name="com.magic.googleuniversity.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <uses-permission android:name="com.magic.googleuniversity.permission.MAPS_RECEIVE "/>
复制代码

其中com.magic.googleuniversity换成自己的包名。
2.3.3 添加其他权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission
android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

2.3.4 添加OpenGL ES V2特性支持
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>

2.4修改布局文件activity_main.xml
<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" >

<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</RelativeLayout>

2.5修改MainActivity.java
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {

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

}

至此,你便可以打开你的APK,欣赏Google map的魅力了。

回复

使用道具 举报

 楼主| 发表于 2014-12-28 17:36:24 | 显示全部楼层

3、 GoogleMap的部分方法

3.1 显示“我的位置按钮”
mMap.setMyLocationEnabled(true);
3.2 设置地图类型,一共有一下四种类型
mMap.setMapType(MAP_TYPE_NORMAL);
mMap.setMapType(MAP_TYPE_HYBRID);
mMap.setMapType(MAP_TYPE_SATELLITE);
mMap.setMapType(MAP_TYPE_TERRAIN);

3.3 设置Marker
mMap.addMarker(new MarkerOptions()
.position(new LatLng(0, 0))
.title("Marker")
.snippet("Maker"));

回复

使用道具 举报

 楼主| 发表于 2014-12-28 17:37:48 | 显示全部楼层

4、监听、并实时显示我的当前位置

4.1 设置我的位置按钮
mMap.setMyLocationEnabled(true);
4.2 LocationClient对象,用于监听位置信息变化
4.3 添加ConnectionCallbacks, OnConnectionFailedListener监听
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; import
com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;

import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends FragmentActivity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener{

private static GoogleMap mMap;
private LocationClient mLocationClient;
private static final LocationRequest REQUEST = LocationRequest.create()
.setInterval(2000) // 2 seconds
.setFastestInterval(16) // 16ms = 60fps
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

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

setUpMapIfNeeded();
}

protected void onResume() {
super.onResume();

if (mLocationClient == null) {
mLocationClient = new LocationClient(this, this, this);
}
mLocationClient.connect();
}

private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment)
getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
}
mMap.setMyLocationEnabled(true);
}

public static void setMapCenter(LatLng latLng) {
CameraPosition cameraPosition = new CameraPosition.Builder().target(latLng)
.zoom(17)
.build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); }

@Override
public void onLocationChanged(Location location) {
setMapCenter(new LatLng(location.getLatitude(), location.getLongitude())); }

@Override
public void onConnected(Bundle arg0) {
mLocationClient.requestLocationUpdates(REQUEST, this);
}

@Override
public void onDisconnected() {
// TODO Auto-generated method stub
}

@Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}

}

回复

使用道具 举报

 楼主| 发表于 2014-12-28 17:38:38 | 显示全部楼层

5、 搜索周边信息

5.1 搜索周边信息的方法
在此,笔者提供一个公共类,以供周边信息搜索,原理是利用当前位置信息,在Google Place API上搜索信息,所以需要在开发者控制台申请Place API的接入

5.2 在公共类的方法中需要提供一个apikey的参数,这里并不是用之前已申请的key,在帐号申请之处,API Access页面中已有一个key,用它就可以了。
5.3 GoogleUtil公共类
注意:此公共类为其他网友所写,为保证著作权,所以使用时请标注上作者名 GoogleUtil.java
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import org.json.JSONArray;
import org.json.JSONObject;

import android.util.Log;

import com.google.android.gms.maps.model.LatLng;

/**
* Google Map的搜索工具
*
* @author macro
*
*/
public class GoogleUtil {
private static String URL_API =
"https://maps.googleapis.com/maps/api/place/search/json?";
/**
* 根据传入的条件信息查询附近信息
*
* @param key API 密钥
* @param location 即要在其周围检索地方信息的纬度/经度。必须指定为纬度、经度。
* @param radius 范围
* @param sensor 请求的设备是否会使用 GPS 等位置传感器
* @param keyword 方建立索引的全部内容相匹配的字词(可选)
* @param language 语言代码(可选)
* @param name 地方信息的名称进行匹配的字词(可选)
* @param types 指定类型相匹配的地方信息,类型应使用竖线符号
(type1|type2|etc) 进行分隔(可选)
* @return List<Map<String, String>>
*/
public static List<Map<String, String>> queryByCondition(String apikey, LatLng latLng, int radius, String keyword, String language, String name, String types) throws Exception { List<Map<String, String>> listMaps = new LinkedList<Map<String, String>>(); // *******************************************组装请求路径信息
************************************************************************// // 例子:
https://maps.googleapis.com/maps/api/place/search/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=AddYourOwnKeyHere URL_API += "location=" + latLng.latitude + "," + latLng.longitude
+ "&radius=" + radius + "";

if (null != keyword && keyword.length() > 0) {// 关键词 URL_API += "&keyword=" + keyword; } if (null != language && language.length() > 0) {// 语言 URL_API += "&language=" + language; } if (null != name && name.length() > 0) {// 匹配名称 URL_API += "&name=" + name; }
if (null != types && types.length() > 0) {// 类型
URL_API += "&types=" + types;
}
URL_API += "&sensor=false";
URL_API += "&key=" + apikey + "";
System.out.println("请求的URL=" + URL_API);
// *******************************************获取查询得到的返回值************************************************************************// StringBuffer buf = new StringBuffer();
InputStream input = null;
try {
URL url = new URL(URL_API);
input = url.openStream();
Scanner scan = new Scanner(input);
while (scan.hasNext()) {
buf.append(scan.next()); // 所有的数据都保存在字符串里面 }
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (input != null) {
input.close();
}
}
System.out.println("查询得到的数据=" + buf.toString());
JSONObject allData = new JSONObject(buf.toString());
// 获取连接状态
String status = allData.getString("status");
if ("OK".equals(status)) {
JSONArray jsonArr = allData.getJSONArray("results");
for (int i = 0; i < jsonArr.length(); i++) {
Map<String, String> map = new HashMap<String, String>();
JSONObject jsonObj = jsonArr.getJSONObject(i);
map.put("vicinity", jsonObj.getString("vicinity"));
map.put("icon", jsonObj.getString("icon"));
map.put("name", jsonObj.getString("name"));
JSONObject locationJsonObj =
jsonObj.getJSONObject("geometry").getJSONObject("location");
map.put("latitude", locationJsonObj.getString("lat"));
map.put("longitude", locationJsonObj.getString("lng"));
listMaps.add(map);
Log.v("location",
"latitude="+locationJsonObj.getString("lat")+",longitude="+locationJsonObj.getString("lng"));
}
}
return listMaps;
}

}
5.4 使用公共类中queryByCondition方法
MainActivity.java
import java.util.List;
import java.util.Map;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; import
com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import android.app.ProgressDialog;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends FragmentActivity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener{
public static final int STATUS_FAILED = 0;
public static final int STATUS_SUCCESS = 1;
public static final int STATUS_NETERROR = 2;
private static final String API_KEY = "AIzaSyBYHW-0vQ5RHPCrh8Zc7uBks8KSTibntcs"; private static final String language = "zh-CN";
private static final String types = "food|restaurant";
private static final int radius = 200;
private String name = "";
private String keywords = "";

private List<Map<String, String>> listMaps = null;
private LatLng latLng = null;

private LocationClient mLocationClient;

private ProgressDialog progressDialog = null;
private static GoogleMap mMap;

private static final LocationRequest REQUEST = LocationRequest.create()
.setInterval(2000) // 2 seconds
.setFastestInterval(16) // 16ms = 60fps
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

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

setUpMapIfNeeded();

}

protected void onResume() {
super.onResume();

if (mLocationClient == null) {
mLocationClient = new LocationClient(this, this, this);
}
mLocationClient.connect();
}

private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment)
getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
}
mMap.setMyLocationEnabled(true);
}

public void displayNearby(View v){
new SearchAsyncTask().execute();
}

public static void setMapCenter(LatLng latLng) {
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLng)
.zoom(17)
.build();

mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); }

@Override
public void onLocationChanged(Location location) {
latLng = new LatLng(location.getLatitude(), location.getLongitude());
setMapCenter(latLng);
}

@Override
public void onConnected(Bundle arg0) {
mLocationClient.requestLocationUpdates(REQUEST, this);
}

@Override
public void onDisconnected() {
// TODO Auto-generated method stub

}

@Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub

}

private class SearchAsyncTask extends AsyncTask<Integer, String, Integer> {

public SearchAsyncTask(){
progressDialog = ProgressDialog.show(MainActivity.this, null, "正在获取附近餐馆数据,请稍后...", true);
progressDialog.setCancelable(false);
}

@Override
protected Integer doInBackground(Integer... arg0) {
try {

if (latLng != null) {
listMaps = GoogleUtil.queryByCondition(API_KEY, latLng, radius, keywords, language, name, types);
return STATUS_SUCCESS;
}else{
return STATUS_FAILED;
}
} catch (Exception e) {
e.printStackTrace();
return STATUS_NETERROR;
}
}

@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if(progressDialog != null) {
progressDialog.dismiss();
progressDialog = null;
}
switch(result){
case STATUS_FAILED:
Toast.makeText(getApplicationContext(), "正在确认当前位置,请稍后再试!", Toast.LENGTH_SHORT).show();
break;
case STATUS_NETERROR:
Toast.makeText(getApplicationContext(), "网络出错,请检查网络!", Toast.LENGTH_SHORT).show();
break;
case STATUS_SUCCESS:
if (null != listMaps && listMaps.size() > 0) {
LatLng latLngTemp = null;
for (int i = 0; i < listMaps.size(); i++) {
latLngTemp = new
LatLng(Double.parseDouble(listMaps.get(i).get("latitude")),Double.parseDouble(listMaps.get(i).get("longitude")));
mMap.addMarker(new
MarkerOptions().position(latLngTemp).title(listMaps.get(i).get("name")).snippet(listMaps.get(i).get("address")));
}
}else{
Toast.makeText(getApplicationContext(), "抱歉,附近未搜索到餐馆!", Toast.LENGTH_SHORT).show();
}
break;
}
}
}

}
activity_main.xml
<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" >

<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />

<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:onClick="displayNearby"
android:text="显示附近餐馆"/>

</RelativeLayout>
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2025-5-5 00:22 , Processed in 0.016605 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表