新建一个BaiduMapDemo项目
一直点Next,创建之后,点击右侧工具栏Gradle,发现是空的。
这时候,我们运行一下app。然后刷新一下Gradle projects发现里面有项目了。Gradle→BaiduMapDemo→Tasks→android→signingReport,再点击右下角的Gradle Console,可以查到SHA1指纹。(每个人的SHA1指纹是不一样的)
接下来,我们需要申请一个百度地图API,打开浏览器http://lbsyun.baidu.com或者打开百度搜索”百度地图API”进入官网。进入之后,点击申请密钥。(需要注册账号 )
点击创建应用。输入应用名称BaiduMapDemo,应用类型选择Android SDK,发布版SHA1和开发版SHA1,我们都可以填之前获取的SHA1指纹。
提交创建成功之后,我们就可以看见我们申请到的API Key。光有这个是不够的,我们还需要准备好百度LBS开放平台的SDK。下载地址:http://lbsyun.baidu.com/sdk/download,这里我们需要,基础定位和基础地图两个功能的SDK,点击“开发包”进行下载。
下载完成之后,对该压缩包解压,里面有一个libs目录,这里面的内容分两部分,BaiduLBS_Android.jar这个文件是jar文件,其他的是so文件,因为这些文件都是百度已经封装好了,我们只需要将libs目录下的没一个文件放置在正确的位置。
打开android studio的BaiduMapDemo项目,点击project,可以看见app模块下面有一个libs目录,这里用来存放jar包,我们将刚才下载的BaiduLBS_Android.jar复制到这个文件夹下。然后展开,src/main目录,右击main→New→Directory,创建一个名为jniLibs的文件夹,这里是专门存放so文件的,然后把压缩包里的其他5个文件直接复制到这里。
这里我们直接将jar包复制libs目录下,没有修改gradle文件,所以不会弹出我们平时熟悉的Sync Now提示。因此这时候,我们需要手动点击android studio顶部工具栏的Sync按钮,不然,项目无法引用jar包中提供的接口。 然后我们会发现,libs目录下的BaiduLBS_Android.jar文件多了一个向右的小三角形,这就表示,现在项目可以引用这些jar包了。
现在LBS的SDK都准备好了,就可以开始写代码了。
一:确定自己的位置的经纬度
activity_main.xml代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
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: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>
修改AndroidManifest.xml文件中的代码:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ivan_keung.baidumapdemo">
<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"/>//都是百度地图需要的授权
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="eQG7xRsSCFRxDxgFEL90wI5lzaccs2jf"/>//申请的API Key
<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">//LBS SDK中的服务
service>
application>
manifest>
MainActivity中的代码:
package com.example.ivan_keung.baidumapdemo;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
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 {
public LocationClient mLocationClient;
private TextView positionText;
private MapView mapView;
private BaiduMap baiduMap;
private boolean isFirstLocate=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLocationClient=new LocationClient(getApplicationContext());
mLocationClient.registerLocationListener(new MyLocationListener());
SDKInitializer.initialize(getApplicationContext());//创建一个LocationClient的实例,
// LocationClient的构建函数接收一个Context参数,这里调用getApplicationContext(),方法来获取一个全局的Context参数并传入。
// 然后调用LocationClient的registerLocationListener()方法来注册一个定位监听器,当获取到位置信息的时候,就会回调这个定位监听器。
setContentView(R.layout.activity_main);
mapView= (MapView) findViewById(R.id.bmapView);
baiduMap=mapView.getMap();
baiduMap.setMyLocationEnabled(true);
positionText= (TextView) findViewById(R.id.position_text_view);
List 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();
}
}//ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION、READ_PHONE_STATE、WRITE_EXTERNAL_STORAGE这4个权限是危险权限
// 需要进行运行时权限处理,不过ACCESS_FINE_LOCATION、ACCESS_COARSE_LOCATION属于同一个权限组,两者申请其一就可以了。
// 这里运用了一比较新的用法在运行时一次性申请3个权限。首先创建了一个List集合,然后依次判断这3个权限有没有被授权,
// 如果没有被授权,就添加到List集合中,最后将List转换成数组,在调用ActivityCompat.requestPermissions()方法一次性申请。
private void requestLocation(){
initLocation();
mLocationClient.start();
}
private void navigateTo(BDLocation location){
if(isFirstLocate){
LatLng ll=new LatLng(location.getLatitude(),location.getLongitude());//LatLng类用于存放经纬度
// 第一个参数是纬度值,第二个参数是精度值。这里输入的是本地位置。
MapStatusUpdate update= MapStatusUpdateFactory.newLatLng(ll);//将LatLng对象传入
baiduMap.animateMapStatus(update);
update=MapStatusUpdateFactory.zoomTo(16f);//百度地图缩放范围,限定在3-19之间,可以去小数点位值
// 值越大,地图显示的信息越精细
baiduMap.animateMapStatus(update);
isFirstLocate=false;//防止多次调用animateMapStatus()方法,以为将地图移动到我们当前位置只需在程序
// 第一次定位的时候调用一次就可以了。
}
MyLocationData.Builder locationBuilder=new MyLocationData.Builder();
locationBuilder.latitude(location.getLatitude());
locationBuilder.longitude(location.getLongitude());
MyLocationData locationData=locationBuilder.build();
baiduMap.setMyLocationData(locationData);//获取我们的当地位置
}
private void initLocation() {
LocationClientOption option=new LocationClientOption();
option.setScanSpan(5000);//表示每5秒更新一下当前位置
option.setIsNeedAddress(true);
option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);
// Hight_Accuracy表示高精确度模式,会在GPS信号正常的情况下优先使用GPS定位,在无法接收GPS信号的时候使用网络定位。
// Battery_Saving表示节电模式,只会使用网络进行定位。
// Device_Sensors表示传感器模式,只会使用GPS进行定位。
mLocationClient.setLocOption(option);
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocationClient.stop();//销毁之前,用stop()来停止定位
mapView.onDestroy();
baiduMap.setMyLocationEnabled(false);
}
@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_LONG).show();
finish();
return;
}
}
requestLocation();
}else{
Toast.makeText(this,"发生未知错误",Toast.LENGTH_LONG).show();
finish();
}
break;
default:
}//onRequestPermissionsResult()方法中,对权限申请结果进行逻辑判断。这里使用一个循环对每个权限进行判断,
// 如果有任意一个权限被拒绝了,那么就会直接调用finish()方法关闭程序,只有当所有的权限被用户同意了,才会
// 调用requestPermissions()方法开始地理位置定位。
}
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
if(location.getLocType()==BDLocation.TypeGpsLocation||location.getLocType()==BDLocation.TypeNetWorkLocation){
navigateTo(location);
}
}
}
}
写的应该还算比较详细了,如果有什么疑问,可以留言,我们一起学习,一起进步。