第一步:API Key获取
如果你要嵌入google map在你自己的app里面,就必须要api key,当然,如果你不嵌入goole map,只是要获得经纬度,可以不用获得api key的。
1. api key 介绍
对于开发者来说,api key 一般分两类,debug key 和 release key(如果你只用debug key,生成出来的apk在其他手机上也能正常显示google map)。debug key是和我们 ~/.android/debug.keystore 对应的(后面会讲到),这也就是说,你下载和拷贝别人的工程到你电脑上,你是不能加载上 google map的,常见的情况就是只显示 很多 格子。(~/.android/debug.keystore 文件不是在工程里面)当然,这也是导致你把你自己的工程(可以加载地图)拷贝到其它人电脑上,他那边也是显示不出来地图的。 -----------解决办法就是自己去重新申请api key,替换 掉就行了。
还有一种就是release key,我们开发产品是要所有人都能使用的,我们不可能为每个手机都去申请api key。所以当我们要发布给别个手机使用的时候,需要在去重新申请一个api key,然后用和这个新api key相关联的签名文件(xxxx.keystore)签名,然后就可以发布出去了。
注意:当你拷贝别人工程的时候,你有 两种方式来显示google map,一种是你拷贝别人工程在eclipse运行该工程来显示google map,另一种是你可以直接运行别人工程里面的apk(xxx_project/bin/xxx.apk--------如果有的话),你会发现我们在eclipse运行工程并不能显示google map,但是我们直接运行apk文件却能显示google map。后面通过讲解签名原理就明白了。 你只要知道,xxx_project/bin/xxx.apk文件是别人 的debug.keystore 签名过的。
2. 获取api key
• 找到或创建keystore证书文件;
做开发的话,如果是linux,证书文件就是 ~/.android/debug.keystore。
如果要发布了,需要重新创建证书文件 keytool -genkey -alias android.keystore -validity 20000 -keystore android.keystore
• 生成MD5认证指纹;
开发者使用 keytool -list -keystore ~/.android/debug.keystore
发布就使用 keytool -list -keystore android.keystore
格式大概是 97:A8:A9:45:01:2C:4A:66:83:DE:F1:08:90:A8:38:55 (这个key不能用,我改过数据了)
• 生成Google Map API Key。
http://code.google.com/intl/zh-CN/android/maps-api-signup.html
上面这个连接是生成api key 的网站,它要求输入 上面的认证指纹 97:A8:A9:45:01:2C:4A:66:83:DE:F1:08:90:A8:38:55
从第二步我们可以看出 生成api key 的流程:证书 ------>>> 认证指纹--------->>> api key
所以这就解释了,为什么你下载别人的工程显示不了地图,因为他的api key 是由 他电脑上的证书文件(~/.android/debug.keystore)生成的,而这个文件是不会在工程里面的。而我们发布的apk文件为什么所有手机都能用呢,那是因为 我们在打包的时候要选择签名文件,而这个签名文件就是我们的证书文件 android.keystore 。并不是说需要把该证书文件拷贝到apk里面,而是用该证书文件来签名,签名具体要做的就是 用该证书文件里面的 私钥签名,并把该证书文件里面的公钥和私钥的签名结果放在apk里面,记住 不是把私钥放在apk里面,那样就不安全了。下面是证书文件的简单介绍。
android.keystore 简单介绍
这个文件相当于一个密钥管理库,里面保存了多对公钥和私钥,还有其它一些信息。
当我们选择一个签名文件的时候,会让我们选择 alias 文件,其实可以出现多个,eclipse 会读取证书文件(android.keystore)里面的所有公私钥对显示成一个列表,如下所示
alias 其实就是你的私钥,开始我也不知道私钥到底存到哪儿去了,做了一些测试之后,我估计就是保存在了 我们的 证书文件里面,并且可以保存多组公私钥。当我们选择一个alia 时,也就选择了一对公私钥准备签名。
如果我们用命令行来签名可以看得更明白些,到底android签名做了写什么:
这里我用 yan私钥 签名 HelloGoogleMaps.apk 并生成 signed.apksig
这里只是在META-INF文件夹下面添加了两项 (adding操作),其它都是签名操作(signing操作---其实就是用私钥加密的过程),但是网上的资料说是会添加四项,我这边可能有地方没对,当我查看eclipse 签名出来的另一个apk文件,有三项。
所以不管怎样,至少有一点是明确的,apk里面的META-INF文件夹是签名文件签名结果的,到底有哪些内容呢?下面是网上的解释。
CERT.SF:生成每个文件相对的密钥
MANIFEST.MF:数字签名信息
xxx.SF:这是 JAR 文件的签名文件,占位符 xxx标识了签名者
xxx.DSA:对输出文件的签名和公钥
里面有一项很重要,就是xxx.DSA 文件,这里面保存了公钥,我们知道签名的原理就是用 私钥加密(signing 操作),用公钥解密。
所以当我们安装apk的时候,android系统应该会用xxx.DSA文件里面的 公钥 解密 私钥加密(signing 操作) 的信息----------也就是META-INF文件夹下的签名信息,如果解密成功,则验证通过,不然就不能安装。
上面这个扯的有点远了。好了,回到我们Google Map 上来。
第二步: 加入MapView。
既然现在我们获得了api key,现在就可以用它了。
环境:
首先要支持 google map 的add-on,创建模拟器的时候,选择 google map创建。------------这一步可能会遇到很多问题,确实比较麻烦
常见的就是 缺少 一个库。
权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_UPDATES" />
MapView 控件
<com.google.android.maps.MapView
android:id="@+id/geoMap" android:clickable="true"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:apiKey="0Vk_Sg_P9567z06o6eTbzFrwJwErAMqS2bZOI0w" /> -----------------(这个aipKey也不能用,我改过了)
继承MapActivity
任何要嵌入google map的活动必须要继承MapActivity。不能简单的继续Activity就行了。
如果不出什么问题,基本可以看到google map可以在你的app里面显示了。
下面我讲一点定位方面的知识。
定位知识
首先google map 定位有两个方案:wifi和GPS
1.wifi定位:
由于GPS无法完成室内定位,所以google借助wifi来实现室内定位。
wifi定位原理和基站地位差不多,都是google通过手机搜集wifi热点或基站ID信息来达到定位的。大致原理应该是:
当我们使用GPS的时候,google会收集周边的wifi热点上传到google服务器建立一个数据库。这里要注意,我们不一定是要连接到该wifi热点,只要手机能搜索到该热点就行了。我想该热点应该有个全球唯一标识 --有两种猜测
一个是无线路由器的Mac地址---------------------------------这个是全球唯一的。
google可以这样做,就是收集当前这个wifi热点无线路由器的Mac地址和你当前GPS位置 到服务器,但是有个问题,这个无线路由器不一定一直保持在那个位置,比如,如果你搬家了,或者坏了。那么这个wifi热点就不准确了。但是我们可以想象出现这种情况的概率真的很低,你想想你家的无线路由器从买回来到现在你动过它几次???即使搬家了(和该路由器换地方了---足够远),你也很快会将该信息上传到google服务器的。只要你用GPS就行了。而且即使你不使用GPS上传,说不定周围某个使用GPS的人从你家经过,就已经将你的wifi热点上传到google服务器了。
当然还有一种就是你无线路由器接入网络的那个网口有个地址(-------------只是猜测有个地址。不一定有。),当你使用GPS的时候,它把这个上传到服务器建立数据库。这样即使你搬家也没有影响,因为他不靠你的wifi路由器定位,而是你路由器即将出入的那个网口找到你。当然前提也是那个网口已经在google数据库里面了。
不管怎样:
从这里,我们能得出一下信息:
1.wifi定位并不是通过很高深的技术实现的。仅仅收集信息,上传信息,查询数据库,然而,google做的不是普通人能做的,在海量数据的前提下,普通人就不能玩得转了。
2.信息是我们自己上传的,当我们在打开google map app的时候,他弹出框让我们勾选wifi定位。
当我们勾选wifi定位的时候,他会给我警告,是否允许google收集你的地理位置。你只要点击 agree,你的收集就会在你不知情的情况下上传地理信息到google服务器,来帮助google完善数据库。
如果你不同意,当然就不能使用wifi定位,也就是不能实现室内定位,但是室外还是可以定位的,毕竟GPS技术可不是靠收集信息实现的。这也就是为什么是你点击Use GPS satellites的时候不会弹出上面的警告框。
2.GPS定位
这个知识就很多了,不详细讲了,大致是至少用3颗卫星来找到你的, 你和每一颗卫星形成一个空间球体,然后这3个空间球的焦点就是你。所以卫星数不能少于3,不然是找不到你的。
总结:
我们开发google map 要注意几点
1.如果发现不能获取经纬度,一般是因为你在室内做的测试,这个一开始也困扰了我很久。其实代码是没有问题的,主要是在室内不能获得GPS信号。
2.当不能获得GPS数据的时候,我们一般会给位置初始化一个值,假设是(0.0,0.0),结果发现地图变成蓝色的了,很多人会认为地图加载不了,其实地图已经显示出来了,蓝色是因为(0.0,0.0)这个地方是海洋,如果你的 zoomLeve级别很大,那么你是看不到陆地位置,即使你在那里不缩小地图的情况下滑动一天地图也很难从海里滑到陆地。 但是如果你把地图缩小,滑动了一会儿就看到陆地了。地图就正常了。 ---------------------------------从这点也看出:google 牛逼 earth 很大。
3.即使你勾选了wifi定位,也很难获得地理位置,这是因为你的wifi地址没在google数据库里面,多用几次GPS就好了,我也不知道到底什么时候google数据库会更新,不过等着吧。。会更新的。
4. 我们做Google Map开发的时候,记得经常清除 你调式App的data 。因为里面包含了google 地图的缓存数据。有时候其实是不能获取GPS的,但是打开程序发现还是有数据,不是因为它能获得GPS,而是因为他读取的缓存。
5.这点比较有意思,就是当你发现你的app不能加载google map的时候,你可以看看你手机的状态栏里面的wifi图标和手机信号图标是否是绿色,如果不是绿色而是灰色,表示你当前不能连接上google的服务(比如,gmail,gtalk,googlemap等)。那么google map肯定也加载不上了,要知道,google map会去服务器上下载地图的。所以呢,等着信号图标变成灰色的时候在试试吧。
6.最后,发布的时候记得重新申请API key,具体原因上面已经解释了。