locationbasedservice(Android学习笔记之——基于位置的服务)

发布时间:2025-12-10 19:15:27 浏览次数:7

Android学习笔记之——基于位置的服务-

Android学习笔记之——基于位置的服务(location-based service)基于位置的服务简称LBS,随着移动互联网的兴起,这个技术在最近的几年里十分火爆。其实它本身并不是什么时髦的技术,主要的工作原理就是利用无线电通讯网络或GPS等定位方式来确定出移动设备所在的位置,而这种定位技术早在很多年前就已经出现了。…

基于位置的服务简称LBS,随着移动互联网的兴起,这个技术在最近的几年里十分火爆。其实它本身并不是什么时髦的技术,主要的工作原理就是利用无线电通讯网络或GPS等定位方式来确定出移动设备所在的位置,而这种定位技术早在很多年前就已经出现了。

那为什么LBS技术直到最近几年才开始流行呢?这主要是因为,在过去移动设备的功能极其有限,即使定位到了设备所在的位置,也就仅仅只是定位到了而已,我们并不能在位置的基础上进行一些其他的操作。而现在就大大不同了,有了Android系统作为载体,我们可以利用定位出的位置进行许多丰富多彩的操作。比如说天气预报程序可以根据用户所在的位置自动选择城市,发微博的时候我们可以向朋友们晒一下自己在哪里,不认识路的时候随时打开地图就可以查询路线,等等。

基于位置的服务所围绕的核心就是要先确定出用户所在的位置。通常有两种技术方式可以实现:一种是通过GPS定位,一种是通过网络定位。GPS定位的工作原理是基于手机内置的GPS硬件直接和卫星交互来获取当前的经纬度信息,这种定位方式精确度非常高,但缺点是只能在室外使用,室内基本无法接收到卫星的信号。网络定位的工作原理是根据手机当前网络附近的三个基站进行测速,以此计算出手机和每个基站之间的距离,再通过三角定位确定出一个大概的位置,这种定位方式精确度一般,但优点是在室内室外都可以使用。

Android对这两种定位方式都提供了相应的API支持,本博文采用百度原生API来实现LBS

目录

申请API key

获取SHA1

使用百度定位

准备LBS SDK

确定自己位置的经纬度

选择定位模式

更直观的位置信息

使用百度地图

让地图显示出来

让“我”显示在地图上

参考资料


申请API key

要想在自己的应用程序里使用百度的LBS功能,首先必须申请一个API Key。得拥有一个百度账号才能进行申请,登录百度账号,并打开下面的网站。在这里填写一些注册信息即可

http://developer.baidu.com/user/reg

接着访问http://lbsyun.baidu.com/apiconsole/key,然后同意百度开发者协议,会看到如下图所示的界面。

点击同意后

由于这是一个刚刚注册的账号,所以目前的应用列表是空的。接下来点击创建应用就可以去申请API Key了,应用名称可以随便填,应用类型选择Android SDK,启用服务保持默认即可,如下图所示。

获取SHA1

这个发布版SHA1和开发版SHA1又是个什么东西呢?这是我们申请API Key所必须填写的一个字段,它指的是打包程序时所用签名文件的SHA1指纹,可以通过Android Studio查看到。打开Android Studio中的任意一个项目,点击右侧工具栏的Gradle→项目名→:app→Tasks→android,如下图所示。

这里展示了一个Android Studio项目中所有内置的Gradle Tasks,其中signingReport这个Task就可以用来查看签名文件信息。双击signingReport,结果如图所示。

根本没有找到sha1证书指纹数据。通过在Android Studio中的Terminal中使用keytool获取了,具体如下所示

我这里只出现SHA-256

试试cmd(可以了~)

在控制台内,定位到.android文件夹,输入cd .android

keytool -list -v -keystore debug.keystore

是否还在为Ide开发工具频繁失效而烦恼,来吧关注以下公众号获取最新激活方式。亲测可用!

为防止网络爬虫,请关注公众号回复”口令”

激活idea 激活CLion DataGrip DataSpell dotCover dotMemory dotTrace GoLand PhpStorm PyCharm ReSharper ReShaC++ Rider RubyMine WebStorm 全家桶 刷新

【正版授权,激活自己账号】:Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】:官方授权 正版激活 自己使用,支持Jetbrains家族下所有IDE…

接下来点击提交,应用就应该创建成功了,如下图所示

就是申请到的API Key,有了它就可以进行后续的LBS开发工作了

使用百度定位

现在正是趁热打铁的好时机,新建一个LBSTest项目,包名应该就会自动被命名为com.example.lbstest。

准备LBS SDK

在开始编码之前,我们还需要先将百度LBS开放平台的SDK准备好,下载地址是:

http://lbsyun.baidu.com/index.php?title=sdk/download&action

我们会用到基础地图和定位功能这两个SDK,将它们勾选上,然后点击“开发包”下载按钮即可,

下载完成后对该压缩包解压,其中会有一个libs目录,这里面的内容就是我们所需要的一切了,如图所示。

libs目录下的内容又分为两部分,BaiduLBS_Android.jar这个文件是Java层要使用到的,其他子目录下的so文件是Native层要用到的。so文件是用C/C++语言进行编写,然后再用NDK编译出来的。当然这里我们并不需要去编写C/C++的代码,因为百度都已经做好了封装,但是我们需要将libs目录下的每一个文件都放置到正确的位置。

