欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

简单实现安卓里百度地图持续定位

程序员文章站 2024-02-21 10:03:10
这几天自己研究了关于地手机上面开发安卓地图的问题,发现百度官方示例demo讲解百度持续定位方面还是讲解的有些不清楚,本人研究了几次之后将其弄得更详细以便于让各位方便学习,有...

这几天自己研究了关于地手机上面开发安卓地图的问题,发现百度官方示例demo讲解百度持续定位方面还是讲解的有些不清楚,本人研究了几次之后将其弄得更详细以便于让各位方便学习,有不足之处请在评论区指出,官方示例的网址是:

上面的网址已经将安卓简单配置百度地图环境讲解的很详细了,再次不做赘述了,此外,可能会有人发现

package com.example.andoridloca;
import java.util.list;
import java.util.timer;
import java.util.timertask;
import android.app.activity;
import android.content.contentvalues;
import android.content.intent;
import android.database.cursor;
import android.os.bundle;
import android.os.handler;
import android.os.message;
import android.text.method.scrollingmovementmethod;
import android.util.log;
import android.view.menu;
import android.view.menuitem;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.textview;
import android.widget.toast;
import com.baidu.location.bdlocation;
import com.baidu.location.bdlocationlistener;
import com.baidu.location.locationclient;
import com.baidu.location.locationclientoption;
import com.baidu.location.bdnotifylistener;//假如用到位置提醒功能,需要import该类
import com.baidu.location.locationclientoption.locationmode;
import com.baidu.location.poi;
import com.baidu.mapapi.sdkinitializer;
import com.baidu.mapapi.map.mapview;
public class mainactivity extends activity implements onclicklistener{
 mapview mmapview = null; 
 public static final string tag="mian";
 stringbuffer sb = new stringbuffer(256);
 public stringbuilder builder=new stringbuilder();
 private button bt1;
 private textview tv1;
 private dbtools dbhelper;
 boolean isopenlocation=false;
 public locationclient mlocationclient = null;
 public bdlocationlistener mylistener = new mylocationlistener();
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  sdkinitializer.initialize(getapplicationcontext()); 
  setcontentview(r.layout.activity_main);
  dbhelper = new dbtools(this); 
  tv1=(textview) findviewbyid(r.id.textview1);
  tv1.setmovementmethod(new scrollingmovementmethod());
  bt1=(button) findviewbyid(r.id.button1);
  bt1.setonclicklistener(this);
  mmapview = (mapview) findviewbyid(r.id.bmapview); 
  mlocationclient = new locationclient(getapplicationcontext());  //声明locationclient类
  mlocationclient.registerlocationlistener( mylistener ); //注册监听函数
  initlocation();
 }
 private void initlocation(){
  locationclientoption option = new locationclientoption();
  option.setlocationmode(locationmode.hight_accuracy
);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
  option.setcoortype("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系
  int span=0;
  option.setscanspan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
  option.setisneedaddress(true);//可选,设置是否需要地址信息,默认不需要
  option.setopengps(true);//可选,默认false,设置是否使用gps
  option.setlocationnotify(true);//可选,默认false,设置是否当gps有效时按照1s1次频率输出gps结果
  option.setisneedlocationdescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在bdlocation.getlocationdescribe里得到,结果类似于“在北京*附近”
  option.setisneedlocationpoilist(true);//可选,默认false,设置是否需要poi结果,可以在bdlocation.getpoilist里得到
  option.setignorekillprocess(false);//可选,默认true,定位sdk内部是一个service,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死 
  option.setignorecacheexception(false);//可选,默认false,设置是否收集crash信息,默认收集
  option.setenablesimulategps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
  mlocationclient.setlocoption(option);
 }
 @override 
 protected void ondestroy() { 
  super.ondestroy(); 
  //在activity执行ondestroy时执行mmapview.ondestroy(),实现地图生命周期管理 
  mmapview.ondestroy(); 
 } 
 @override 
 protected void onresume() { 
  super.onresume(); 
  //在activity执行onresume时执行mmapview. onresume (),实现地图生命周期管理 
  mmapview.onresume(); 
  } 
 @override 
 protected void onpause() { 
  super.onpause(); 
  //在activity执行onpause时执行mmapview. onpause (),实现地图生命周期管理 
  mmapview.onpause(); 
  } 
 public class mylocationlistener implements bdlocationlistener {
  @override
  public void onreceivelocation(bdlocation location) {
   //receive 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("\nlontitude : ");
   sb.append(location.getlongitude());
   sb.append("\nradius : ");
   sb.append(location.getradius());
   if (location.getloctype() == bdlocation.typegpslocation){// gps定位结果
    sb.append("\nspeed : ");
    sb.append(location.getspeed());// 单位:公里每小时
    sb.append("\nsatellite : ");
    sb.append(location.getsatellitenumber());
    sb.append("\nheight : ");
    sb.append(location.getaltitude());// 单位:米
    sb.append("\ndirection : ");
    sb.append(location.getdirection());// 单位度
    sb.append("\naddr : ");
    sb.append(location.getaddrstr());
    sb.append("\ndescribe : ");
    sb.append("gps定位成功");
   } else if (location.getloctype() == bdlocation.typenetworklocation){// 网络定位结果
    sb.append("\naddr : ");
    sb.append(location.getaddrstr());
    //运营商信息
    sb.append("\noperationers : ");
    sb.append(location.getoperators());
    sb.append("\ndescribe : ");
    sb.append("网络定位成功");
   } else if (location.getloctype() == bdlocation.typeofflinelocation) {// 离线定位结果
    sb.append("\ndescribe : ");
    sb.append("离线定位成功,离线定位结果也是有效的");
   } else if (location.getloctype() == bdlocation.typeservererror) {
    sb.append("\ndescribe : ");
    sb.append("服务端网络定位失败,可以反馈imei号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
   } else if (location.getloctype() == bdlocation.typenetworkexception) {
    sb.append("\ndescribe : ");
    sb.append("网络不同导致定位失败,请检查网络是否通畅");
   } else if (location.getloctype() == bdlocation.typecriteriaexception) {
    sb.append("\ndescribe : ");
    sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
   }
    sb.append("\nlocationdescribe : ");
    sb.append(location.getlocationdescribe());// 位置语义化信息
    list<poi> list = location.getpoilist();// poi数据
    if (list != null) {
     sb.append("\npoilist size = : ");
     sb.append(list.size());
     for (poi p : list) {
     sb.append("\npoi= : ");
     sb.append(p.getid() + " " + p.getname() + " " + p.getrank());
     }
    }
   log.i("baidulocationapidem", sb.tostring());
   dbtools dbhelper=new dbtools(getapplicationcontext());
   contentvalues initialvalues = new contentvalues();
   initialvalues.put("shijian",location.gettime());
   initialvalues.put("didian",location.getlatitude()+"--"+location.getlongitude());
   dbhelper.open();
   dbhelper.insert("path",initialvalues);
   dbhelper.close();
   tv1.settext(sb.tostring()); 
  }
 }
 @override
 public void onclick(view arg0) {
  thread mytime=new thread(new threadshow());
   if(isopenlocation){
    mlocationclient.stop();
    isopenlocation=false; 
   }
   else{
    toast.maketext(getapplicationcontext(), "开启", toast.length_short).show();  
    isopenlocation=true;
    //mlocationclient.start();
    mytime.start(); 
   }
  }
 // handler类接收数据 
 handler handler = new handler() { 
  public void handlemessage(message msg) { 
   if (msg.what == 1) { 
    log.i("baidulocationapidem", "加以");
    mlocationclient.start();
    mlocationclient.requestlocation(); 
   } 
  }; 
 }; 
  // 线程类 
 class threadshow implements runnable { 
   @override 
  public void run() { 
   // todo auto-generated method stub 
   while (isopenlocation) { 
    try { 
     mlocationclient.stop();
     thread.sleep(2000); 
     message msg = new message(); 
     msg.what = 1; 
     handler.sendmessage(msg); 
     // system.out.println("send..."); 
    } catch (exception e) { 
     // todo auto-generated catch block 
     e.printstacktrace(); 
     system.out.println("thread error..."); 
    } 
   } 
  } 
 } 
 }

这里面关于mlocationclient.stop();mlocationclient.start();  mlocationclient.requestlocation(); 这三个函数我有必要讲解一下,因为持续定位时这三个函数的配合使用很重要,官方文档里面解释说mlocationclient.start()函数用于开启定位,mlocationclient.requestlocation()函数用于主动触发定位sdk内部定位逻辑,个人感觉差不多,两个都会执行我的mlocationclient的所属类里面的逻辑代码,可能是我的项目就这样吧,然后是mlocationclient.stop(),此函数用于停止定位,如果持续定位的话,是需要和mlocationclient.start()函数配合使用的,具体在上面的代码里面有展示。

切记不要将mlocationclient.start()和mlocationclient.stop()一起使用,我在网上查询时好像是说一部原因,具体举一个例子吧:

//某段代码如果是这样的话按照逻辑韩式会将mlocationclient所属类的里面逻辑代码执行一遍,具体见mainavtivity里面的mylocationlistener类内容,但是实际上是不会执行的
mlocationclient.start();
mlocationclient.stop();

所以在我的mainactivity里面我使用线程来一遍遍的执行start和stop函数,这样就会消除刚刚说的这种效果,最后就能够实现持续定位了。

在此给出我的布局文件配合看看

<linearlayout 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:orientation="vertical"
 tools:context="com.example.newloca.mainactivity" >
<relativelayout 
 android:layout_width="match_parent"
 android:layout_height="300dp">
 <com.baidu.mapapi.map.mapview 
 android:id="@+id/bmapview" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent" 
 android:clickable="true" />
</relativelayout>
 <textview
  android:id="@+id/textview1"
  android:layout_width="match_parent"
  android:layout_height="150dp"
  android:scrollbars="vertical"
  android:background="#f00"
  android:text="位置信息" />
 <relativelayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
   >
  <button
   android:id="@+id/button1"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_alignparentright="true"
   android:layout_alignparentbottom="true"
   android:text="获取位置" />
 </relativelayout>
</linearlayout>

其他像权限什么的配置,用最开始给的官方地址里面的就行了

顺便说一下,本人是使用的安卓4.2版本开发的,手机真机调试和虚拟机调试在定位的时间间隔上面会有点误差,也不知道什么原因

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!