androidGPS和基站混合定位的使用

luoyjx · 2014-11-05 16:14 · 1278次阅读

阐述几个概念:

基站:类似于WIFI热点,官方解释,移动通信系统中,连接固定部分与无线部分,并通过空中的无线传输与移动台相连的设备。基站即公用移动通信基站是无线电台站的一种形式,是指在一定的无线电覆盖区中,通过移动通信交换中心,与移动电话终端之间进行信息传递的无线电收发信电台。
单基站定位是指:通过手机获取当前连接到的基站信息,来确定用户的大概位置(用户可能在某个基站(手机当前连接的基站)发出的无线电覆盖区域中)。
三基站或多基站:通过手机获取附近区域的基站信息(不是用户当前连接的基站,得到的是一组基站信息),来确定用户的大概位置。

多基站定位的思路就是通过移动网络来获取附近基站的信息,然后通过上传这些基站信息到对应的服务器,由服务器来计算你所在的大致位置。

在2012年年底之前,谷歌是提供了这样的api供大家使用的,之后就关闭了,现在有很多第三方的平台提供这种服务,但是这些都不是收费的,都是提供一个接口和一个key供你调用,按请求次数来计费。

随便的找了下,新浪微博和百度地图等很多都有这种api提供,新浪微博的呢,还要先授权登陆,嫌麻烦,非微博相关的三方应用搞这个浪费时间,百度地图的,好像是请求次数有限制还是神马,具体还没有测试过,搜了下看到腾讯的开放API写的是不限制请求次数,所以就做了个用用,好像还行吧,现在使用的是最基本的信息的模式,只获取经纬度等信息的。

以下是腾讯地图SDK中的定位原理:

定位原理
定位SDK使用当前设备的GPS、基站信号和WiFi信号生成定位依据,并将定位依据发送到腾讯的定位服务器。
定位服务器对定位依据进行计算得到定位结果,并将结果返回给定位SDK,由定位SDK回调 app 注册的位置监听器。

从这里可以知道,腾讯的定位是相对来说封装程度较高的,默认的给你判断了是哪种网络并选择最优的,这点有好有坏吧。暂时就用这种倒是挺方便。

在这个例子中,我是以一个Service来使用定位服务的,我这里的场景就是在进入应用后定时的获取定位信息,并向服务器发送,当然,这些是在后台执行的。

直接上代码吧:

哦对,我先讲讲思路:

    需要用到的是三个类

  1.      普通类TXGPS,使用腾讯的API来获取网络或者GPS定位。
  2.     Service类TXGpsService,也就是定时从TXGPS中获取定位信息并发布到广播中的服务(Service)。
  3.     Service类 UploadLocationService,在接收到广播时取出定位信息存储起来,在自己的周期中定时的向服务器发送当前最新的定位信息。

这次真的是代码了。

TXGPS.java

public class TXGPS {

    private Context ctx = null;
    private TencentLocation location = null;
    private TencentLocationRequest request = null;
    private TencentLocationManager locationManager = null;

    public TXGPS(Context ctx){
        this.ctx = ctx;
        request = TencentLocationRequest.create();
        request.setInterval(1000);
        request.setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_GEO);
        locationManager = TencentLocationManager.getInstance(ctx);
        location = locationManager.getLastKnownLocation();
        int error = locationManager.requestLocationUpdates(request, TXLocationListener);
    }

    private TencentLocationListener TXLocationListener = new TencentLocationListener(){
        /**
         * Location变化
         * @param tencentLocation 新的位置
         * @param i 错误码
         * @param s 错误描述
         */
        @Override
        public void onLocationChanged(TencentLocation tencentLocation, int i, String s) {
            if (TencentLocation.ERROR_OK == i) {
                // 定位成功
                location = tencentLocation;
            } else if(TencentLocation.ERROR_NETWORK == i){
                // 网络原因定位失败
                System.out.println("网络原因请求失败");
            } else if(TencentLocation.ERROR_BAD_JSON == i){
                System.out.println("GPS, Wi-Fi 或基站错误引起的定位失败");
            } else if(TencentLocation.ERROR_WGS84 == i){
                System.out.println("无法将WGS84坐标转换成GCJ-02坐标时的定位失败");
            }else if(TencentLocation.ERROR_UNKNOWN == i){
                System.out.println("未知原因引起的定位失败");
            }
        }

        /**
         *
         * @param s GPS,Wi-Fi等
         * @param i 新的状态, 启用或禁用
         * @param s2 状态描述
         */
        @Override
        public void onStatusUpdate(String s, int i, String s2) {

        }
    };

    public TencentLocation getLocation(){
        return location;
    }

    /**
     * 关闭定位
     */
    public void closeLocation(){
        if(locationManager != null){
            if(TXLocationListener != null){
                locationManager.removeUpdates(TXLocationListener);
                TXLocationListener = null;
            }
            locationManager=null;
        }
    }
}