首先观察一下当前的项目结构,你会发现app模块下面有一个libs目录,这里就是用来存放所有的Jar包的,我们将BaiduLBS_Android.jar复制到这里,如图所示。

接下来展开src/main目录,右击该目录→New→Directory,再创建一个名为jniLibs的目录,这里就是专门用来存放so文件的,然后把压缩包里的其他所有目录直接复制到这里,如图所示(有点类似于opencv)。

另外,虽然所有新创建的项目中,app/build.gradle文件都会默认配置以下这段声明:

dependencies {    implementation fileTree(dir: 'libs', include: ['*.jar'])    implementation 'androidx.appcompat:appcompat:1.1.0'    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'    testImplementation 'junit:junit:4.12'    androidTestImplementation 'androidx.test.ext:junit:1.1.1'    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'}

这表示会将libs目录下所有以.jar结尾的文件添加到当前项目的引用中。但是由于我们是直接将Jar包复制到libs目录下的,并没有修改gradle文件,因此不会弹出我们平时熟悉的Sync Now提示。这个时候必须手动点击一下Android Studio顶部工具栏中的Sync按钮,不然项目将无法引用到Jar包中提供的任何接口。(找不到这个按钮,但是可以随意更改一下同步,在删掉同步)

点击Sync按钮之后,libs目录下的jar文件就会多出一个向右的箭头,这就表示项目已经能引用到这些Jar包了

好了,这样我们就把LBS的SDK都准备好了,接下来开始编码吧。

确定自己位置的经纬度

首先修改activity_main.xml中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:andro    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <TextView        android:        android:layout_width="wrap_content"        android:layout_height="wrap_content"        /></LinearLayout>

布局文件中的内容非常简单,只有一个TextView控件,用于稍后显示当前位置的经纬度信息。

然后修改AndroidManifest.xml文件中的代码,添加权限如下所示:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/><uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/><uses-permission android:name="android.permission.READ_PHONE_STATE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><uses-permission android:name="android.permission.WAKE_LOCK"/>

这里首先添加了很多行权限声明,每一个权限都是百度LBS SDK内部要用到的。

然后在<application> 标签的内部添加了一个<meta-data> 标签,这个标签的android:name 部分是固定的,必须填com.baidu.lbsapi.API_KEY ,android:value 部分则应该填入前面申请到的API Key。

最后,还需要再注册一个LBS SDK中的服务,

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:andro    xmlns:tools="http://schemas.android.com/tools"    package="com.example.lbstest">    <!-- 获取粗略位置 -->    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>    <!--获取精确gps位置-->    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>    <!-- 获取wifi状态 -->    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>    <!-- 获取网络状态 -->    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>    <!-- 更改wifi连状态 -->    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>    <!-- 读写sd卡 -->    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <!-- 网络链接 -->    <uses-permission android:name="android.permission.INTERNET"/>    <!--允许程序读写手机状态和身份-->    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"        tools:ignore="ProtectedPermissions" />    <uses-permission android:name="android.permission.WAKE_LOCK"/>    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <meta-data            android:name="com.baidu.lbsapi.API_KEY"            android:value="SWgGmRt1AKucEnXEpQG712tL4tpA58oR"/>        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <!--定义百度地图的服务,用于定位-->        <service android:name="com.baidu.location.f"            android:enabled="true"            android:process=":remote">        </service>    </application></manifest>

接下来修改MainActivity中的代码,如下所示:

package com.example.lbstest;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;import android.Manifest;import android.content.pm.PackageManager;import android.os.Bundle;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 java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    private TextView positionText;    public LocationClient mLocationClient;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //构建一个LocationClient的实例        mLocationClient=new LocationClient(getApplicationContext());//LocationClient的构建函数接收一个context参数        //调用getApplicationContext() 方法来获取一个全局的Context 参数并传入        //调用registerLocationListener方法来注册一个定位的监听器。当获取到位置信息的时候,就会回调这个定位监听器。        mLocationClient.registerLocationListener(new MyLocationListener());        positionText=(TextView) findViewById(R.id.position_text_view);        //如果没有启动下面权限,就询问用户让用户打开        List<String> permissionList=new ArrayList<>();        //创建一个空的list集合,然后依次判断这3个权限有没有被授权        //如果没被授权就添加到List集合中        //最后将List转换成数组        //采用运行时权限。对于危险权限是需要进行运行时权限处理的        if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED)        {            //由于ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION属于同一个权限组,只需申请一个即可            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);        }        if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED)        {            permissionList.add(Manifest.permission.READ_PHONE_STATE);        }        if (ContextCompat.checkSelfPermission(MainActivity.this,                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);        }        if (!permissionList.isEmpty()) {            String[] permissions = permissionList.toArray(new String[permissionList.size()]);//将List转换成数组            //调用ActivityCompat.requestPermissions() 方法一次性申请            ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);        }        else {            requestLocation();        }    }    //监听线程,获得当前的经纬度,并显示    public class MyLocationListener implements BDLocationListener{        @Override        public void onReceiveLocation(final BDLocation bdLocation) {            runOnUiThread(new Runnable() {//不能在主线程(UI线程)以外操作UI,android中把耗时的操作都放到子线程里面                @Override                public void run() {                    StringBuilder currentPosition = new StringBuilder();//一个可变的字符序列                    currentPosition.append("纬度:").append(bdLocation.getLatitude()).append("\n");                    currentPosition.append("经线:").append(bdLocation.getLongitude()).append("\n");                    currentPosition.append("定位方式:");                    if (bdLocation.getLocType()==BDLocation.TypeGpsLocation){                        currentPosition.append("GPS");                    }else if (bdLocation.getLocType()==BDLocation.TypeNetWorkLocation)                    {                        currentPosition.append("网络");                    }                    positionText.setText(currentPosition);                }            });        }    }    //*初始化函数,并启动位置客户端LocationClient*/    private void requestLocation() {        initLocation();        //默认情况下,调用LocationClient的start() 方法只会定位一次        mLocationClient.start();//调用方法来启动定位。定位的结果会反馈到上面所注册的监听器MyLocationListener中    }    private void initLocation(){        LocationClientOption option = new LocationClientOption();        option.setScanSpan(5000);//调用setScanSpan方法设置更新的间隔(每5秒会更新一下当前的位置)        mLocationClient.setLocOption(option);    }    //只有同意打开相关权限才可以开启本程序    @Override    public void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults){        //通过一个循环将申请的每个权限都进行了判断,如果有任何一个权限被拒绝        // 那么就直接调用finish() 方法关闭当前程序,        // 只有当所有权限都被用户同意了,才会调用requestLocation() 方法开始地理位置定位        switch(requestCode){            case 1:                if (grantResults.length>0){                    for (int result:grantResults){                        if (result !=PackageManager.PERMISSION_GRANTED){                            Toast.makeText(this,"必须同意所有权限才能使用本程序",Toast.LENGTH_SHORT).show();                            finish();                            return;                        }                    }                    requestLocation();                }else{                    Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show();                    finish();                }                break;            default:        }    }    //在活动被销毁的时候一定要调用LocationClient 的stop() 方法来停止定位,    //不然程序会持续在后台不停地进行定位,从而严重消耗手机的电量。    @Override    protected void onDestroy(){        super.onDestroy();        mLocationClient.stop();    }}

