Android手机定位

一.前言:

当前越来越多的安卓应用开始使用基于LBS的服务来完善用户体验。术语LBS(Location Based Service)可以称为基于位置信息的服务,使用百度地图或google地图进行开发的应用程序不可避免的要使用到定位功能。

首先说明一下,android系统其实自带了实现定位功能的API,主要使用AndroidFramework中的LocationManager类和Location类。

 locationManager.requestLocationUpdates(
         LocationManager.NETWORK_PROVIDER,   0,0,locationListener);

但是使用Android自带的API经常会遇到返回的location为null的情况,这是因为很多国内的手机在出厂的时候系统都被阉割过,导致在使用定位API的时候经常遇见错误。

因此一般建议使用百度定位API或者是Google地图API,百度地图在定位国内的地理位置时比较优秀,很多小的地理坐标都有明确标示而Google地图在世界范围内的位置坐标比较明确。

二.手机定位方式简介

1.GPS定位方式
最简单的手机定位方式当然是通过GPS模块(现在大部分的智能机应该都有了)。GPS方式准确度是最高的,但是它的缺点也非常明显:
(1),比较耗电;
(2),绝大部分用户默认不开启GPS模块;
(3),从GPS模块启动到获取第一次定位数据,可能需要比较长的时间;
(4),室内几乎无法使用。
这其中,缺点2,3都是比较致命的。需要指出的是,GPS走的是卫星通信的通道,在没有网络连接的情况下也能用。
2.Network定位方式
(1).基站定位
大致思路就是采集到手机上的基站ID号(cellid)和其它的一些信息(MNC,MCC,LAC等等),然后通过网络访问一些定位服务,获取并返回对应的经纬度坐标。基站定位的精确度不如GPS,但好处是能够在室内用,只要网络通畅就行。
(2).Wifi定位
和基站定位类似,这种方式是通过获取当前所用的wifi的一些信息,然后访问网络上的定位服务以获得经纬度坐标。
因为这两种方式都要借用网络进行定位,因此可以统称为网络定位方式。

三.使用百度API进行手机定位

3.1 开发前的准备

(1). 以locSDK*_3.1.jar为例。对用使用到liblocSDK3.so文件,这些都可以在百度云api的网站上下载。首先在libs文件夹下面建立armeabi文件夹,将liblocSDK3.so放到该文件夹下,将locSKD_*3.1.jar导入到项目中。
(2). 注意:红色警告
一定要将locSDK_3.1.jar放到libs文件夹下面,否则定位系统崩溃。(亲自遇见多次,慎重。)
(3). 百度定位是以服务的形式在后台开启,因此必须在manifest.xml文件中添加服务。

<service
             android:enabled = "true"
             android:name="com.baidu.location.f"
             android:process=":remote"
            >

</service>

(4).定位API需要开启很多权限

   <uses-permission android:name="android.permission.INTERNET" />  
    <!-- 访问精确位置的权限 -->  
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
    <!-- 访问网络状态的权限 -->  
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
    <!-- 访问WIFI网络状态的权限 -->  
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  
    <!-- 改变WIFI网络状态的权限 -->  
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />  
    <!-- 读写存储卡的权限 -->  
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
    <!-- 读取电话状态的权限 -->  
<uses-permission android:name="android.permission.READ_PHONE_STATE" />  

3.2 主要对象简介

(1).LocationClient类
定位需要的”句柄“类。
(2).LocationClientOption类
通过设置该类的对象间接完成对LocationClient对象的修改。
(3).自定义MyLocationListener继承BDLocationListener
该类主要有两个需要实现的回调函数,一般复写OnReceiveLoation(BDLocation location)方法。

3.3 Source Code

主界面显示当前位置的信息等参数。

package com.example.exadapter;

import java.util.ArrayList;
import java.util.List;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity 
{

    @Override
    protected void onStop() 
    {
        // TODO Auto-generated method stub
        mLocationClient.stop();
        super.onStop();
    }



    //定位相关的变量
    private LocationClient mLocationClient = null;
    private BDLocation bdloca;
    public MyLocationListener myLocListener = new MyLocationListener();
    TextView locTV;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        initView();
        locListener();
    }

    /*
     * 定位SDK监听函数
     * 
     * */
    public class MyLocationListener implements BDLocationListener
    {

        @Override
        public void onReceiveLocation(BDLocation location) {
            // TODO Auto-generated method stub
            if(location == null)
            {
                return;
            }
            bdloca = location;
            StringBuffer sb = new StringBuffer(256);
            sb.append("time: ");
            sb.append(location.getTime());
            sb.append("\nerror code: ");
            sb.append(location.getLocType());
            sb.append("\nlatitude : ");
            sb.append(location.getLatitude());
            sb.append("\nlongitude : ");
            sb.append(location.getLongitude());
            sb.append("\nradius : ");
            sb.append(location.getRadius());

            if(location.getLocType() == BDLocation.TypeGpsLocation)
            {
                sb.append("\nspeed: ");
                sb.append(location.getSpeed());
                sb.append("\nsatellite: ");
                sb.append(location.getSatelliteNumber());
            }
            else if(location.getLocType() == BDLocation.TypeNetWorkLocation)
            {
                sb.append("\naddr: ");
                sb.append(location.getAddrStr());
            }

            sb.append("\nsdk version: ");
            sb.append(mLocationClient.getVersion());
            locTV.setText(sb.toString());
            locTV.setTextSize(20);
            locTV.setTextColor(Color.RED);

        }

        @Override
        public void onReceivePoi(BDLocation arg0) {
            // TODO Auto-generated method stub

        }

    }  
    private void locListener()
    {
        mLocationClient = new LocationClient(this);
        LocationClientOption option = new LocationClientOption();
        option.setAddrType("all");
        option.setPoiExtraInfo(true);
        option.setProdName("定位我当前的位置");
        option.setPoiDistance(500);
        option.setCoorType("bd0911");
        option.setPoiNumber(3);
        option.setPriority(LocationClientOption.NetWorkFirst);
        option.setOpenGps(true);
        option.setScanSpan(5000);
        mLocationClient.setLocOption(option);

        mLocationClient.registerLocationListener(myLocListener);
        mLocationClient.start();
    }

    protected void initView()
    {
       locTV = (TextView) findViewById(R.id.locInfo);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

3.4.具体的各个参数的意义,可以查看百度官方的文档,都有详细的介绍。

四.App界面展示

这里写图片描述

下面的界面是一个ExpandableListView控件,用来做测试用的。

五.总结
手机定位是一个很实用的功能,现在基于LBS的手机APP越来越多,理解和掌握定位的实现具有很大的实际意义。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值