先提示一点,不能使用用模拟器研究Android的基站定位:基站信息是来自运营商的,仿真器只能模拟网络延迟(-netdelay)、网速(-netspeed)、以及一些电话相关的操作,gsm 。还不能模拟信号。
一段基于Rexsee()的基本示例demo,其中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('',postData,'utf-8'));
- }
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('',postData,'utf-8'));
}
返回的结果是:
需要注意几个问题:
1. 如果直接用alert(rexseeCellLocation.getLastKnownLocation()); 这个方法得到的经纬度会是两个非常大的数字 所以需要通过ajax提交到"" 把所需要的经纬度返回来;
2. 开始监听,一旦位置发生变化,会触发事件onCellLocationChanged。所以,要在 onCellLocationChanged中写代码,调用你的query函数。而不是直接使用onclick测试。
Rexsee扩展函数介绍
【函数】 boolean isEnabled()
【说明】 是否正在监听基站定位的变化。
【返回】 true或false。
【参数】 无
【示例】
- alert(rexseeCellLocation.isEnabled());
alert(rexseeCellLocation.isEnabled());
【函数】 boolean enable()
【说明】 开始监听,一旦位置发生变化,会触发事件onCellLocationChanged。
【返回】 true或false。
【参数】 无
【示例】
- alert(rexseeCellLocation.enable());
alert(rexseeCellLocation.enable());
【函数】 boolean disable()
【说明】 停止监听。
【返回】 true或false。
【参数】 无
【示例】
- alert(rexseeCellLocation.disable());
alert(rexseeCellLocation.disable());
【函数】 JsonObject getLastKnownLocation()
【说明】 读取基站定位数据,注意,CDMA网络和GSM网络的定位数据格式是不同的。
【返回】 JSON对象,使用eval('('+json+')')转换为JavaScript对象。
【参数】 无
【示例】
- alert(rexseeCellLocation.getLastKnownLocation());
alert(rexseeCellLocation.getLastKnownLocation());
rexseeCellLocation.java源码如下:
-
- 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();
- }
- 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 + "}";
- }
- }
/*
* 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
*
*
*
* 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 + "}";
}
}仅对Rexsee的源码和函数事件做了整理,相关的demo或源码解析可以在Rexsee社区了解,目前Rexsee已提供了近2000个扩展,覆盖Android原生功能超过90%,且全部开放: