admin管理员组文章数量:1794759
超详细的Android百度地图开发:在APP上定位并显示出来
超详细的Android百度地图开发:在APP上定位并显示出来
- 一 写在前面
- 二 注册百度开发者账户、申请API KEY
- 三、代码实现
- 四、问题
- 五、总结
由于项目所需,我需要在手机APP中嵌入百度地图。参考的文档是《第一行代码》。其中的功能包括GPS/网络定位、地图的显示、搜索地点并进行导航(这个第一行代码没有,需要自己实现)。今天要实现的功能是,通过GPS/网络来进行定位,并以文本的形式1、将经纬度显示在APP上,2、具体的国省市区街道信。
效果如图所示:
二 注册百度开发者账户、申请API KEY1、注册百度开发者账户:lbsyun.baidu/ 在右上角按下登录,若有账号直接登录,反之注册。 2、进入百度地图Android定位SDK网页:lbsyun.baidu/index.php?title=android-locsdk
点击获取密钥 点击创建应用 如图操作: 其中上图第三步,如下图操作所示,将SHA1复制进入上图的两个SHA1空位。
提交之后,你就发现自己已经有一个应用啦。 3、下载百度地图SDK:lbsyun.baidu/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)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="schemas.android/apk/res/android" package="com.example.lbstest"> <!-- 读写sd卡 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 写sd卡 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_GPS" /> <!-- 获取精确gps位置 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 获取粗略位置 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 允许程序访问额外的定位提供者指令获取模拟定位信 --> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- 网络链接 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 获取网络状态 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 更改wifi连状态 --> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 获取wifi状态 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!--允许程序读写手机状态和身份--> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission> <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="BaiduMobAd_STAT_ID" android:value="48ae76de3f" /> --> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="填写刚申请的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"> </service> </application> </manifest>2、activity_main.xml文件,即UI配置文件 一开始,我们就简单地用文本显示定位的经纬度,所以在UI文件中,我们只配置了一个TextView的控件。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="schemas.android/apk/res/android" xmlns:tools="schemas.android/tools" 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" /> </LinearLayout>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<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*/ 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); } }); } } 四、问题1.错误:从内部类中访问本地变量location;需要被声明为最终类型。 解决方法:加上final 2.Invalid process name remote in package com.example.lbstest: must have at least one 百度了一下INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,发现错误是出现在AndroidManifest.xml里,经检查发现: 红线处少了一个’:'
修改之后: 3.显示地图,但定位总是在北京。
当做完显示地图这个步骤之后,将地图移动到我的位置这一步似乎没有发挥其作用,即总是定位在北京。
检查之后,我觉得是这部分代码可能出现了一些问题。
位置:onReceiveLocation函数
书上这个函数的代码是没有开启线程的,这样的话就不会移动到我的当前位置,所以一直都是北京区域。
所以的话,在此函数增加一条线程代码即可,亲测有效的。^- ^
public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(final BDLocation location) { runOnUiThread(new Runnable() { @Override public void run() { if (location.getLocType() == BDLocation.TypeGpsLocation || location.getLocType() == BDLocation.TypeNetWorkLocation) { navigateTo(location); } } }); } } 五、总结那么这一小节就完成了,效果如开头的手机截图一样。
如果我的文章对你有帮助,欢迎关注,点赞,收藏,有问题可以评论。
版权声明:本文标题:超详细的Android百度地图开发:在APP上定位并显示出来 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1686469896a71054.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论