TXGpsService.java

public class TXGpsService extends Service {

    private TXGPS gps=null;
    private boolean threadDisable=false;

    @Override
    public void onCreate() {
        super.onCreate();

        gps = new TXGPS(TXGpsService.this);

        new Thread(new Runnable(){
            @Override
            public void run() {
                while (!threadDisable) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if(gps!=null){ //当结束服务时gps为空
                        //获取经纬度
                        TencentLocation location = gps.getLocation();
                        //发送广播
                        Intent intent=new Intent();
                        intent.putExtra("lat", location==null?"":location.getLatitude()+"");
                        intent.putExtra("lon", location==null?"":location.getLongitude()+"");
                        intent.putExtra("alt", location==null?"":location.getAltitude()+"");
                        intent.putExtra("userId", GlobalApplication.userInfo.getId());
                        intent.putExtra("username", GlobalApplication.userInfo.getUserName());
                        intent.setAction("xxx.xxx.xxx.TXGpsService");
                        sendBroadcast(intent);
                    }
                }
            }
        }).start();
    }

    @Override
    public void onDestroy() {
        threadDisable=true;
        if(gps!=null){
            gps.closeLocation();
            gps=null;
        }
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

UploadLocationService.java

public class UploadLocationService extends Service {

    private boolean threadDisable = false;
    private GpsReceiver receiver = null;
    private String lon = "";
    private String lat = "";
    private String alt = "";
    private String userId = "0";
    private String username = "";

    @Override
    public void onCreate() {
        //注册广播
        receiver = new GpsReceiver();
        IntentFilter filter=new IntentFilter();
        filter.addAction("xxx.xxx.xxx.TXGpsService");
        registerReceiver(receiver, filter);

        new Thread(new Runnable(){
            @Override
            public void run() {
                while (!threadDisable) {
                    try {
                        Thread.sleep(600000);//十分钟上传一次路径点
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
//                    System.out.println("======>上传路径点");
                    if("".equals(lon) || "".equals(lat) ||"".equals(alt)){//未获取坐标信息则不上传
                        System.out.println("未获取路径点坐标");
                        continue;
                    }
                    //封装参数
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    params.add(new BasicNameValuePair("data", "{userId:"+ userId +",userName:'"+ username +"',routeDate: "+ new Date().getTime() +",longitude: '"+ lon +"', latitude:'"+lat+"', altitude: '"+alt+"'}"));
                    Thread companyThread = new Thread(new RestHandler(getString(R.string.rest_upload_route), params, dataHandler));
                    companyThread.start();
                }
            }
        }).start();
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        threadDisable=true;
        if(receiver != null){
            unregisterReceiver(receiver);
        }
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    Handler dataHandler = new Handler(){
        public void handleMessage(Message msg) {
            //登录失败,返回原因
            int  isNetError = msg.getData().getInt("ResultCode");
            switch (isNetError){
                case 0:
                    System.out.println(msg.getData().getString("result"));
                    if (msg.getData().getString("result").indexOf("success") != -1){
                        System.out.println("上传成功");
                    }else{
                        System.out.println("上传失败");
                    }
                    break;
                case 1:
                    System.out.println("查询失败:请检查您网络连接.");
                    break;
                case 2:
                    System.out.println("系统服务异常.");
                    break;
            }
        }
    };

    //获取广播数据
    private class GpsReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
//            System.out.println("==================>接收到GPS信息广播");
            Bundle bundle=intent.getExtras();
            lon = bundle.getString("lon");
            lat = bundle.getString("lat");
            alt = bundle.getString("alt");
            userId = bundle.getString("userId");
            username = bundle.getString("username");
//            System.out.println("=====>lon"+lon+"====>lat"+lat+"=====>alt"+alt+"====>username"+userId+"====>username"+username);
        }
    }

}

大致例子就是这样了,有建议或者错误的可以给我留言或者邮件,yjk99@qq.com

收藏

暂无评论

登录后可以进行评论。没有账号?马上注册