AndroidAndroid开发首页推荐

11特色开发-百度地图

2018-04-03  本文已影响120人  何惧l

申请API Key

  1. 打开这个连接 http://lbsyun.baidu.com/apiconsole/key,申请百度地图开发者平台服务,点击我同意,创建应用
    创建应用界面.png
  2. 这个发布版SHA1和开发板SHA1是什么意思呢?这个是打包程序时所用签名文件的SHA1指纹,通过ANdroid Studio可以查看到,打开任何一个项目点击右边工具栏的Gradle-->项目名-->:app-->Tasks-->android


    内置的Tasks.png
  3. 双击这个signingReport文件


    signingReport.png
    • 其中的F2:F8:68:53:5F:1C:D9:1E:68:6A:14:4B:24:91:DD:37:95:58:A1:9B就是需要的SHA1指纹了,要注意的是现在使用的是debug.keystore文件生成的指纹,这是Android自动生成用于测试的签名文件,当应用程序发布时还要创建一个正式的签名文件,
    • 在定义的项目中(com.example.lbstest)
      创建数字签名.png
      新创建一个.png
      创建.png
      记住这个密码,这就创建成功了
      要得到它的指纹,就在cmd中输入以下命令
      keytool -list -v -keystore <签名文件路径>
      获取到签名.png
  4. 现在得到的SHA1指纹实际上是一个开发版的SHA1指纹,不过现在没有发布版的SHA1,这两个值填写一样就可以了,最后还有一个包名,就是上一步中的包名


    查看已创建的应用.png
    • 其中的AK就是申请到的API Key,有了它就可以进行后续的LBS开发工作了

使用百度定位

项目就是lsbtest,包名是com.example.lbstest,就是上面定义的那个

  1. 准备LBS SDKhttp://lbsyun.baidu.com/index.php?title=sdk/download&action#selected=location_all
    • 将百度LBS开发平台上的SDK下载下来,点击开发包


      下载SDK界面.png
  2. 下载后解压,其中有一个libs目录,这里面的内容就是我们需要的


    压缩包libs目录下的文件.png
    • BaiduLBS_Android.jar这个文件是java层要使用的,其他子目录下的so文件是Native层要用的,
    • so文件是C/C++语言写的,因为百度都封装好了,直接使用就可以了
  3. 首先看一下当前项目目录,
    • 其中app模块下的libs目录就是用来存放Jar包的,把BaiduLBS_Android.jar复制到这里


      把jar包复制到这里.png
    • 接下来右击src/main目录,进行目录jniLibs目录,把压缩包里的所有目录直接复制到这里


      把so文件放置到jniLibs目录中.png
  4. 这个时候在配置文件中build.gradle中,会默认有这一行代码
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ...
}

确定自己的位置的经纬度

  1. 修改activity_main.xml中的代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <TextView
        android:id="@+id/position_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"/>
</LinearLayout>
  1. 修改AndroidManifest.xml文件中的代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.lbstest">

    <!-- 这个权限用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
    <!-- 这个权限用于访问GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <!-- 用于读取手机当前的状态-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <!-- 访问网络,网络定位需要上网-->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- SD卡读取权限,用户写入离线定位数据-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>

    <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">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>


        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="PG73Gkx1BxSahdcdHDuM57tmCB5UPcn4" >
        </meta-data>

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

    </application>

</manifest>

  1. 修改MainActivity中的代码
package com.example.lbstest;

public class MainActivity extends AppCompatActivity {

    // 声明这个对象,该对象初始化需传入Context类型参数。推荐使用getApplicationConext()方法获取全进程有效的Context。
    public LocationClient mLocationClient;
    private MyLocationListener myListener = new MyLocationListener();
    private TextView positionText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 进行初始化
        mLocationClient = new LocationClient(getApplicationContext());
        // 注册监听函数
        mLocationClient.registerLocationListener(myListener);
        setContentView(R.layout.activity_main);
        // 获取到控件
        positionText = (TextView)findViewById(R.id.position_text_view);
        // 关于权限的操作
        List<String> permissionList = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
            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()]);
            ActivityCompat.requestPermissions(MainActivity.this,permissions,1);
        }else {
            requestLocation();
        }

    }


    //调用LocationClient的start()方法,便可发起定位请求
    public void requestLocation(){
        mLocationClient.start();
    }

    // 动态添加权限
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        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:
        }
    }


    // 监听函数
    public class MyLocationListener implements BDLocationListener{
        //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            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);
        }
    }

}

  1. 运行程序,运行权限就可以看到


    地理位置定位.png
  2. 不过,在默认的情况下,LocationClient的start()方法只会定位一次,但是如果我们此时移·动的话,怎么样才能更新位置呢?这个时候就得修改MainActivity中的代码了