效果如下图所示

选择定位模式

首先,GPS定位功能必须要由用户主动去启用才行,不然任何应用程序都无法使用GPS获取到手机当前的位置信息。进入手机的设置→位置信息,

可以通过顶部的开关来控制定位功能是开启还是关闭,另外,点击“提高精确度”可以选择具体的定位模式

开启了GPS定位功能之后,可以在initLocation() 方法中对百度LBS SDK的定位模式进行指定,一共有3种模式可选:

Hight_Accuracy Battery_Saving Device_Sensors

Hight_Accuracy表示高精确度模式,会在GPS信号正常的情况下优先使用GPS定位,在无法接收GPS信号的时候使用网络定位。Battery_Saving表示节电模式,只会使用网络进行定位。Device_Sensors表示传感器模式,只会使用GPS进行定位。其中,Hight_Accuracy是默认的模式,也就是说,我们即使不修改任何代码,只要拿着手机走到室外去,让手机可以接收到GPS信号,就会自动切换到GPS定位模式了。

更直观的位置信息

package com.example.lbstest;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;import android.Manifest;import android.content.pm.PackageManager;import android.os.Bundle;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 java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    private TextView positionText;    public LocationClient mLocationClient;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //构建一个LocationClient的实例        mLocationClient=new LocationClient(getApplicationContext());//LocationClient的构建函数接收一个context参数        //调用getApplicationContext() 方法来获取一个全局的Context 参数并传入        //调用registerLocationListener方法来注册一个定位的监听器。当获取到位置信息的时候,就会回调这个定位监听器。        mLocationClient.registerLocationListener(new MyLocationListener());        positionText=(TextView) findViewById(R.id.position_text_view);        //如果没有启动下面权限,就询问用户让用户打开        List<String> permissionList=new ArrayList<>();        //创建一个空的list集合,然后依次判断这3个权限有没有被授权        //如果没被授权就添加到List集合中        //最后将List转换成数组        //采用运行时权限。对于危险权限是需要进行运行时权限处理的        if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED)        {            //由于ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION属于同一个权限组,只需申请一个即可            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);        }        if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED)        {            permissionList.add(Manifest.permission.READ_PHONE_STATE);        }        if (ContextCompat.checkSelfPermission(MainActivity.this,                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);        }        if (!permissionList.isEmpty()) {            String[] permissions = permissionList.toArray(new String[permissionList.size()]);//将List转换成数组            //调用ActivityCompat.requestPermissions() 方法一次性申请            ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);        }        else {            requestLocation();        }    }    //监听线程,获得当前的经纬度,并显示    public class MyLocationListener implements BDLocationListener{        @Override        public void onReceiveLocation(final BDLocation bdLocation) {            runOnUiThread(new Runnable() {//不能在主线程(UI线程)以外操作UI,android中把耗时的操作都放到子线程里面                @Override                public void run() {                    StringBuilder currentPosition = new StringBuilder();//一个可变的字符序列                    currentPosition.append("纬度:").append(bdLocation.getLatitude()).append("\n");                    currentPosition.append("经线:").append(bdLocation.getLongitude()).append("\n");                    //获取地址信息一定需要用到网络                    // 因此即使我们将定位模式指定成了Device_Sensors,也会自动开启网络定位功能。                    currentPosition.append("国家:").append(bdLocation.getCountry()).append("\n");                    currentPosition.append("省:").append(bdLocation.getProvince()).append("\n");                    currentPosition.append("市:").append(bdLocation.getCity()).append("\n");                    currentPosition.append("区:").append(bdLocation.getDistrict()).append("\n");                    currentPosition.append("街道:").append(bdLocation.getStreet()).append("\n");                    currentPosition.append("定位方式:");                    if (bdLocation.getLocType()==BDLocation.TypeGpsLocation){                        currentPosition.append("GPS");                    }else if (bdLocation.getLocType()==BDLocation.TypeNetWorkLocation)                    {                        currentPosition.append("网络");                    }                    positionText.setText(currentPosition);                }            });        }    }    //*初始化函数,并启动位置客户端LocationClient*/    private void requestLocation() {        initLocation();        //默认情况下,调用LocationClient的start() 方法只会定位一次        mLocationClient.start();//调用方法来启动定位。定位的结果会反馈到上面所注册的监听器MyLocationListener中    }    private void initLocation(){        LocationClientOption option = new LocationClientOption();        option.setScanSpan(5000);//调用setScanSpan方法设置更新的间隔(每5秒会更新一下当前的位置)        //调用了setLocationMode() 方法来将定位模式指定成传感器模式,也就是说只能使用GPS进行定位        option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);        option.setIsNeedAddress(true);//表示我们需要获取当前位置详细的地址信息。        mLocationClient.setLocOption(option);    }    //只有同意打开相关权限才可以开启本程序    @Override    public void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults){        //通过一个循环将申请的每个权限都进行了判断,如果有任何一个权限被拒绝        // 那么就直接调用finish() 方法关闭当前程序,        // 只有当所有权限都被用户同意了,才会调用requestLocation() 方法开始地理位置定位        switch(requestCode){            case 1:                if (grantResults.length>0){                    for (int result:grantResults){                        if (result !=PackageManager.PERMISSION_GRANTED){                            Toast.makeText(this,"必须同意所有权限才能使用本程序",Toast.LENGTH_SHORT).show();                            finish();                            return;                        }                    }                    requestLocation();                }else{                    Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show();                    finish();                }                break;            default:        }    }    //在活动被销毁的时候一定要调用LocationClient 的stop() 方法来停止定位,    //不然程序会持续在后台不停地进行定位,从而严重消耗手机的电量。    @Override    protected void onDestroy(){        super.onDestroy();        mLocationClient.stop();    }}

