分享

手机定位折腾记(1):安卓手机的网络定位与NetworkLocation.apk

 quasiceo 2016-05-24

手机定位折腾记(1):安卓手机的网络定位与NetworkLocation.apk

时间 2013-06-14 19:59:29 HorseLuke@微碌

前言

从苹果、安卓等智能手机快速普及的那一天起,由于国内各种特别的行情,有关手机定位的问题一直困扰着普通用户和开发者。比如,安卓手机为什么总不能使用网络定位?NetworkLocation.apk是什么?为什么外国app的地图显示出来的总是偏移的?本文试图以回答这些问题,给普通用户和开发者(尤其是移动开发者)一些指引,并且提出一些自己的思考。由于本人并非GIS从业者,所以也许会有错漏,敬请指正。

本文阅读人群:
智能手机普通用户、移动应用从业者(开发者)

================================================

如果是安卓手机/平板的深度使用用户,必定会对许多手机定位(尤其是冷启动定位)的速度不敢恭维、甚至说基本是废的(除了某些专用于导航的安卓设备);雪上加霜的是,由于各种行情,手机中的网络定位许多也不能正常工作的。论坛上各种标榜“秒定”(秒速定位)的rom随处可见,究竟是如何做到的?

这系列的第一篇,主要讲的是安卓系统中,网络定位的那些事情。在此之前,先对全系列的一些要点提前解读。

GPS、GLONASS、北斗和GNSS

说起定位,大家第一时间联想到的是美国的GPS。但实质上,俄罗斯的GLONASS、中国的北斗、欧盟的Galileo等也在做一样的事情。其实,他们都同属GNSS(Global Navigation Satellite System、全球导航卫星系统)的领域下。

一些GNSS的简要介绍如下:
(1)GPS(Global Positioning System)是美国的全球定位系统,其坐标系是WGS-84。
(2)GLONASS是俄罗斯的格洛纳斯系统,其坐标系是PZ-90。[1]
(3)中国的北斗,其坐标系是CGS2000。
……

现在集成GPS + GLONASS的双GNSS定位芯片和设备已经成为了某些设备的新卖点,比如小米手机2[2]、Garmin eTrex 30[3]等。展望未来,混搭GNSS会是主流方向(甚至已经出现了MT3332/MT3333五合一方案[4]),有GIS从业者也提出应该让“GNSS”取代“GPS”成为新的定位名词[5]。

但是…….鉴于当前许多设备还是基于GPS芯片和系统运行,许多用户还是更熟悉“GPS”而不是“GNSS”这个名词,故而下面,也就只讲述GPS和与之相关的定位技术了。

网络定位、A-GPS和GPS的关系

