由于项目所需,我需要在手机APP中嵌入百度地图。参考的文档是《第一行代码》。其中的功能包括GPS/网络定位、地图的显示、搜索地点并进行导航(这个第一行代码没有,需要自己实现)。接下来我会一步一步来实现功能,并把代码都贴在我的github上。今天要实现的功能是,通过GPS/网络来进行定位,并以文本的形式1、将经纬度显示在APP上,2、具体的国省市区街道信息。
1、注册百度开发者账户:http://lbsyun.baidu.com/
在右上角按下登录,若有账号直接登录,反之注册。
2、进入百度地图Android定位SDK网页:http://lbsyun.baidu.com/index.php?title=android-locsdk
点击获取密钥
点击创建应用
如图操作:
其中上图第三步,如下图操作所示,将SHA1复制进入上图的两个SHA1空位。
提交之后,你就发现自己已经有一个应用啦。
3、下载百度地图SDK:http://lbsyun.baidu.com/index.php?title=android-locsdk/geosdk-android-download
点击去下载,网页会提示你需要下载哪些组件,由于我需要定位、地图、检索和导航功能,所以我选择了以下四项,点击开发包下载。
4.新建Android项目
在Android Studio中新建一个名为LBSTest的项目,包名应该会自动被命名为com.example.lbstest。注意本章中的代码最好在手机上运行,因为手机可以得到真实的位置数据,感受会更深刻。
5、将SDK文件放入相关的路径中
下载成功并解压之后,会发现如下文件,点击进入libs。
libs中含有以下文件:
将BaiduLBS_Android.jar文件放在LBSTest文件夹-》app-》libs文件夹下。
将其余文件夹(arm64-v8a、armeabi、armeabi-v7a、x86、x86_64)放在LBSTest-》src-》main-》jniLibs文件夹下。
注意:jniLibs文件夹是原本没有的,需要自己创建。
6、重新构建项目
打开LBSTest项目,点击AS右上角的Sync Project with Gradle Files
现在,百度地图所需的基本配置已经完成啦,接下来让我们修改代码部分。
1、AndroidManifest.xml文件
在这个文件,主要有两个功能:
(1)、声明些所需要用到的权限,比如手机GPS、网络的权限等。(位置:uses-permission)
(2)、将百度地图的API-KEY写进去,下面代码我没有将API-KEY写进去,需要读者自行将自己申请的APIKEY复制输入进去。(位置:meta-data)
(3)、定义百度地图的服务,用于定位。(位置:service)
2、activity_main.xml文件,即UI配置文件
一开始,我们就简单地用文本显示定位的经纬度,所以在UI文件中,我们只配置了一个TextView的控件。
3、MainActivity文件,即主活动文件
这个文件主要写了创建位置客户端,打开相应的权限,以及获取经纬度、字符串拼接并打印在TextView上。
一个需要注意的问题,如果是自己按照书本上敲的代码,出现红色的错误请不要慌。因为要么后面会有函数声明,要么没有import相应的库。后者的解决方法就是同时按下Alt+Enter,系统会自动帮你import相应的库,或者可以直接复制我下面的代码。
package com.example.lbstest;
import android.Manifest;
import android.content.pm.PackageManager;
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.os.Bundle;
import android.util.Log;
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 {
public LocationClient mLocationClient;
//private MapView mapview;
private TextView positionText;
private StringBuilder currentPosition;
public MainActivity() {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLocationClient = new LocationClient((getApplicationContext()));
mLocationClient.registerNotifyLocationListener(new MyLocationListener());
setContentView(R.layout.activity_main);
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();
}
}
/*初始化函数,并启动位置客户端LocationClient*/
private void requestLocation() {
initLocation();
mLocationClient.start();
}
/*初始化函数*/
private void initLocation() {
LocationClientOption option = new LocationClientOption();
option.setScanSpan(5000);
mLocationClient.setLocOption(option);
}
/*只有同意打开相关权限才可以开启本程序*/
@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 {
@Override
public void onReceiveLocation(final BDLocation location) {
runOnUiThread(new Runnable() {
@Override
public void run() {
currentPosition = new StringBuilder();
currentPosition.append("纬度:").append(location.getLatitude()).append("\n");
currentPosition.append("经度:").append(location.getLongitude()).append("\n");
currentPosition.append("定位方式:");
if (location.getLocType() == BDLocation.TypeGpsLocation) {
currentPosition.append("GPS");
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
currentPosition.append("网络");
}
positionText.setText(currentPosition);
}
});
}
}
public void onConnectHotSpotMessage(String s, int i) {
}
@Override
protected void onDestroy(){
super.onDestroy();
mLocationClient.stop();
}
}
4、选择定位方式:
聪明的读者已经注意到了,开头的截图显示的是网络定位,众所周知,网络定位精度在室外不如GPS定位,那我们怎么切换成GPS定位呢?
很简单,只要修改initLoation()函数。如下所示:
private void initLocation() {
LocationClientOption option = new LocationClientOption();
option.setScanSpan(5000);
option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);
mLocationClient.setLocOption(option);
}
重新编译安装,然后走到室外,你会发现已经是GPS定位了。
5、具体位置显示
由于只看经纬度我们无法一下子知道自己的具体位置,所以引入具体位置显示。只需要修改MainActivity.java即可。
修改部分:
(1)、先是调用了setIsNeedAddress传入true,表示我们需要获取当前具体的位置。
private void initLocation() {
LocationClientOption option = new LocationClientOption();
option.setScanSpan(5000);
// option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);
option.setIsNeedAddress(true);
mLocationClient.setLocOption(option);
}
(2)、调用getProvince、getCity等函数获得具体的位置信息。
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(final BDLocation location) {
runOnUiThread(new Runnable() {
@Override
public void run() {
currentPosition = new StringBuilder();
currentPosition.append("纬度:").append(location.getLatitude()).append("\n");
currentPosition.append("经度:").append(location.getLongitude()).append("\n");
currentPosition.append("国家:").append(location.getCountry()).append("\n");
currentPosition.append("省:").append(location.getProvince()).append("\n");
currentPosition.append("市:").append(location.getCity()).append("\n");
currentPosition.append("区:").append(location.getDistrict()).append("\n");
currentPosition.append("街道:").append(location.getStreet()).append("\n");
currentPosition.append("定位方式:");
if (location.getLocType() == BDLocation.TypeGpsLocation) {
currentPosition.append("GPS");
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
currentPosition.append("网络");
}
positionText.setText(currentPosition);
}
});
}
}
那么这一小节就完成了,效果如开头的手机截图一样,接下来的任务会抽空完成。欢迎大家点赞,收藏,有问题可以收藏评论。
下面是我在这个过程中出现的一些小问题,如果遇到了相同的问题可以点进去看看~
Android搭建百度地图出现:错误: 从内部类中访问本地变量location; 需要被声明为最终类型
Android搭建百度地图时出现:Invalid process name remote in package com.example.lbstest: must have at least one:
Android搭建百度地图时出现:程序包com.baidu.mapapi.map不存在