...


  //调用LocationClient的start()方法,便可发起定位请求
    public void requestLocation(){
        initLocation();
        mLocationClient.start();
    }

    // 创建一个LocationClientOption对象,调用方法来设置跟新的间隔
    private void initLocation(){
        LocationClientOption option = new LocationClientOption();
        option.setScanSpan(5000);
        mLocationClient.setLocOption(option);
    }

    // 活动被销毁的时候要调用stop()方法来停止定位
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.stop();
    }

    ...

选择定位模式

上面是使用网络定位的方式,这次使用精准度高的GPS定位

  1. 首先GPS定位功能要由用户主动的启动才行,进入设置-->位置信息


    选择定位模式.png
  2. 开启GPS定位功能后,可以在initLocation()方法中对百度LBS SDK的定位模式指定,Hinght_Accuracy、Battery_Saving和Device_Sensors,其中Hinght_Accuracy模式标识高精确度,在GPS信号正常的情况下优先使用,在无法使用GPS信号的时候就使用网络定位,Battery_Saving表示节点模式,只会使用网络进行定位,Device_Sensors表示传感模式,只会使用GPS定位,其中的Hinght_Accuracy是默认的定位,不需要修改任何代码,把手机拿到室外就可以了,这个时候手机就会自动切换到GPS定位模式了
  3. 当然了也可以强制指定为GPS定位,修改MainActivity中的代码
    private void initLocation(){
        LocationClientOption option = new LocationClientOption();
        option.setScanSpan(5000);
        // 强制使用GPS定位的模式
        option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);
        mLocationClient.setLocOption(option);
    }

看得懂的位置信息

当然了,获取经度和纬度对于小白来说也是看不懂的,这个时候就得获取直观的位置信息,

  1. 当然了,这些百度LBS SDK都支持,只需要进行一些简单的接口调用就可以了,修改MainActiviyt中的代码
package com.example.lbstest;


public class MainActivity extends AppCompatActivity {

    ...
    
    private void initLocation(){
        LocationClientOption option = new LocationClientOption();
        option.setScanSpan(5000);
        // 开启详细信息
        option.setIsNeedAddress(true);
        mLocationClient.setLocOption(option);
    }

    // 监听函数
    public class MyLocationListener implements BDLocationListener{
        //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            StringBuilder currentPosition = new StringBuilder();
            currentPosition.append("纬度:").append(bdLocation.getLatitude()).append("\n");
            currentPosition.append("经度:").append(bdLocation.getLongitude()).append("\n");
            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);
        }
    }

}

让地图显示出来

  1. 直接在上一个的基础上进行修改,在activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <TextView
        android:id="@+id/position_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:visibility="gone"
        />

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        />
    
</LinearLayout>
  1. 接下来修改MainActivity中的代码
package com.example.lbstest;


public class MainActivity extends AppCompatActivity {

    // 声明这个对象,该对象初始化需传入Context类型参数。推荐使用getApplicationConext()方法获取全进程有效的Context。
    public LocationClient mLocationClient;
    private MyLocationListener myListener = new MyLocationListener();
    private TextView positionText;

    // 
    private MapView mapView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 进行初始化
        mLocationClient = new LocationClient(getApplicationContext());
        // 注册监听函数
        mLocationClient.registerLocationListener(myListener);
        
        // 调用这个方法来进行初始化
        SDKInitializer.initialize(getApplicationContext());
        
        setContentView(R.layout.activity_main);

        // 获取到这个控件
        mapView = (MapView)findViewById(R.id.bmapView);
        ...

    }

    ...

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onResume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.stop();
        mapView.onDestroy();
    }
    ...
}

移动到我的位置