要讨论安卓智能手机的定位,一定离不开三个词:网络定位、A-GPS和GPS。他们之间的关系如下:

  网络定位(此处特指安卓“设置”中给出的概念) (包括非卫星参与的移动基站定位、WiFi 定位) A-GPS (Assisted GPS GPS
设备是否需要联网(WIFI/2G/3G等) 需要 需要 不需要
定位源/数据源 移动基站、wifi等无线基站信息 移动基站、wifi等无线基站信息 卫星
系统独立性 可单独使用 目标是为了令GPS定位更快更精准,不可单独使用 可单独使用
定位速度 快(需视乎网络速度、与位置服务器连接的情况) 目标是为了令GPS定位更快更精准,不能比较(辅助GPS的速度:需视乎网络速度、与位置服务器连接和通讯的质量) 相对其它两个较慢(如果A-GPS工作良好,也比较快)
定位精度 低(需要视乎数据源提供商) 目标是为了令GPS定位更快更精准,不能比较(辅助GPS的精度:需要视乎数据源提供商) 高(需视乎定位芯片和天线接收质量)
(安卓)所属开发层 应用程序框架层(<=4.0.x / 4.1.x / 4.2.x三大开发方式接入LocationProviderProxy) + platform级签名 Linux内核层(驱动级开发)(需搭配GPS驱动一并开发) Linux内核层 + 应用程序框架层(需继承LocationProvider派生出GpsLocationProvider等)(驱动级开发)

android_location_series_1_associate

以上的关系,后面再展开阐述。现在进入本文的主题:网络定位。

网络定位简介

在安卓的设置中,“网络定位”是指利用手机基站信息、wifi信息等发送到指定的位置服务器;位置服务器接收后,直接返回粗略的经纬度和精度信息。整个过程中其实就是“根据IP地址获取地址”的高级版,而且手机端无需定位卫星的信号,做到低耗电定位(所以说,网络定位的本质,其实和GPS乃至AGPS都没什么关系)。

(网络定位在HTML5的例子, 手机点此链接访问该页面 ,可测试网络定位是否正常)

从上面可以看到,要实现网络定位,位置服务器是必须的,但这部分一般都在地图资源商的手中,手机/平板制造商不可能有这种资源。他们只能通过和地图资源商进行商务合作或者取得授权,才能够合法地放入网络定位的相关底层应用和分发使用权,否则会被视为侵权使用。国内常见的网络定位目前有两种:

(1)Google GMS(Google Mobile Service)中的网络定位服务(许多人可能更加熟悉NetworkLocation.apk)。但国内行货由于众多原因,目前没有一家通过GMS认证,所以一定不会有这个服务(换句话讲,也不会有这个文件)。即使有,其实也是在灰色使用状态,不能太声张——之前曾有一次,小米放入这个文件,结果引发同行批评[7]。也有rom制作者与刷机发烧友等尝试自行刷入这个GMS的网络定位,这部分遇到的技术问题下文再表。

(2)百度地图的网络定位服务(一般为NetworkLocation_Baidu.apk或者BaiduNetworkLocation.apk)。目前有部分国行和部分rom采用。这满足了国行不能使用GMS、但又希望使用网络定位的需求。至于有没有坐标偏移,手头没有机器,没有测试。

网络定位的开发与故障

在应用开发上,要使用网络定位,必须要在AndroidManifest.xml申明“android.permission.ACCESS_COARSE_LOCATION”的uses-permission;同时也要求手机联网完成获取。 但是如果网络定位服务不存在或者异常,则不会返回任何信息。典型的情况是,使用HTML5的navigator.geolocation.getCurrentPosition,总会返回PositionError.code为3的Timeout expired(即超时)。 (注意:网络定位服务不可用并不影响HTML5对GPS设备的数据读取;如果GPS成功获取当前高精度坐标并正常运行、且html5代码申请了enableHighAccuracy: true,则HTML5也能正常读取GPS的数据并显示)

在底层开发上,要实现网络定位,不同的安卓版本、甚至不同的机型都有不同的实现方式。但 归根到底都要最终实现“以Provider+Service方式接入LocationProviderProxy”的目标,而且相关接入应用必须以platform级别证书签名,否则不能运行。 从大版本来看,有三大实现模式,有兴趣的开发者可照附录一的简表自行查看源代码。

“秒定秘籍”之一:恢复网络定位

恢复网络定位功能,的确可以有秒定的良好感觉,只不过问题是这种秒定的精度并不高,而且设备还必须联网才行。但是怎么恢复确实不易,尤其是 处理platform签名 的问题。以在rom中恢复Google Mobile Service的网络定位为例(这里不考虑侵权问题,仅作技术交流),要万无一失,理论上整体的过程如下:

(1)确定安卓版本号,和要恢复的网络定位包(com.google.android.maps.jar/com.google.android.maps.xml/features.xml/GoogleServicesFramework.apk/NetworkLocation.apk等;有些安卓版本还需要SetupWizard.apk等)。

(2)准备platform级别的证书(platform.x509.pem,platform.pk8)。如果仅是测试自用,可以从这里下载:

https://github.com/android/platform_build/tree/master/target/product/security

(3)确定/system/framework/framework_res.apk是否和公钥platform.x509.pem一致。方法是:
(A)用解压缩软件拿出META-INF\CERT.RSA,然后改名为CERT_framwwork.p7b;
(B)双击打开,然后导出里面的证书,选择“Base64编码 X.509(.CER)”,导出为CERT_framwwork_public.cer。

android_location_series_3_cert_export

(C)对比platform.x509.pem和CERT_framwwork_public.cer文字是否一致。一致的话,恭喜你,后面的工作省心多了。但一般来讲,国行是用了自己的platform证书签名的,因此,后面的改动就比较大了。

(4)反编译/system/framework/framework_res.apk,根据附录一的“网络定位配置表”,找到相关配置。如果是GMS默认的值(这里没法收集到,可参见其他rom),恭喜你,这里不用改了;如果不是,就得改,然后重编译并用(2)中的证书签名。

(5)如果(3)中的对比结果为不一致,就必须用(2)中的证书重新签名/system/framework/framework_res.apk。

(6)按照(3)的步骤分别对GoogleServicesFramework.apk、NetworkLocation.apk的公钥和platform.x509.pem进行对比,如果不一致,需要重新签名。
注意:如果需要恢复其他GMS应用,则必须找出和GoogleServicesFramework.apk使用了相同签名的GMS应用,然后重新用(2)的证书签名。

(7)如果(3)中的对比结果为不一致,就必须在/system/app/下进行如下操作:
(A)以Settings.apk为中心,找出和Settings.apk一样的、所有使用platform签名的应用(参见(3)的过程);
(B)将这些应用全部重新用(2)的证书签名一遍

(8)将(1)中网络定位包的相关文件放置到相关位置

(9)重新打包rom,测试

从以上可以看到,想要简单恢复网络定位,对于普通用户来讲并不容易,也因此有了各种自制rom。但有些rom作者图省事,直接将所有apk全部给platform签名,其结果会造成一个隐患:任何应用都有权读写系统敏感区域了。

另一种方法则是利用国内行货和海外版行货使用同一个platform证书签名的特性,将海外版行货的GMS给移植回国内行货。这种情况,需要一定的运气,以及祈求厂商在国内外的版本上核心改动不大。

网络定位初始化可用性检查小工具

为了让各位自查网络定位的签名是否正常,我做了一个 Android_Location_Provider_Test应用 。当前只能检查Android 4.0.x及以下版本的网络定位是否初始化正常(没其他机器啊亲)。不能正常初始化的话,则表明网络定位设置不对或者签名有异常,则一定不能工作,如果可以正常初始化,那么表明网络定位的签名没问题,可以用的概率还是很大的。

android_location_series_4_app_init_failure

(初始化异常,网络定位不可用)

android_location_series_5_app_init_ok

(初始化正常,网络定位可用性比较大)

在Google的网络定位中,恢复Google Service Framework是否就一定可以正常工作呢?现在这个问题变得复杂了,由于Google Play的出现,Play服务也横空出世并成为必装服务。如果Google Service Framework、Play服务和GMS其他应用之间应用不畅,一样造成无法使用。遇到这种情况,Android_Location_Provider_Test应用就无能为力测试了。至于解决方法,暂时没找到……

android_location_series_6_setting_networklocation

(可以见到,此时网络定位已经由google地图的GoogleLocationService接管了网络定位的核心功能;如果Google Service Framework、Play服务和GMS其他应用之间应用不畅,这个对话框也无法出现,导致网络定位也实质无法使用)

(本文完,下文预告:《手机定位折腾记(2):AGPS和GPS》)

附录一:网络定位的底层开发简表

LocationManagerService类重要关注方法:

android版本 LocationManagerService类重要关注方法 源代码位置(相对于https://android./platform/frameworks/base/+/  或者 https://github.com/android/platform_frameworks_base/tree/ ) 反编译的文件和位置
<= 4.0.x LocationManagerService(Context context);_loadProvidersLocked(); /{<=4.0.x的分支}/services/java/com/android/server/LocationManagerService.java (暂未找寻)
4.1.x LocationManagerService(Context context);findBestPackage(String serviceIntentName, String sigPackageName);_loadProvidersLocked(); /{4.1.x的分支}/services/java/com/android/server/LocationManagerService.java (暂未找寻)
4.2.x LocationManagerService(Context context);loadProvidersLocked();ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs); /{4.2.x的分支}/services/java/com/android/server/LocationManagerService.java (暂未找寻)

网络定位配置:

android版本 配置字符串 源代码位置(相对于https://android./platform/frameworks/base/+/  或者 https://github.com/android/platform_frameworks_base/tree/ ) 反编译/system/framework/framework_res.apk位置
<= 4.0.x config_networkLocationProvider /{<=4.0.x的分支}/core/res/res/values/config.xml /res/values/strings.xml
4.1.x config_networkLocationProviderPackageName /{4.1.x的分支}/core/res/res/values/config.xml /res/values/strings.xml
4.2.x config_locationProviderPackageNames /{4.2.x的分支}/core/res/res/values/config.xml /res/values/arrays.xml

从4.1.x开始,网络定位还必须实现统一指定的Intent Action,否则不予运行:

android版本 统一指定的Intent Action 源代码位置(相对于https://android./platform/frameworks/base/+/  或者 https://github.com/android/platform_frameworks_base/tree/ ) 反编译的文件和位置
4.1.x public static final String SERVICE_ACTION = “com.android.location.service.NetworkLocationProvider”; /{4.1.x的分支}/services/java/com/android/server/location/LocationProviderProxy.java (暂未找寻)
4.2.x private static final String NETWORK_LOCATION_SERVICE_ACTION =  ”com.android.location.service.v2.NetworkLocationProvider”;private static final String FUSED_LOCATION_SERVICE_ACTION =  ”com.android.location.service.FusedLocationProvider”; /{4.2.x的分支}/services/java/com/android/server/LocationManagerService.java (暂未找寻)

============
[1]GPS、GLONASS卫星坐标计算和导航应用研究: http://wenku.baidu.com/view/5c00b92a0066f5335a8121d8.html

[2]小米手机2: http://www./mi2

[3]Garmin eTrex 30: http://www./products/onthetrail/etrex301Outdoor/

[4]联发科技发布全球首颗支持中国北斗卫星的五合一全球导航卫星系统接收器SoC解决方案(2013-01-28): http://www./_cn/03_news/01-2_newsDetail.php?sn=1094

[5]“应该用GNSS全面代替GPS名词”: http://weibo.com/2154494070/ztN2ZjrsG

[6]利用Google接口实现网络定位NetworkLocation(基站定位、WiFi定位): http://my.oschina.net/u/617626/blog/71043

[7]全过程见:
http://weibo.com/2679966300/yl14fxAFI

http://weibo.com/1782068057/ypGbKjfnK

http://weibo.com/2679966300/ypGrvs3I6

分享

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多