当前位置:操作系统 > 安卓/Android >>

在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());

              }

       &nbs

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,