显示是显示出来的,但是出来的是默认的北京市的,怎么才能定位到自己的呢?

  1. 百度LBS SDK的API中提供了一个BaiduMap类,它是地图的总控制器,调用MapView的getMap()方法就可以获取到BaiduMap的实例
    BaiduMap baiduMap = mapView.getMap()
  2. 获取到这个以后,就可以对地图进行各种操作了,比如设置地图的缩放级别以及将地图以哦对那个到某个经纬度上
    • 地图的缩放级别在3到19之间,越大就越精细,也可以是小数点,比如设置为12.5就可以写成
    MapStatusUpdate update = MapStatusUpdateFactory.zoomTo(12.5f);
    baiduMap.animateMapStatus(update);
  1. 怎么将地图移动到某一个经纬度上呢,这个时候就要借助LatLng类,这个类就是用于存放经纬度的,它的构造方法接收两个参数,第一个是纬度值,第二个是经度值,之后调用MapStatusUpdateFactory的newLatLng()方法将这个LatLng对象传入,这个newLatLng()方法也是返回一个MapStatusUpdate对象,把这个对象传入到BaiduMap的animateMapStatus()方法中,就可以将地图移动到指定的经纬度上了
LatLng ll = new LatLng(111,222);
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
baiduMa.animateMapStatus(update);

  1. 继续在这个项目上修改,
package com.example.lbstest;

public class MainActivity extends AppCompatActivity {

    ...

    private BaiduMap baiduMap;
    private boolean isFirstLocate = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 进行初始化
        mLocationClient = new LocationClient(getApplicationContext());
        // 注册监听函数
        mLocationClient.registerLocationListener(myListener);

        SDKInitializer.initialize(getApplicationContext());

        setContentView(R.layout.activity_main);
        mapView = (MapView)findViewById(R.id.bmapView);

        // 获取到实例
        baiduMap = mapView.getMap();


    
    private void navigateTo(BDLocation location){
        if (isFirstLocate){
            // 设置位置
            LatLng ll = new LatLng(location.getLatitude(),location.getLongitude());
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
            baiduMap.animateMapStatus(update);
            // 设置缩放级别
            update = MapStatusUpdateFactory.zoomTo(10f);
            baiduMap.animateMapStatus(update);
            isFirstLocate = false;
        }
    }



    // 监听函数
    public class MyLocationListener implements BDLocationListener{
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            
            if (bdLocation.getLocType() == BDLocation.TypeNetWorkLocation ||bdLocation.getLocType() == BDLocation.TypeGpsLocation ){
                navigateTo(bdLocation);
            }
        }
    }
}

}

让我显示在地图上

如果当前的设备正在移动,那么显示我的这个光标就会跟着一起移动

  1. 百度的LBS SDK当中提供了一个MyLocationData.Builder类,这个类就是用来封装设备当前所在的位置,只要将当前位置的经纬度传入进来就可以了
MyLocationData.Builder locationBuilder = new MyLocationData.Builder();
locationBuilder.latitude(50);
locationBuilder.longitude(100);
  1. MyLocationData.Builder类还提供了一个build()方法,当把封装的信息都设置完成后,只需要调用build()方法就可以生成一个MyLocationData的实例,然后把这个实例传入到BaiduMap的setMyLocationData()方法中,就可以了
MyLocationData locationData = locationBuilder.build();
baiduMap.setMyLocationData(locationData);
  1. 具体实现
package com.example.lbstest;

public class MainActivity extends AppCompatActivity {

    ...

    private BaiduMap baiduMap;
    private boolean isFirstLocate = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 进行初始化
        mLocationClient = new LocationClient(getApplicationContext());
        // 注册监听函数
        mLocationClient.registerLocationListener(myListener);

        SDKInitializer.initialize(getApplicationContext());

        setContentView(R.layout.activity_main);
        mapView = (MapView)findViewById(R.id.bmapView);

        // 获取到实例
        baiduMap = mapView.getMap();

         // 开启这个功能
        baiduMap.setMyLocationEnabled(true);

        ...
    
    private void navigateTo(BDLocation location){
        if (isFirstLocate){
            // 设置位置
            LatLng ll = new LatLng(location.getLatitude(),location.getLongitude());
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
            baiduMap.animateMapStatus(update);
            // 设置缩放级别
            update = MapStatusUpdateFactory.zoomTo(10f);
            baiduMap.animateMapStatus(update);
            isFirstLocate = false;
        }
           // 
        MyLocationData.Builder locationBuilder = new MyLocationData.Builder();
        locationBuilder.latitude(location.getLatitude());
        locationBuilder.longitude(location.getLongitude());
        MyLocationData locationData = locationBuilder.build();
        baiduMap.setMyLocationData(locationData);
    }



   @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.stop();
        mapView.onDestroy();
        //
        baiduMap.setMyLocationEnabled(false);
    }
}
}

上一篇 下一篇

猜你喜欢

热点阅读