使用百度地图

让地图显示出来

先修改activity_main.xml中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:andro    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <TextView        android:        android:layout_width="wrap_content"        android:layout_height="wrap_content"        />    <com.baidu.mapapi.map.MapView        android:        android:layout_width="match_parent"        android:layout_height="match_parent"        android:clickable="true"/></LinearLayout>

这里在布局文件中新放置了一个MapView控件,并让它填充满整个屏幕。这个MapView是由百度提供的自定义控件,所以在使用它的时候需要将完整的包名加上。同时,如果不需要前面的textView的信息,可以增加下面语句将其去掉

android:visibility="gone"

接下来修改MainActivity中的代码,如下所示:

package com.example.lbstest;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;import android.Manifest;import android.content.pm.PackageManager;import android.os.Bundle;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.mapapi.SDKInitializer;import com.baidu.mapapi.map.MapView;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {private TextView positionText;public LocationClient mLocationClient;private MapView mapView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SDKInitializer.initialize(getApplicationContext());//先通过initialize方法来进行初始化操作//initialize() 方法接收一个Context 参数// 这里我们调用getApplicationContext() 方法来获取一个全局的Context 参数并传入//注意初始化操作一定要在setContentView() 方法前调用,不然的话就会出错setContentView(R.layout.activity_main);//构建一个LocationClient的实例mLocationClient=new LocationClient(getApplicationContext());//LocationClient的构建函数接收一个context参数//调用getApplicationContext() 方法来获取一个全局的Context 参数并传入//调用registerLocationListener方法来注册一个定位的监听器。当获取到位置信息的时候,就会回调这个定位监听器。mLocationClient.registerLocationListener(new MyLocationListener());positionText=(TextView) findViewById(R.id.position_text_view);mapView=(MapView) findViewById(R.id.bmapView);//找到MapView实例//如果没有启动下面权限,就询问用户让用户打开List<String> permissionList=new ArrayList<>();//创建一个空的list集合,然后依次判断这3个权限有没有被授权//如果没被授权就添加到List集合中//最后将List转换成数组//采用运行时权限。对于危险权限是需要进行运行时权限处理的if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){//由于ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION属于同一个权限组,只需申请一个即可permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);}if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED){permissionList.add(Manifest.permission.READ_PHONE_STATE);}if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);}if (!permissionList.isEmpty()) {String[] permissions = permissionList.toArray(new String[permissionList.size()]);//将List转换成数组//调用ActivityCompat.requestPermissions() 方法一次性申请ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);}else {requestLocation();}}//监听线程,获得当前的经纬度,并显示public class MyLocationListener implements BDLocationListener{@Overridepublic void onReceiveLocation(final BDLocation bdLocation) {runOnUiThread(new Runnable() {//不能在主线程(UI线程)以外操作UI,android中把耗时的操作都放到子线程里面@Overridepublic void run() {StringBuilder currentPosition = new StringBuilder();//一个可变的字符序列currentPosition.append("纬度:").append(bdLocation.getLatitude()).append("\n");currentPosition.append("经线:").append(bdLocation.getLongitude()).append("\n");//获取地址信息一定需要用到网络// 因此即使我们将定位模式指定成了Device_Sensors,也会自动开启网络定位功能。currentPosition.append("国家:").append(bdLocation.getCountry()).append("\n");currentPosition.append("省:").append(bdLocation.getProvince()).append("\n");currentPosition.append("市:").append(bdLocation.getCity()).append("\n");currentPosition.append("区:").append(bdLocation.getDistrict()).append("\n");currentPosition.append("街道:").append(bdLocation.getStreet()).append("\n");currentPosition.append("定位方式:");if (bdLocation.getLocType()==BDLocation.TypeGpsLocation){currentPosition.append("GPS");}else if (bdLocation.getLocType()==BDLocation.TypeNetWorkLocation){currentPosition.append("网络");}positionText.setText(currentPosition);}});}}//*初始化函数,并启动位置客户端LocationClient*/private void requestLocation() {initLocation();//默认情况下,调用LocationClient的start() 方法只会定位一次mLocationClient.start();//调用方法来启动定位。定位的结果会反馈到上面所注册的监听器MyLocationListener中}private void initLocation(){LocationClientOption option = new LocationClientOption();option.setScanSpan(5000);//调用setScanSpan方法设置更新的间隔(每5秒会更新一下当前的位置)//调用了setLocationMode() 方法来将定位模式指定成传感器模式,也就是说只能使用GPS进行定位option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);option.setIsNeedAddress(true);//表示我们需要获取当前位置详细的地址信息。mLocationClient.setLocOption(option);}//只有同意打开相关权限才可以开启本程序@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults){//通过一个循环将申请的每个权限都进行了判断,如果有任何一个权限被拒绝// 那么就直接调用finish() 方法关闭当前程序,// 只有当所有权限都被用户同意了,才会调用requestLocation() 方法开始地理位置定位switch(requestCode){case 1:if (grantResults.length>0){for (int result:grantResults){if (result !=PackageManager.PERMISSION_GRANTED){Toast.makeText(this,"必须同意所有权限才能使用本程序",Toast.LENGTH_SHORT).show();finish();return;}}requestLocation();}else{Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show();finish();}break;default:}}//这个方法在活动准备好和用户进行交互的时候调用。// 此时的活动一定位于返回栈的栈顶,并且处于运行状态。@Overrideprotected void onResume(){super.onResume();mapView.onResume();}//这个方法在系统准备去启动或者恢复另一个活动的时候调用。// 通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,// 但这个方法的执行速度一定要快,不然会影响到新的栈顶活动的使用。@Overrideprotected void onPause(){super.onPause();mapView.onPause();}//在活动被销毁的时候一定要调用LocationClient 的stop() 方法来停止定位,//不然程序会持续在后台不停地进行定位,从而严重消耗手机的电量。@Overrideprotected void onDestroy(){super.onDestroy();mLocationClient.stop();mapView.onDestroy();}}

地图是成功显示出来了,但也许这并不是你想要的。因为这是一张默认的地图,显示的是北京市中心的位置,而你可能希望看到更加精细的地图信息,比如说自己所在位置的周边环境。显然,通过缩放和移动的方式来慢慢找到自己的位置是一种很愚蠢的做法。那么本小节我们就来学习一下,如何才能在地图中快速移动到自己的位置。

百度LBS SDK的API中提供了一个BaiduMap 类,它是地图的总控制器,调用MapView的getMap()方法就能获取到BaiduMap 的实例,如下所示:

BaiduMap baiduMap = mapView.getMap();

有了BaiduMap后,我们就能对地图进行各种各样的操作了,比如设置地图的缩放级别以及将地图移动到某一个经纬度上。

百度地图将缩放级别的取值范围限定在3到19之间,其中小数点位的值也是可以取的,值越大,地图显示的信息就越精细。比如我们想要将缩放级别设置成12.5,就可以这样写:

MapStatusUpdate update = MapStatusUpdateFactory.zoomTo(12.5f);baiduMap.animateMapStatus(update);

其中MapStatusUpdateFactory的zoomTo() 方法接收一个float 型的参数,就是用于设置缩放级别的,这里传入12.5f。zoomTo() 方法返回一个MapStatusUpdate 对象,我们把这个对象传入BaiduMap的animateMapStatus() 方法当中即可完成缩放功能。

那么怎样才能让地图移动到某一个经纬度上呢?这就需要借助LatLng 类了。其实LatLng并没有什么太多的用法,主要就是用于存放经纬度值的,它的构造方法接收两个参数,第一个参数是纬度值,第二个参数是经度值。之后调用MapStatusUpdateFactory的newLatLng() 方法将LatLng 对象传入,newLatLng() 方法返回的也是一个MapStatusUpdate 对象,我们再把这个对象传入BaiduMap的animateMapStatus() 方法当中,就可以将地图移动到指定的经纬度上了,写法如下:

LatLng ll = new LatLng(39.915, 116.404);MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);baiduMap.animateMapStatus(update);

