正文  设备功能 > GPS/LBS/定位 >

Android CellLocation源码,基于Rexsee对象的基站定位功能

用模拟器研究Android的基站定位,折腾了半天收不到数据,结果意识到最基本的东西弄错了。。基站信息是来自运营商的,仿真器只能模拟网络延迟(-netdelay)、网速(-netspeed)、以及一些电话相关的操作,gsm 。还不......

用模拟器研究Android的基站定位,折腾了半天收不到数据,结果意识到最基本的东西弄错了。。基站信息是来自运营商的,仿真器只能模拟网络延迟(-netdelay)、网速(-netspeed)、以及一些电话相关的操作,gsm 。还不能模拟信号。

用的是Rexsee的基站定位(RexseeCellLocation对象)。示例代码如下,其中cid 和 lac 为经纬度。

代码段

function query(){

var loction = eval('('+rexseeCellLocation.getLastKnownLocation()+')');

var type = location.type.toLowerCase();

var mcc = parseInt(location.operator.substring(0,3));

var mnc = (type=='gsm')?parseInt(location.operator.substring(3)):location.systemId;

var cid= (type=='gsm')?location.cid:location.baseStationId;

var lac= (type=='gsm')?location.lac:location.networkId;

var postData="{\version\":\"1.1.0\",\"host\":\maps.google.com\",\"access_token\";\"2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe\",\"home_mobile_country_code\":"+mcc+",\"home_mobile_network_code\":"+mnc+",\"address_language\";\"zh_CN\",\"radio_type\";\""+type+"\",\"request_address\":true,\"cell_towers\":[{\"cell_id\":+cid+",\"location_area_code\":+lac+",\"mobile_aountry_code\":"+mcc+",\"mobile_network_code\":"+mnc+",\"timing_advance\":5555}]}";

alert(rexseeAjax.syncSubmit('http://www.google.com/loc/json',postData,'utf-8'));

}

返回的结果是:http://www.rexsee.com/imagecache/bbs/11-10-09/1318156045.jpg

需要注意几个问题:

1. 如果直接用alert(rexseeCellLocation.getLastKnownLocation()); 这个方法得到的经纬度会是两个非常大的数字 所以需要通过ajax提交到"http://www.google.com/loc/json" 把所需要的经纬度返回来;

2. 开始监听,一旦位置发生变化,会触发事件onCellLocationChanged。所以,要在 onCellLocationChanged中写代码,调用你的query函数。而不是直接使用onclick测试。

CellLocation全部源码如下:

/*

* Copyright (C) 2011 The Rexsee Open Source Project

*

* Licensed under the Rexsee License, Version 1.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.rexsee.com/CN/legal/license.html

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package rexsee.location;

import rexsee.core.browser.JavascriptInterface;

import rexsee.core.browser.RexseeBrowser;

import android.content.Context;

import android.telephony.CellLocation;

import android.telephony.PhoneStateListener;

import android.telephony.TelephonyManager;

import android.telephony.cdma.CdmaCellLocation;

import android.telephony.gsm.GsmCellLocation;

public class RexseeCellLocation implements JavascriptInterface {

private static final String INTERFACE_NAME = "CellLocation";

@Override

public String getInterfaceName() {

return mBrowser.application.resources.prefix + INTERFACE_NAME;

}

@Override

public JavascriptInterface getInheritInterface(RexseeBrowser childBrowser) {

return this;

}

@Override

public JavascriptInterface getNewInterface(RexseeBrowser childBrowser) {

return new RexseeCellLocation(childBrowser);

}

public static final String EVENT_ONCELLLOCATIONCHANGED = "onCellLocationChanged";

public final Context mContext;

private final RexseeBrowser mBrowser;

private final int mPhoneType;

private PhoneStateListener mListener = null;

private CellLocation mLocation = null;

public RexseeCellLocation(RexseeBrowser browser) {

mContext = browser.getContext();

mBrowser = browser;

browser.eventList.add(EVENT_ONCELLLOCATIONCHANGED);

TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

mPhoneType = tm.getPhoneType();

}

//JavaScript Interface

public boolean isEnabled() {

return mListener != null;

}

public boolean enable() {

try {

TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

mListener = new PhoneStateListener() {

@Override

public void onCellLocationChanged(CellLocation location) {

mLocation = location;

mBrowser.eventList.run(EVENT_ONCELLLOCATIONCHANGED);

}

};

tm.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);

return true;

} catch (Exception e) {

mBrowser.exception(getInterfaceName(), e);

return false;

}

}

public boolean disable() {

if (mListener == null) return true;

try {

TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

tm.listen(mListener, PhoneStateListener.LISTEN_NONE);

mListener = null;

return true;

} catch (Exception e) {

mBrowser.exception(getInterfaceName(), e);

return false;

}

}

public String getLastKnownLocation() {

if (mLocation == null) return "{}";

TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

String rtn = "";

rtn += "\"operator\":\"" + tm.getNetworkOperator() + "\"";

rtn += ",\"operatorName\":\"" + tm.getNetworkOperatorName() + "\"";

if (mPhoneType == TelephonyManager.PHONE_TYPE_GSM) {

GsmCellLocation gsm = (GsmCellLocation) mLocation;

rtn += ",\"type\":\"GSM\"";

rtn += ",\"cid\":" + gsm.getCid();

rtn += ",\"lac\":" + gsm.getLac();

} else if (mPhoneType == TelephonyManager.PHONE_TYPE_CDMA) {

CdmaCellLocation cdma = (CdmaCellLocation) mLocation;

rtn += ",\"type\":\"CDMA\"";

rtn += ",\"baseStationId\":" + cdma.getBaseStationId();

rtn += ",\"baseStationLatitude\":" + cdma.getBaseStationLatitude();

rtn += ",\"baseStationLongitude\":" + cdma.getBaseStationLongitude();

rtn += ",\"networkId\":" + cdma.getNetworkId();

rtn += ",\"systemId\":" + cdma.getSystemId();

}

return "{" + rtn + "}";

}

}