百度地图后台持续定位<定位SDK-6.13>

来源:互联网 发布:python 时间戳 整数 编辑:程序博客网 时间:2024/04/26 02:09

此实现可以在后台持续进行定位,将经纬度信息传给服务器或者其他操作。
在定位之前请先准备好:百度地图定位SDK和相关权限配置(具体参照Baidu官方文档)。
后台持续重复定位,具体实现是通过调用自定义服务实现,在服务中创建定时器,在定时器中定时进行定位。
自定义服务,在此服务中进行定位。注意要在清单配置文件中注册该服务。

public class LocationServices extends Service{    //定位点信息    public LatLng latlng;    private String strLocationProvince;//定位点的省份    private String strLocationCity;//定位点的城市    private String strLocationDistrict;//定位点的区县    private String strLocationStreet;//定位点的街道信息    private String strLocationStreetNumber;//定位点的街道号码    private String strLocationAddrStr;//定位点的详细地址(包括国家和以上省市区等信息)    private LocationClient mLocationClient =null;//定位客户端    public MyLocationListener mMyLocationListener = new MyLocationListener();;    private Timer mTimer = null;    private TimerTask mTimerTask = null;    private boolean isStop = false;    @Override    public void onCreate() {        // TODO Auto-generated method stub        super.onCreate();        mLocationClient = new LocationClient(getApplicationContext());        mLocationClient.setLocOption(setLocationClientOption());        mLocationClient.registerLocationListener(mMyLocationListener);    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        // 触发定时器        if (!isStop) {            Log.i("tag", "定时器启动");            startTimer();        }        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        // TODO Auto-generated method stub        if (mLocationClient!=null) {            mLocationClient.stop();        }        super.onDestroy();        // 停止定时器        if (isStop) {            Log.i("tag", "定时器服务停止");            stopTimer();        }    }    /**     * 定时器 每隔一段时间执行一次     */    private void startTimer() {        isStop = true;//定时器启动后,修改标识,关闭定时器的开关        if (mTimer == null) {            mTimer = new Timer();        }        if (mTimerTask == null) {            mTimerTask = new TimerTask() {                @Override                public void run() {                    do {                        try {                            Log.d("tag", "isStop="+isStop);                            Log.d("tag", "mMyLocationListener="+mMyLocationListener);                            mLocationClient.start();                            Log.d("tag", "mLocationClient.start()");                            Log.d("tag", "mLocationClient=="+mLocationClient);                            Thread.sleep(1000*3);//3秒后再次执行                        } catch (InterruptedException e) {                            // TODO Auto-generated catch block                            e.printStackTrace();                        }                    } while (isStop);                }            };        }        if (mTimer != null && mTimerTask != null) {            Log.d("tag", "mTimer.schedule(mTimerTask, delay)");            mTimer.schedule(mTimerTask, 0);//执行定时器中的任务        }    }    /**     * 停止定时器,初始化定时器开关     */    private void stopTimer() {        if (mTimer != null) {            mTimer.cancel();            mTimer = null;        }        if (mTimerTask != null) {            mTimerTask.cancel();            mTimerTask = null;        }        isStop = false;//重新打开定时器开关        Log.d("tag", "isStop="+isStop);    }       @Override    public IBinder onBind(Intent intent) {        // TODO Auto-generated method stub        return null;    }    /**     * 定位客户端参数设定,更多参数设置,查看百度官方文档     * @return     */    private LocationClientOption setLocationClientOption() {        LocationClientOption option = new LocationClientOption();        option.setLocationMode(com.baidu.location.LocationClientOption.LocationMode.Hight_Accuracy);// 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备        option.setScanSpan(1000);//每隔1秒发起一次定位        option.setCoorType("bd09ll");// 可选,默认gcj02,设置返回的定位结果坐标系        option.setOpenGps(true);//是否打开gps        option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到该描述,不设置则在4G情况下会默认定位到“天安门广场”        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要,不设置则拿不到定位点的省市区信息        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到        option.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果        /*可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”        该参数若不设置,则在4G状态下,会出现定位失败,将直接定位到天安门广场         */        return option;    }    /**     * 定位监听器     * @author User     *     */    public class MyLocationListener implements BDLocationListener {        @Override        public void onReceiveLocation(BDLocation location) {            if (location==null) {                return;            }            double lat = location.getLatitude();            double lng = location.getLongitude();            latlng = new LatLng(lat, lng);            //定位点地址信息做非空判断            if ("".equals(location.getProvince())) {                strLocationProvince = "未知省";            }else {                strLocationProvince = location.getProvince();            }            if ("".equals(location.getCity())) {                strLocationCity = "未知市";            }else {                strLocationCity = location.getCity();            }            if ("".equals(location.getDistrict())) {                strLocationDistrict = "未知区";            }else {                strLocationDistrict = location.getDistrict();            }            if ("".equals(location.getStreet())) {                strLocationStreet = "未知街道";            }else {                strLocationStreet = location.getStreet();            }            if ("".equals(location.getStreetNumber())) {                strLocationStreetNumber = "";            }else {                strLocationStreetNumber =location.getStreetNumber();            }            if ("".equals(location.getAddrStr())) {                strLocationAddrStr = "";            }else {                strLocationAddrStr =location.getAddrStr();            }            //定位成功后对获取的数据依据需求自定义处理,这里只做log显示            Log.d("tag", "latlng.lat="+lat);            Log.d("tag", "latlng.lng="+lng);            Log.d("tag", "strLocationProvince="+strLocationProvince);            Log.d("tag", "strLocationCity="+strLocationCity);            Log.d("tag", "strLocationDistrict="+strLocationDistrict);            // 到此定位成功,没有必要反复定位            // 应该停止客户端再发送定位请求            if (mLocationClient.isStarted()) {                Log.d("tag", "mLocationClient.isStarted()==>mLocationClient.stop()");                mLocationClient.stop();            }        }    }}

在Application中初始化SDK,如果不需要在Application中初始化,在MainActivity中setContentView方法之前初始化也可以。百度官方建议在Application中初始化。

public class MyApplication extends Application{    @Override    public void onCreate() {        // TODO Auto-generated method stub        super.onCreate();        // 在使用 SDK 各组间之前初始化 context 信息,传入 ApplicationContext        SDKInitializer.initialize(this);    }}

在MainActivity中开启和关闭服务。

public class MainActivity extends Activity {    private Button startService;          private Button stopService;      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        startService = (Button) findViewById(R.id.start_service);        stopService = (Button) findViewById(R.id.stop_service);        startService.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                Intent startIntent = new Intent(MainActivity.this, LocationServices.class);                startService(startIntent);            }        });        stopService.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                Intent stopIntent = new Intent(MainActivity.this, LocationServices.class);                stopService(stopIntent);            }        });    }    @Override    protected void onDestroy() {        // TODO Auto-generated method stub        Log.d("tag", "MainActivity.onDestroy()");        Intent stopIntent = new Intent(MainActivity.this, LocationServices.class);        stopService(stopIntent);        super.onDestroy();    }}

MainActivity.xml布局。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.bdlocationdemo.activity.MainActivity" >    <Button          android:id="@+id/stop_service"          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:text="StopService" />    <Button        android:id="@+id/start_service"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:layout_marginTop="77dp"        android:text="StartService" /></RelativeLayout>

特别注意:
在清单配置文件中,需要声明百度定位服务,这样才能重复定位,否则服务开启后只会执行第一次定位,后面执行的LocationClient.start();方法,都不会执行定位监听器BDLocationListener中的代码,这里需要特别留意。

        <!-- 注册自己的服务 -->        <service            android:name="com.example.bdlocationdemo.services.LocationServices"            android:enabled="true"            android:exported="true" >        </service>        <!-- 必须声明这个服务,才能在服务中定时重复定位 -->        <service            android:name="com.baidu.location.f"            android:enabled="true"            android:process=":remote" >        </service>
0 2