上述代码就实现了将地图移动到北纬39.915度、东经116.404度这个位置的功能。

代码如下

package com.example.lbstest;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;import android.Manifest;import android.content.pm.PackageManager;import android.os.Bundle;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.mapapi.SDKInitializer;import com.baidu.mapapi.map.BaiduMap;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MapView;import com.baidu.mapapi.model.LatLng;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {private TextView positionText;public LocationClient mLocationClient;private MapView mapView;private BaiduMap baiduMap;private boolean isFirstLocate=true;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SDKInitializer.initialize(getApplicationContext());//先通过initialize方法来进行初始化操作//initialize() 方法接收一个Context 参数// 这里我们调用getApplicationContext() 方法来获取一个全局的Context 参数并传入//注意初始化操作一定要在setContentView() 方法前调用,不然的话就会出错setContentView(R.layout.activity_main);//构建一个LocationClient的实例mLocationClient=new LocationClient(getApplicationContext());//LocationClient的构建函数接收一个context参数//调用getApplicationContext() 方法来获取一个全局的Context 参数并传入//调用registerLocationListener方法来注册一个定位的监听器。当获取到位置信息的时候,就会回调这个定位监听器。mLocationClient.registerLocationListener(new MyLocationListener());positionText=(TextView) findViewById(R.id.position_text_view);mapView=(MapView) findViewById(R.id.bmapView);//找到MapView实例//百度LBS SDK的API中提供了一个BaiduMap 类,它是地图的总控制器,// 调用MapView的getMap()方法就能获取到BaiduMap 的实例baiduMap = mapView.getMap();//***************权限********************//如果没有启动下面权限,就询问用户让用户打开List<String> permissionList=new ArrayList<>();//创建一个空的list集合,然后依次判断这3个权限有没有被授权//如果没被授权就添加到List集合中//最后将List转换成数组//采用运行时权限。对于危险权限是需要进行运行时权限处理的if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){//由于ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION属于同一个权限组,只需申请一个即可permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);}if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED){permissionList.add(Manifest.permission.READ_PHONE_STATE);}if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);}if (!permissionList.isEmpty()) {String[] permissions = permissionList.toArray(new String[permissionList.size()]);//将List转换成数组//调用ActivityCompat.requestPermissions() 方法一次性申请ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);}else {requestLocation();}}//监听线程,获得当前的经纬度,并显示public class MyLocationListener implements BDLocationListener{@Overridepublic void onReceiveLocation(final BDLocation bdLocation) {if(bdLocation.getLocType()==BDLocation.TypeNetWorkLocation||bdLocation.getLocType()==BDLocation.TypeGpsLocation){navigateTo(bdLocation);}runOnUiThread(new Runnable() {//不能在主线程(UI线程)以外操作UI,android中把耗时的操作都放到子线程里面@Overridepublic void run() {StringBuilder currentPosition = new StringBuilder();//一个可变的字符序列currentPosition.append("纬度:").append(bdLocation.getLatitude()).append("\n");currentPosition.append("经线:").append(bdLocation.getLongitude()).append("\n");//获取地址信息一定需要用到网络// 因此即使我们将定位模式指定成了Device_Sensors,也会自动开启网络定位功能。currentPosition.append("国家:").append(bdLocation.getCountry()).append("\n");currentPosition.append("省:").append(bdLocation.getProvince()).append("\n");currentPosition.append("市:").append(bdLocation.getCity()).append("\n");currentPosition.append("区:").append(bdLocation.getDistrict()).append("\n");currentPosition.append("街道:").append(bdLocation.getStreet()).append("\n");currentPosition.append("定位方式:");if (bdLocation.getLocType()==BDLocation.TypeGpsLocation){currentPosition.append("GPS");}else if (bdLocation.getLocType()==BDLocation.TypeNetWorkLocation){currentPosition.append("网络");}positionText.setText(currentPosition);}});}}private void navigateTo(BDLocation location){//先是将BDLocation 对象中的地理位置信息取出并封装到LatLng 对象中if(isFirstLocate){//************将地图调到当前位置**********LatLng ll=new LatLng(location.getLatitude(),location.getLongitude());//用于存放经纬度//调用MapStatusUpdateFactory的newLatLng() 方法将LatLng 对象传入,// newLatLng() 方法返回的也是一个MapStatusUpdate 对象MapStatusUpdate update= MapStatusUpdateFactory.newLatLng(ll);// 再把这个对象传入BaiduMap的animateMapStatus() 方法当中,就可以将地图移动到指定的经纬度上了baiduMap.animateMapStatus(update);//**************将地图缩放*******//MapStatusUpdateFactory的zoomTo() 方法接收一个float 型的参数,就是用于设置缩放级别的update=MapStatusUpdateFactory.zoomTo(19f);//zoomTo() 方法返回一个MapStatusUpdate 对象,我们把这个对象传入BaiduMap的animateMapStatus() 方法当中即可完成缩放功能。baiduMap.animateMapStatus(update);isFirstLocate=false;//只有首次需要做初始化设置}}//*初始化函数,并启动位置客户端LocationClient*/private void requestLocation() {initLocation();//默认情况下,调用LocationClient的start() 方法只会定位一次mLocationClient.start();//调用方法来启动定位。定位的结果会反馈到上面所注册的监听器MyLocationListener中}private void initLocation(){LocationClientOption option = new LocationClientOption();option.setScanSpan(5000);//调用setScanSpan方法设置更新的间隔(每5秒会更新一下当前的位置)//调用了setLocationMode() 方法来将定位模式指定成传感器模式,也就是说只能使用GPS进行定位option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);option.setIsNeedAddress(true);//表示我们需要获取当前位置详细的地址信息。mLocationClient.setLocOption(option);}//只有同意打开相关权限才可以开启本程序@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults){//通过一个循环将申请的每个权限都进行了判断,如果有任何一个权限被拒绝// 那么就直接调用finish() 方法关闭当前程序,// 只有当所有权限都被用户同意了,才会调用requestLocation() 方法开始地理位置定位switch(requestCode){case 1:if (grantResults.length>0){for (int result:grantResults){if (result !=PackageManager.PERMISSION_GRANTED){Toast.makeText(this,"必须同意所有权限才能使用本程序",Toast.LENGTH_SHORT).show();finish();return;}}requestLocation();}else{Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show();finish();}break;default:}}//这个方法在活动准备好和用户进行交互的时候调用。// 此时的活动一定位于返回栈的栈顶,并且处于运行状态。@Overrideprotected void onResume(){super.onResume();mapView.onResume();}//这个方法在系统准备去启动或者恢复另一个活动的时候调用。// 通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,// 但这个方法的执行速度一定要快,不然会影响到新的栈顶活动的使用。@Overrideprotected void onPause(){super.onPause();mapView.onPause();}//在活动被销毁的时候一定要调用LocationClient 的stop() 方法来停止定位,//不然程序会持续在后台不停地进行定位,从而严重消耗手机的电量。@Overrideprotected void onDestroy(){super.onDestroy();mLocationClient.stop();mapView.onDestroy();}}

结果如下图所示

让“我”显示在地图上

现在我们已经可以让地图显示我们周边的环境了,但是相信在你平时使用手机地图时应该会注意到,通常情况下手机地图上应该都会有一个小光标,用于显示设备当前所在的位置,并且如果设备正在移动的话,那么这个光标也会跟着一起移动。那么我们现在就继续对现有代码进行扩展,让“我”能够显示在地图上。

百度LBS SDK当中提供了一个MyLocationData.Builder 类,这个类是用来封装设备当前所在位置的,我们只需将经纬度信息传入到这个类的相应方法当中就可以了,如下所示:

MyLocationData.Builder locationBuilder = new MyLocationData.Builder();locationBuilder.latitude(39.915);locationBuilder.longitude(116.404);

MyLocationData.Builder 类还提供了一个build() 方法,当我们把要封装的信息都设置完成之后,只需要调用它的build() 方法,就会生成一个MyLocationData的实例,然后再将这个实例传入到BaiduMap的setMyLocationData() 方法当中,就可以让设备当前的位置显示在地图上了,写法如下:

MyLocationData locationData = locationBuilder.build();baiduMap.setMyLocationData(locationData);

修改MainActivity中的代码,如下所示:

package com.example.lbstest;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;import android.Manifest;import android.content.pm.PackageManager;import android.os.Bundle;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.mapapi.SDKInitializer;import com.baidu.mapapi.map.BaiduMap;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MapView;import com.baidu.mapapi.map.MyLocationData;import com.baidu.mapapi.model.LatLng;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {private TextView positionText;public LocationClient mLocationClient;private MapView mapView;private BaiduMap baiduMap;private boolean isFirstLocate=true;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SDKInitializer.initialize(getApplicationContext());//先通过initialize方法来进行初始化操作//initialize() 方法接收一个Context 参数// 这里我们调用getApplicationContext() 方法来获取一个全局的Context 参数并传入//注意初始化操作一定要在setContentView() 方法前调用,不然的话就会出错setContentView(R.layout.activity_main);//构建一个LocationClient的实例mLocationClient=new LocationClient(getApplicationContext());//LocationClient的构建函数接收一个context参数//调用getApplicationContext() 方法来获取一个全局的Context 参数并传入//调用registerLocationListener方法来注册一个定位的监听器。当获取到位置信息的时候,就会回调这个定位监听器。mLocationClient.registerLocationListener(new MyLocationListener());positionText=(TextView) findViewById(R.id.position_text_view);mapView=(MapView) findViewById(R.id.bmapView);//找到MapView实例//百度LBS SDK的API中提供了一个BaiduMap 类,它是地图的总控制器,// 调用MapView的getMap()方法就能获取到BaiduMap 的实例baiduMap = mapView.getMap();//如果要在地图上显示自己的位置,需要先调用下面方法来开启这个功能baiduMap.setMyLocationEnabled(true);//***************权限********************//如果没有启动下面权限,就询问用户让用户打开List<String> permissionList=new ArrayList<>();//创建一个空的list集合,然后依次判断这3个权限有没有被授权//如果没被授权就添加到List集合中//最后将List转换成数组//采用运行时权限。对于危险权限是需要进行运行时权限处理的if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){//由于ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION属于同一个权限组,只需申请一个即可permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);}if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED){permissionList.add(Manifest.permission.READ_PHONE_STATE);}if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);}if (!permissionList.isEmpty()) {String[] permissions = permissionList.toArray(new String[permissionList.size()]);//将List转换成数组//调用ActivityCompat.requestPermissions() 方法一次性申请ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);}else {requestLocation();}}//监听线程,获得当前的经纬度,并显示public class MyLocationListener implements BDLocationListener{@Overridepublic void onReceiveLocation(final BDLocation bdLocation) {if(bdLocation.getLocType()==BDLocation.TypeNetWorkLocation||bdLocation.getLocType()==BDLocation.TypeGpsLocation){navigateTo(bdLocation);}runOnUiThread(new Runnable() {//不能在主线程(UI线程)以外操作UI,android中把耗时的操作都放到子线程里面@Overridepublic void run() {StringBuilder currentPosition = new StringBuilder();//一个可变的字符序列currentPosition.append("纬度:").append(bdLocation.getLatitude()).append("\n");currentPosition.append("经线:").append(bdLocation.getLongitude()).append("\n");//获取地址信息一定需要用到网络// 因此即使我们将定位模式指定成了Device_Sensors,也会自动开启网络定位功能。currentPosition.append("国家:").append(bdLocation.getCountry()).append("\n");currentPosition.append("省:").append(bdLocation.getProvince()).append("\n");currentPosition.append("市:").append(bdLocation.getCity()).append("\n");currentPosition.append("区:").append(bdLocation.getDistrict()).append("\n");currentPosition.append("街道:").append(bdLocation.getStreet()).append("\n");currentPosition.append("定位方式:");if (bdLocation.getLocType()==BDLocation.TypeGpsLocation){currentPosition.append("GPS");}else if (bdLocation.getLocType()==BDLocation.TypeNetWorkLocation){currentPosition.append("网络");}positionText.setText(currentPosition);}});}}private void navigateTo(BDLocation location){//先是将BDLocation 对象中的地理位置信息取出并封装到LatLng 对象中if(isFirstLocate){//************将地图调到当前位置**********LatLng ll=new LatLng(location.getLatitude(),location.getLongitude());//用于存放经纬度//调用MapStatusUpdateFactory的newLatLng() 方法将LatLng 对象传入,// newLatLng() 方法返回的也是一个MapStatusUpdate 对象MapStatusUpdate update= MapStatusUpdateFactory.newLatLng(ll);// 再把这个对象传入BaiduMap的animateMapStatus() 方法当中,就可以将地图移动到指定的经纬度上了baiduMap.animateMapStatus(update);//**************将地图缩放*******//MapStatusUpdateFactory的zoomTo() 方法接收一个float 型的参数,就是用于设置缩放级别的update=MapStatusUpdateFactory.zoomTo(19f);//zoomTo() 方法返回一个MapStatusUpdate 对象,我们把这个对象传入BaiduMap的animateMapStatus() 方法当中即可完成缩放功能。baiduMap.animateMapStatus(update);isFirstLocate=false;//只有首次需要做初始化设置}//***********将自己当前的位置显示出来**********//MyLocationData.Builder 类,这个类是用来封装设备当前所在位置的,只需将经纬度信息传入到这个类的相应方法当中就可以了MyLocationData.Builder locationBuilder=new MyLocationData.Builder();locationBuilder.latitude(location.getLatitude());locationBuilder.longitude(location.getLongitude());//调用MyLocationData.Builder 类所提供的build() 方法,// 就会生成一个MyLocationData的实例MyLocationData locationData=locationBuilder.build();//再将这个实例传入到BaiduMap的setMyLocationData() 方法当中,就可以让设备当前的位置显示在地图上了baiduMap.setMyLocationData(locationData);}//*初始化函数,并启动位置客户端LocationClient*/private void requestLocation() {initLocation();//默认情况下,调用LocationClient的start() 方法只会定位一次mLocationClient.start();//调用方法来启动定位。定位的结果会反馈到上面所注册的监听器MyLocationListener中}private void initLocation(){LocationClientOption option = new LocationClientOption();option.setScanSpan(5000);//调用setScanSpan方法设置更新的间隔(每5秒会更新一下当前的位置)//调用了setLocationMode() 方法来将定位模式指定成传感器模式,也就是说只能使用GPS进行定位option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);option.setIsNeedAddress(true);//表示我们需要获取当前位置详细的地址信息。mLocationClient.setLocOption(option);}//只有同意打开相关权限才可以开启本程序@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults){//通过一个循环将申请的每个权限都进行了判断,如果有任何一个权限被拒绝// 那么就直接调用finish() 方法关闭当前程序,// 只有当所有权限都被用户同意了,才会调用requestLocation() 方法开始地理位置定位switch(requestCode){case 1:if (grantResults.length>0){for (int result:grantResults){if (result !=PackageManager.PERMISSION_GRANTED){Toast.makeText(this,"必须同意所有权限才能使用本程序",Toast.LENGTH_SHORT).show();finish();return;}}requestLocation();}else{Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show();finish();}break;default:}}//这个方法在活动准备好和用户进行交互的时候调用。// 此时的活动一定位于返回栈的栈顶,并且处于运行状态。@Overrideprotected void onResume(){super.onResume();mapView.onResume();}//这个方法在系统准备去启动或者恢复另一个活动的时候调用。// 通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,// 但这个方法的执行速度一定要快,不然会影响到新的栈顶活动的使用。@Overrideprotected void onPause(){super.onPause();mapView.onPause();}//在活动被销毁的时候一定要调用LocationClient 的stop() 方法来停止定位,//不然程序会持续在后台不停地进行定位,从而严重消耗手机的电量。@Overrideprotected void onDestroy(){super.onDestroy();mLocationClient.stop();mapView.onDestroy();baiduMap.setMyLocationEnabled(false);//程序退出时,关闭在地图上显示自己位置的功能}}

其他的开发指南可以参考:http://lbsyun.baidu.com/

参考资料

https://blog.csdn.net/kezhongke/article/details/42678077(sha1证书指纹数据)

https://blog.csdn.net/yeluoweiluo615/article/details/54020678(sha1证书指纹数据)

https://blog.csdn.net/Hanghang_/article/details/87207093?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%AE%89%E5%8D%93%E7%AC%AC%E4%B8%80%E8%A1%8C%E4%BB%A3%E7%A0%81%20%E4%BD%BF%E7%94%A8%E7%99%BE%E5%BA%A6%E5%AE%9A%E4%BD%8D&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-87207093

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477