Android LBS中网络定位服务的实现方法
来源:互联网 发布:sql判断count的值大于 编辑:程序博客网 时间:2024/05/22 11:48
由于大陆禁止使用Google定位服务。因此我们需要自己研发一款基于网络与基站的LBS应用。
但是由于Google并没有开放networklocation.apk的源码。因此我们需要自己动手山寨一个
既然是山寨了,那肯定要走反向工程了。
我们先看看LBS服务的基础LocationManagerService是如何启动网络定位服务的
先看LocationManagerService 的构造方法
public LocationManagerService(Context context) { super(); mContext = context; Resources resources = context.getResources(); mNetworkLocationProviderPackageName = resources.getString( com.android.internal.R.string.config_networkLocationProviderPackageName); mGeocodeProviderPackageName = resources.getString( com.android.internal.R.string.config_geocodeProviderPackageName); mPackageMonitor.register(context, null, true); if (LOCAL_LOGV) { Slog.v(TAG, "Constructed LocationManager Service"); } }
mNetworkLocationProviderPackageName 这个就是网络定位服务APK的name.如果用的是国际版的ROM的话 这个name应该是networklocation
我们继续
其实,LocationManagerService 是一个线程类,除了构造函数以外,在其 run 方法中又完成了另外一部分的初始化工作,主要是调用其 initialize 方法。 在 initialize 方法中调用了 loadProviders 方法,loadProviders 这个方法中完成了 Location Provider 的加载工作。 该方法又经过同步加锁以及异常的包装,最终的实现方法是 _loadProvidersLocked。 _loadProvidersLocked 方法的代码如下所示:
private void _loadProvidersLocked() { // Attempt to load "real" providers first if (GpsLocationProvider.isSupported()) { // Create a gps location provider GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this); mGpsStatusProvider = gpsProvider.getGpsStatusProvider(); mNetInitiatedListener = gpsProvider.getNetInitiatedListener(); addProvider(gpsProvider); mGpsLocationProvider = gpsProvider; } // create a passive location provider, which is always enabled PassiveProvider passiveProvider = new PassiveProvider(this); addProvider(passiveProvider); mEnabledProviders.add(passiveProvider.getName()); // initialize external network location and geocoder services. // The initial value of mNetworkLocationProviderPackageName and // mGeocodeProviderPackageName is just used to determine what // signatures future mNetworkLocationProviderPackageName and // mGeocodeProviderPackageName packages must have. So alternate // providers can be installed under a different package name // so long as they have the same signature as the original // provider packages. if (mNetworkLocationProviderPackageName != null) { String packageName = findBestPackage( LocationProviderProxy.SERVICE_ACTION, mNetworkLocationProviderPackageName); if (packageName != null) { mNetworkLocationProvider = new LocationProviderProxy( mContext, LocationManager.NETWORK_PROVIDER, packageName, mLocationHandler); mNetworkLocationProviderPackageName = packageName; addProvider(mNetworkLocationProvider); } } if (mGeocodeProviderPackageName != null) { String packageName = findBestPackage( GeocoderProxy.SERVICE_ACTION, mGeocodeProviderPackageName); if (packageName != null) { mGeocodeProvider = new GeocoderProxy(mContext, packageName); mGeocodeProviderPackageName = packageName; } } updateProvidersLocked(); }
mNetworkLocationProvider 这个就是我们要找的
代码里是根据 mNetworkLocationProviderPackageName 字段创建 LocationProviderProxy 对象。(在创建 LocationProviderProxy 的时候,packageName 参数是依赖于 mNetworkLocationProviderPackageName 的。这个字段是在 LocationManagerService 的构造函数中初始化的。)
既然提到了LocationProviderProxy,那我们就继续跟踪下去。
Handler handler) {
mContext = context;
mName = name;
mIntent = new Intent(SERVICE_ACTION);
mHandler = handler;
reconnect(packageName);
}
/** Bind to service. Will reconnect if already connected */
public void reconnect(String packageName) {
synchronized (mMutex) {
if (mServiceConnection != null) {
mContext.unbindService(mServiceConnection);
}
mServiceConnection = new Connection();
mIntent.setPackage(packageName);
mContext.bindService(mIntent, mServiceConnection,
Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND |
Context.BIND_ALLOW_OOM_MANAGEMENT);
}
}
bindService o(∩∩)o...哈哈 看到这里我们就大概上知道该怎么办了。
我们自己要实现的networklocation首先需要是一个service,并且需要实现onBind接口。
那下面的问题是IBinder在那里呢
我们继续看LocationProviderProxy
private class Connection implements ServiceConnection, Runnable { private ILocationProvider mProvider; // for caching requiresNetwork, requiresSatellite, etc. private DummyLocationProvider mCachedAttributes; // synchronized by mMutex public void onServiceConnected(ComponentName className, IBinder service) { synchronized (this) { mProvider = ILocationProvider.Stub.asInterface(service); if (mProvider != null) { mHandler.post(this); } } }
LocationManagerService通信的接口类
但是我们不能直接使用ILocationProvider。我们为了编码方便可以使用android提供给我们的gift
frameworks/base/location/lib/java/com/android/location/provider/LocationProvider.java
现在我们可以开始架构我们自己的networklocation.apk了。权且叫它NewLBSLocation.apk吧
我们需要以下几个类(以下只是简单实现)
NewLBSLocationService------------继承自android service,这个是整个APK的入口类,实现onBind接口
NewLBSLocationProvider------------继承自LocationProvider,这个主要是实现与
LocationManagerService的通信接口
NewLBSLocationUtil--------------通过handler与NewLBSLocationProvider通信,在这个类中监听基站与WIFI热点的变化,然后将相关信息发送给定位服务器获取相关位置location,然后通过一系列算法优化location.
- Android LBS中网络定位服务的实现方法
- 关于Android中GPS的位置定位服务(LBS),有瑕疵
- Android使用百度LBS定位服务
- 瑞柏匡丞:别样的LBS定位服务
- android如何实现LBS定位实例代码
- Android学习-- 基于位置的服务 LBS(基于百度地图Android SDK)--定位SDK
- (android地图开发) 基于百度Lbs服务定位用户的当前位置
- android LBS的定位源码解析
- android LBS的定位源码解析
- android LBS的定位源码解析
- android LBS的定位源码解析
- LBS定位实现
- 工作杂谈:LBS定位服务
- Android 基于位置的服务(LBS)
- 在3G中实现LBS的定位技术和GIS系统
- 在3G中实现LBS的定位技术和GIS系统
- 实现定位服务的两种方法
- 【android】网络定位服务NetworkLocationProvider
- 【java】矩阵相加
- 利用pysftp实现sqlite的远程访问
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第十一课
- 形象理解android电源管理wakelock状态
- 【java】矩阵相乘
- Android LBS中网络定位服务的实现方法
- 基于Android平台的手机卫士效果图
- ext panel的使用 以及ext.ajax.request的使用
- linux redis 安装配置, 以及redis php扩展
- 百度地图V2.3.5获取API key相关经验(android)
- JDBC之一:JDBC快速入门
- python unittest框架用后分享
- ext2、ext3、ext4、brtfs文件系统区别
- xcode和苹果系统OS 一些常用的快捷键