wifi 定位 java_在Android里完美实现基站和WIFI定位

众所周知的,在OPhone和大部分国产的Android定制机里不支持最简单实用的基站和WIFI定位,只能使用速度慢而耗电的GPS定位,但OPhone和华为/中兴生产的一些Android定制机却占据了一定的市场,因此导致了很多使用了定位技术的Andorid应用挺尴尬的。

不过其实只要明白了基站/WIFI定位的原理,自己实现基站/WIFI定位其实不难。基站定位一般有几种,第一种是利用手机附近的三个基站进行三角定位,由于每个基站的位置是固定的,利用电磁波在这三个基站间中转所需要时间来算出手机所在的坐标;第二种则是利用获取最近的基站的信息,其中包括基站id,location area code、mobile country code、mobile network code和信号强度,将这些数据发送到google的定位web服务里,就能拿到当前所在的位置信息,误差一般在几十米到几百米之内。其中信号强度这个数据很重要,网上很多所谓的手动通过基站和WIFI信息定位的方法误差大都是因为没使用信号强度而导致误差过大。高德也自己做了一个基站库,具体可以google搜索一下。

现在在一些大中型城市里,WIFI已经普及,有私人或企业的WIFI,亦有中国电信的WIFI,通过WIFI信息进行定位,并不需要真正连接上指定的WIFI路由器,只需要探测到有WIFI存在即可,因此当手机使用的不是GSM制式(因为google的基站库里并没在保存太多的CDMA基站)的时候,也可以使用WIFI进行定位,原理也和基站定位一样,必须要拿到WIFI路由器的SSID和信号强度。

由于有些用户默认是将WIFI关闭的,通过API开启WIFI硬件并进行搜索附近的WIFI路由器需要一段时间,怎样才能将手机基站定位和WIFI定位完美结合起来呢,Android提供了一种很好的机制,就是Handler和Looper,Handler和Looper一般用于跨线程传递数据,但当在单线程里使用时,就变成了一个先进先出的消息泵。利用这个消息泵进行调度,就可以将基站定位和WIFI定位完美结合。以下是相关的代码:

CellInfoManager

import java.lang.reflect.Method;

import java.util.Iterator;

import java.util.List;

import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;

import android.content.Context;

import android.telephony.CellLocation;

import android.telephony.NeighboringCellInfo;

import android.telephony.PhoneStateListener;

import android.telephony.TelephonyManager;

import android.telephony.gsm.GsmCellLocation;

import android.util.Log;

public class CellInfoManager {

private int asu;

private int bid;

private int cid;

private boolean isCdma;

private boolean isGsm;

private int lac;

private int lat;

private final PhoneStateListener listener;

private int lng;

private int mcc;

private int mnc;

private int nid;

private int sid;

private TelephonyManager tel;

private boolean valid;

private Context context;

public CellInfoManager(Context paramContext) {

this.listener = new CellInfoListener(this);

tel = (TelephonyManager) paramContext.getSystemService(Context.TELEPHONY_SERVICE);

this.tel.listen(this.listener, PhoneStateListener.LISTEN_CELL_LOCATION | PhoneStateListener.LISTEN_SIGNAL_STRENGTH);

context = paramContext;

}

public static int dBm(int i) {

int j;

if (i >= 0 && i <= 31)

j = i * 2 + -113;

else

j = 0;

return j;

}

public int asu() {

return this.asu;

}

public int bid() {

if (!this.valid)

update();

return this.bid;

}

public JSONObject cdmaInfo() {

if (!isCdma()) {

return null;

}

JSONObject jsonObject = new JSONObject();

try {

jsonObject.put("bid", bid());

jsonObject.put("sid", sid());

jsonObject.put("nid", nid());

jsonObject.put("lat", lat());

jsonObject.put("lng", lng());

} catch (JSONException ex) {

jsonObject = null;

Log.e("CellInfoManager", ex.getMessage());

}

return jsonObject;

}

public JSONArray cellTowers() {

JSONArray jsonarray = new JSONArray();

int lat;

int mcc;

int mnc;

int aryCell[] = dumpCells();

lat = lac();

mcc = mcc();

mnc = mnc();

if (aryCell == null || aryCell.length < 2) {

aryCell = new int[2];

aryCell[0] = cid;

aryCell[1] = -60;

}

for (int i = 0; i < aryCell.length; i += 2) {

try {

int j2 = dBm(i + 1);

JSONObject jsonobject = new JSONObject();

jsonobject.put("cell_id", aryCell[i]);

jsonobject.put("location_area_code", lat);

jsonobject.put("mobile_country_code", mcc);

jsonobject.put("mobile_network_code", mnc);

jsonobject.put("signal_strength", j2);

jsonobject.put("age", 0);

jsonarray.put(jsonobject);

} catch (Exception ex) {

ex.printStackTrace();

Log.e("CellInfoManager", ex.getMessage());

}

}

if (isCdma())

jsonarray = new JSONArray();

return jsonarray;

}

public int cid() {

if (!this.valid)

update();

return this.cid;

}

public int[] dumpCells() {

int[] aryCells;

if (cid() == 0) {

aryCells = new int[0];

return aryCells;

}

List lsCellInfo = this.tel.getNeighboringCellInfo();

if (lsCellInfo == null || lsCellInfo.size() == 0) {

aryCells = new int[1];

int i = cid();

aryCells[0] = i;

return aryCells;

}

int[] arrayOfInt1 = new int[lsCellInfo.size() * 2 + 2];

int j = 0 + 1;

int k = cid();

arrayOfInt1[0] = k;

int m = j + 1;

int n = asu();

arrayOfInt1[j] = n;

Iterator iter = lsCellInfo.iterator();

while (true) {

if (!iter.hasNext()) {

break;

}

NeighboringCellInfo localNeighboringCellInfo = (NeighboringCellInfo) iter.next();

int i2 = localNeighboringCellInfo.getCid();

if ((i2 <= 0) || (i2 == 65535))

continue;

int i3 = m + 1;

arrayOfInt1[m] = i2;

m = i3 + 1;

int i4 = localNeighboringCellInfo.getRssi();

arrayOfInt1[i3] = i4;

}

int[] arrayOfInt2 = new int[m];

System.arraycopy(arrayOfInt1, 0, arrayOfInt2, 0, m);

aryCells = arrayOfInt2;

return aryCells;

}

public JSONObject gsmInfo() {

if (!isGsm()) {

return null;

}

JSONObject localObject = null;

while (true) {

try {

JSONObject localJSONObject1 = new JSONObject();

String str1 = this.tel.getNetworkOperatorName();

localJSONObject1.put("operator", str1);

String str2 = this.tel.getNetworkOperator();

if ((str2.length() == 5) || (str2.length() == 6)) {

String str3 = str2.substring(0, 3);

String str4 = str2.substring(3, str2.length());

localJSONObject1.put("mcc", str3);

localJSONObject1.put("mnc", str4);

}

localJSONObject1.put("lac", lac());

int[] arrayOfInt = dumpCells();

JSONArray localJSONArray1 = new JSONArray();

int k = 0;

int m = arrayOfInt.length / 2;

while (true) {

if (k >= m) {

localJSONObject1.put("cells", localJSONArray1);

localObject = localJSONObject1;

break;

}

int n = k * 2;

int i1 = arrayOfInt[n];

int i2 = k * 2 + 1;

int i3 = arrayOfInt[i2];

JSONObject localJSONObject7 = new JSONObject();

localJSONObject7.put("cid", i1);

localJSONObject7.put("asu", i3);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值