Android如何实现地图定位?Android studio+百度地图API+Android6.0系统实现地图显示、地址设置、点击地图定位功能(详细)
文章说明:本文初衷是为了记录毕设学习过程,避免忘记操作流程。该功能是毕业设计的Android软件端的功能之一,本文将从获取百度地图密钥(AK)开始,详细地对地图定位配置和相关代码进行说明,文末将附上实现该功能的代码。后续等答辩完成会把整个Android端代码上传。
6月27日更新,完整的智能家居APP的源码和相关说明已经发出,感兴趣的同学点开链接看看
使用Android studio完成简易智能家居APP的制作(含源码工程包)
目录
3、下载相关开发包并将文件配置到Android studio的文件中
3、下载相关开发包后,进行Android Studio的配置
1、将获取的百度地图移动版开发密钥AK,配置到Android studio中
2、将下载好的JAR格式百度地图开发包置于libs下,并在build.gradle中增加一条语句,用于展开JAR开发包
3、创建一个jniLibs文件名,在class="lazy" data-src/java/jniLibs这个路径下,添加开发包的其他文件
4、在activity_main.xml的layout文件中,设置相关按钮(就是普通/卫星地图那些玩意的选择)
在进入学习前,老(新)规矩,先看效果图:
2023/4.8 新增功能及其界面如下:
okok,看完效果图,那咱们就开始吧!
1、使用的软硬件说明
软件:百度地图API,使用的外部包是百度地图Android SDK基于Android 4.0及以上版本设备的应用程序接口,Android studio开发软件,360手机助手。
硬件:openA57手机一台,数据线一根
百度地图移动版的开发密钥(AK)是一个API访问授权凭证,用于验证应用程序或网站请求百度地图API时的身份和权限。它是一段由百度地图开发者平台生成的字符串,类似于密码,需要在每次API调用中传递给服务器以获得访问权限。
具体步骤如下:
登录或者注册百度地图开放平台,进入链接获取百度地图开发密钥网址链接
点击创建应用
进入界面后,选择Android SDK,自己创建应用名字
这一步涉及到两个关键的信息源,如何获得这两个信息显得十分的关键,这两个信息分别是包名和SHA1,如图所示,其中发布饭SHA1和包名是必填项,具体如何获取,下面我将详细说明。当然也可以通过官方获取文档的教学进行操作获取。
1)获取包名
这个数据的获取相对简单,如图所示:
2)获取SHA1(重点)
首先说明一下SHA1其实是
SHA1 (Secure Hash Algorithm 1) 是一种加密算法,常用于验证数据的完整性和安全性。在地图开发中,获取SHA1通常是为了使用百度地图服务API进行身份验证和授权。通常需要生成应用程序签名并使用keytool工具来获取SHA1指纹。
那么具体应该如何操作呢?
此处教一个万能的方法,首先打开安装Android studio目录下的jre,此处我安装的路径是C:\Program Files\Android\Android Studio\jre\bin;找到路径后,使用win+R输入cmd命令,进入命令行工具(或者直接右键点击在终端打开)如下图所示:
然后找到你的 debug.keystore所在的目录,如图所示,我的在c盘用户目录的.android一般都在这个“.android”目录下,这个需要自己寻找哈!完成这一步,恭喜你,你已经近乎完成了!!!
还记得我们刚刚打开的cmd命令端吗?打开它然后直接输入下面这串字符和刚刚找到的debug.keystore路径,再之后回车即可:
keytool -list -v -keystore 路径(刚刚寻找的debug.keystore的路径)
需要注意的是,它需要你输入密钥库口令,请输入:android
如图所示,你成功获得了SHA1数据;接下来在创建应用界面输入包名和SHA1的数据即可,让后你就得到了一个应用,具体如下图,应用ak即可得到
3、下载相关开发包并将文件配置到Android studio的文件中
这里呢,就需要我们下载一个Android SDK,这是个什么呢?且看解释!
1、Android SDK专业解释:
Android SDK是指Android软件开发工具包(Software Development Kit),它是一组用于开发Android应用程序的工具和资源集合。Android SDK由Google或其他地图进行提供,可以免费下载和使用。
Android SDK包含了许多开发应用程序所需的组件,例如:
- Android操作系统的API(应用程序接口)文档,包括各种库、函数和类,供开发人员调用和使用。
- Android模拟器(emulator):可以在计算机上模拟Android设备,并进行应用程序测试和调试。
- 调试工具:包括adb(Android调试桥)、Logcat等,可以帮助开发人员调试和诊断应用程序。
- 样例代码和示例应用程序:提供给开发人员参考和学习。
使用Android SDK,开发人员可以利用Java语言编写Android应用程序,并通过Eclipse、Android Studio等开发环境对其进行编辑、编译和打包等操作。同时,Android SDK还支持用C/C++语言编写Android应用程序,并利用NDK(Native Development Kit)进行编译等操作。
2、Android SDK的获取
又将如何选择呢?我要完成的功能是地图和定位,故而选择的是①基础定位+②JAR格式包+③标准开发包,如图:
3、下载相关开发包后,进行Android Studio的配置
这里的配置较为繁琐,仔细点哇!
1、将获取的百度地图移动版开发密钥AK,配置到Android studio中
打开AndroidManifest.xml文件,在文件中进行如下图所示的配置:注意蓝牙框框内的name不允许改变,而那个value就是我们前边费劲心思搞到的ak
2、将下载好的JAR格式百度地图开发包置于libs下,并在build.gradle中增加一条语句,用于展开JAR开发包
语句:implementation files('libs/BaiduLBS_Android.jar'),注意这条语句放在dependencies
什么?你说找不到libs包?找不到不会自己创建啊?嗯?
3、创建一个jniLibs文件名,在class="lazy" data-src/java/jniLibs这个路径下,添加开发包的其他文件
你问我为什么要取这么个名字(jniLibs)?我也不知道,真不知道,我去问问ChatGPT。看图,懂了吧!嘿嘿!
4、在activity_main.xml的layout文件中,设置相关按钮(就是普通/卫星地图那些玩意的选择)
代码如下:
5、开启权限(定位权限,网络权限等)
具体开启权限的代码如下(注意这里的开启的权限,一部分与地图定位的无关,这是因为开发的功能不仅仅局限于地图定位,懂?):
okok,通过上述五步,地图定位的配置工作已经告一段落了,接下来就是枯燥的代码环节,我将贴粗关键代码,仅供学习!说明:代码实际是借鉴一位大佬的,具体是谁,忘记了,我只是进行了一些简单的修改,而且改的很烂,反正你也打不到我,别在评论区骂我就行!
4、代码(地图定位)
关于该功能实现的layout文件和权限配置这两个,我已经把代码贴出来了,往上找!
1、AndroidManifest.xml文件
首先需要声明,有些代码是不需要的,如下图的几个红色的框框,表示的是将要运行的Java活动程序,而该功能只需要执行MapApp、MainActivity两个Java活动程序。
我已经将不会用到的代码删除,具体如下:
2、在进活动运行前,还需要运行一个,MapApp.java文件
用于动态申请啥的...
package com.example.lbstest;import android.app.Application;import com.baidu.mapapi.CoordType;import com.baidu.mapapi.SDKInitializer;public class MapApp extends Application { @Override public void onCreate() { super.onCreate(); //动态申请 SDKInitializer.setAgreePrivacy(this,true); //在使用SDK各组件之前初始化context信息,传入ApplicationContext SDKInitializer.initialize(this); //自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型. //包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。 SDKInitializer.setCoordType(CoordType.BD09LL); }}
3、下面就是核心代码,MainActivity.java文件
package com.example.lbstest;import androidx.appcompat.app.AlertDialog;import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint;import android.content.DialogInterface;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.view.MenuInflater;import android.view.MenuItem;import android.view.View;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.ImageButton;import android.widget.RadioButton;import android.widget.RadioGroup;import android.widget.Toast;import com.baidu.mapapi.map.MapView;public class MainActivity extends AppCompatActivity{//MainActivity类继承于AppCompatActivity类 private MapView mMapView; private RadioGroup mapType; private RadioButton nombtn; private RadioButton sabtn; private CheckBox lubtn; private CheckBox rebtn; private com.baidu.location.LocationClient mLocClient; private com.baidu.mapapi.map.BaiduMap mBaiduMap; private com.baidu.mapapi.map.BitmapDescriptor bitmap;//标点的图标 private double markerLatitude = 0;//标点纬度 private double markerLongitude = 0;//标点经度 private ImageButton ibLocation;//重置定位按钮 private com.baidu.mapapi.map.Marker marker;//标点也可以说是覆盖物 public int MAP_flag =0;//用于点击按钮后是否在家附近 public static final String TAG="RightFragment"; @SuppressLint({"MissingInflatedId", "ResourceType"}) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取地图控件引用 mMapView = (MapView) findViewById(R.id.bmapView); mapType = findViewById(R.id.id_rp_mapType); nombtn = findViewById(R.id.id_normal); sabtn = findViewById(R.id.id_satel); lubtn= findViewById(R.id.id_lukuan); rebtn=findViewById(R.id.id_reli); initEvent(); initView();//视图初始化 initLocation();//定位初始化 mapOnClick();//地图点击 } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.bluetooth_map_onenet, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int itemid = item.getItemId();// 获取当前点击菜单的资源ID Intent intent = new Intent(); switch (itemid){ case R.id.action_bluetooth_button: intent.setClass(MainActivity.this, BlueToothActivity.class); startActivity(intent); MainActivity.this.finish(); break; case R.id.action_baidu_map: Toast.makeText(this, "你正在此界面", Toast.LENGTH_LONG).show(); case R.id.action_onenet_button: intent.setClass(MainActivity.this, OneNetActivity.class); startActivity(intent); MainActivity.this.finish(); break; } return super.onOptionsItemSelected(item); } private void initEvent(){ mapType.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {//地图类型选择 @Override public void onCheckedChanged(RadioGroup radioGroup, int i) { if (i==nombtn.getId()){ mMapView.getMap().setMapType(com.baidu.mapapi.map.BaiduMap.MAP_TYPE_NORMAL);//普通地图 }else if (i==sabtn.getId()){ mMapView.getMap().setMapType(com.baidu.mapapi.map.BaiduMap.MAP_TYPE_SATELLITE);//卫星地图 // } } }); lubtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { mMapView.getMap().setTrafficEnabled(b);//调用路况图 } }); rebtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { mMapView.getMap().setBaiduHeatMapEnabled(b);//调用热力图 } }); } private void initView() { // 地图初始化 mMapView = (MapView) findViewById(R.id.bmapView); //回到当前定位 ibLocation = (ImageButton) findViewById(R.id.ib_location); mMapView.showScaleControl(false); // 设置比例尺是否可见(true 可见/false不可见) //mMapView.showZoomControls(false); // 设置缩放控件是否可见(true 可见/false不可见) mMapView.removeViewAt(1);// 删除百度地图Logo mBaiduMap = mMapView.getMap(); mBaiduMap.setOnMarkerClickListener(new com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener() {//地图的点击事件 @Override public boolean onMarkerClick(com.baidu.mapapi.map.Marker marker) { final String info = (String) marker.getExtraInfo().get("info"); Toast.makeText(MainActivity.this, info, Toast.LENGTH_SHORT).show(); return true; } }); } public void initLocation() { //添加隐私合规政策 com.baidu.location.LocationClient.setAgreePrivacy(true); // 开启定位图层 mBaiduMap.setMyLocationEnabled(true); // 定位初始化 if (mLocClient == null) { try { mLocClient = new com.baidu.location.LocationClient(this); } catch (Exception e) { e.printStackTrace(); } } if (mLocClient != null) { MyLocationListener myListener = new MyLocationListener(); mLocClient.registerLocationListener(myListener); com.baidu.location.LocationClientOption option = new com.baidu.location.LocationClientOption(); option.setLocationMode(com.baidu.location.LocationClientOption.LocationMode.Hight_Accuracy);// 设置高精度定位 option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系,bd09ll 百度经纬度坐标 option.setScanSpan(0);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的 option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要 option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近” option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到 option.setIgnoreKillProcess(false);//可选,默认false,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认杀死 option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集 mLocClient.setLocOption(option); mLocClient.start();//开始定位 } } public void resetLocation(View view) { markerLatitude = 0; initLocation(); marker.remove();//清除标点 } public void mapOnClick() { // 设置marker图标 bitmap = com.baidu.mapapi.map.BitmapDescriptorFactory.fromResource(R.drawable.icon_marka); mBaiduMap.setOnMapClickListener(new com.baidu.mapapi.map.BaiduMap.OnMapClickListener() { @Override public void onMapPoiClick(com.baidu.mapapi.map.MapPoi mapPoi) { } //此方法就是点击地图监听 @Override public void onMapClick(com.baidu.mapapi.model.LatLng latLng) { //获取经纬度 markerLatitude = latLng.latitude; markerLongitude = latLng.longitude; //先清除图层 mBaiduMap.clear(); // 定义Maker坐标点 com.baidu.mapapi.model.LatLng point = new com.baidu.mapapi.model.LatLng(markerLatitude, markerLongitude); // 构建MarkerOption,用于在地图上添加Marker com.baidu.mapapi.map.MarkerOptions options = new com.baidu.mapapi.map.MarkerOptions().position(point) .icon(bitmap); // 在地图上添加Marker,并显示 //mBaiduMap.addOverlay(options); marker = (com.baidu.mapapi.map.Marker) mBaiduMap.addOverlay(options); Bundle bundle = new Bundle(); bundle.putSerializable("info", "纬度:" + markerLatitude + " 经度:" + markerLongitude); marker.setExtraInfo(bundle);//将bundle值传入marker中,给baiduMap设置监听时可以得到它 if (markerLatitude >= 23.72 && markerLongitude >=113.08 && markerLatitude <= 23.73 && markerLongitude <=113.09) { AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).setTitle("转跳远端控制").setMessage("此时已经定位至家的附近,是否转跳远端控制").setIcon(R.mipmap.ic_launcher).setPositiveButton("确定", new DialogInterface.OnClickListener() {//添加"Yes"按钮 @Override public void onClick(DialogInterface dialogInterface, int i) { Intent intent_DW = new Intent();//转跳活动 intent_DW.setClass(MainActivity.this, OneNetActivity.class); startActivity(intent_DW); MainActivity.this.finish(); }}).setNegativeButton("取消", new DialogInterface.OnClickListener() {//添加取消 @Override public void onClick(DialogInterface dialogInterface, int i) { Toast.makeText(MainActivity.this, "好的,收到主人", Toast.LENGTH_SHORT).show(); }}).create(); alertDialog.show(); } System.out.println("纬度"+markerLatitude); System.out.println("经度"+markerLongitude); System.out.println("标记位"+MAP_flag); //点击地图之后重新定位 initLocation(); } }); } public class MyLocationListener extends com.baidu.location.BDAbstractLocationListener { @Override public void onReceiveLocation(com.baidu.location.BDLocation location){ Toast.makeText(MainActivity.this, location.getAddrStr(), Toast.LENGTH_SHORT).show(); // MapView 销毁后不在处理新接收的位置 if (mMapView == null) { return; } double resultLatitude; double resultLongitude; if (markerLatitude == 0) {//自动定位 resultLatitude = location.getLatitude(); resultLongitude = location.getLongitude(); ibLocation.setVisibility(View.GONE); } else {//标点定位 resultLatitude = markerLatitude; resultLongitude = markerLongitude; ibLocation.setVisibility(View.VISIBLE); } com.baidu.mapapi.map.MyLocationData locData = new com.baidu.mapapi.map.MyLocationData.Builder() .accuracy(location.getRadius())// 设置定位数据的精度信息,单位:米 .direction(location.getDirection()) // 此处设置开发者获取到的方向信息,顺时针0-360 .latitude(resultLatitude) .longitude(resultLongitude) .build(); mBaiduMap.setMyLocationData(locData);// 设置定位数据, 只有先允许定位图层后设置数据才会生效 com.baidu.mapapi.model.LatLng latLng = new com.baidu.mapapi.model.LatLng(resultLatitude, resultLongitude); com.baidu.mapapi.map.MapStatus.Builder builder = new com.baidu.mapapi.map.MapStatus.Builder(); builder.target(latLng).zoom(20.0f); mBaiduMap.animateMapStatus(com.baidu.mapapi.map.MapStatusUpdateFactory.newMapStatus(builder.build())); } } @Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理 mMapView.onResume(); } @Override protected void onPause() { super.onPause(); //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理 mMapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); // 退出时销毁定位 mLocClient.stop(); // 关闭定位图层 mBaiduMap.setMyLocationEnabled(false); // 在activity执行onDestroy时必须调用mMapView.onDestroy() mMapView.onDestroy(); }}
行了,打完收工!
回头答完辩,把工程代码贴出来,再会!
23年4月8日修改,对代码进行补充,添加设置地址功能
使用三道不那么华丽的水平线,以下是更新后的代码,为了使代码的可用性和把玩性更高,我将一开始写死在代码里的经纬度数据进行了修正用以保证我项目的完整性。
项目需求:当在地图界面点击设置按钮后,界面有三个输入的EditText,分别是输入家庭地址、输入经度、输入纬度,需要注意的是只要提供家庭地址,就会自动生成经纬度,相反,只要提供经纬度,就会自动定位出家庭地址,并显示到文本框。除此之外还提供三个按钮,其一是清空当前输入数据,注意清空的数据是EditText中的数据;其二是获取当前位置,直接设置为家庭地址,需要注意的是,此时只是显示在EditText中,真正的参数并不赋值;最后一个按钮功能是设置完成,返回地图界面,需要注意的是,返回的同时,需要把经纬度两个参数进行赋值。
修改后的MainActivity代码:
package com.example.lbstest;import androidx.appcompat.app.AlertDialog;import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint;import android.content.DialogInterface;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.view.MenuInflater;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.ImageButton;import android.widget.RadioButton;import android.widget.RadioGroup;import android.widget.Toast;import com.baidu.mapapi.map.MapView;import java.text.DecimalFormat;public class MainActivity extends AppCompatActivity{//MainActivity类继承于AppCompatActivity类 private MapView mMapView; private RadioGroup mapType; private RadioButton nombtn;//普通地图 private RadioButton sabtn;//卫星地图 private CheckBox lubtn;//路况图选择 private CheckBox rebtn;//热力图选择 private Button setButton_Home;//设置家庭地址按钮 private com.baidu.location.LocationClient mLocClient; private com.baidu.mapapi.map.BaiduMap mBaiduMap; private com.baidu.mapapi.map.BitmapDescriptor bitmap;//标点的图标 private double markerLatitude = 0;//标点纬度 private double markerLongitude = 0;//标点经度 private ImageButton ibLocation;//重置定位按钮 private com.baidu.mapapi.map.Marker marker;//标点也可以说是覆盖物 //标记位 public int SetHomeLocation_Flg = 0;//代码是否设置成功 private double latitude = 23.72; private double longitude = 113.08;//经纬度初始是清远的地址调用对应的destroy()方法释放资源 public double Longitude; public double Latitude; public static final String TAG="RightFragment"; @SuppressLint({"MissingInflatedId", "ResourceType"}) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SetHomeLocation_Flg = getIntent().getIntExtra("Set_home_flg",0); if(SetHomeLocation_Flg == 1) { Longitude = getIntent().getDoubleExtra("Longitude", 0); Latitude = getIntent().getDoubleExtra("Latitude", 0); // System.out.println("经度"+Longitude);// System.out.println("纬度"+Latitude); //将double类型的经纬度保留小数点后两位,我不需要过于精确的数据 DecimalFormat df = new DecimalFormat("#.00"); String LongitudeFormatted = df.format(Longitude); String LatitudeFormatted = df.format(Latitude); Longitude = Double.parseDouble(LongitudeFormatted);//将只剩下两个小数点的经纬度重新转化为double类型的数据 Latitude = Double.parseDouble(LatitudeFormatted); SetHomeLocation_Flg = 0;//设置完成,标记位清零 // Toast.makeText(this, "地址设置成功", Toast.LENGTH_LONG).show();// System.out.println("保留两位小数的经度"+Longitude);// System.out.println("保留两位小数的纬度"+Latitude); }else if( SetHomeLocation_Flg==0 ){//两处赋值,一处是初始值,一处是SetHomeLocationActivity活动返回值 Longitude = longitude; Latitude = latitude;//使用默认的清远地址 Toast.makeText(this, "恢复默认家庭地址设置", Toast.LENGTH_LONG).show(); } //获取地图控件引用 mMapView = (MapView) findViewById(R.id.bmapView); mapType = findViewById(R.id.id_rp_mapType); nombtn = findViewById(R.id.id_normal); sabtn = findViewById(R.id.id_satel); lubtn = findViewById(R.id.id_lukuan); rebtn =findViewById(R.id.id_reli); setButton_Home = findViewById(R.id.id_set_home_location);//设置家庭地址的按钮 initEvent(); initView();//视图初始化 initLocation();//定位初始化 mapOnClick();//地图点击 } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.bluetooth_map_onenet, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int itemid = item.getItemId();// 获取当前点击菜单的资源ID Intent intent = new Intent(); switch (itemid){ case R.id.action_bluetooth_button: intent.setClass(MainActivity.this, BlueToothActivity.class); startActivity(intent); MainActivity.this.finish(); break; case R.id.action_baidu_map: Toast.makeText(this, "你正在此界面", Toast.LENGTH_LONG).show(); case R.id.action_onenet_button: intent.setClass(MainActivity.this, OneNetActivity.class); startActivity(intent); MainActivity.this.finish(); break; } return super.onOptionsItemSelected(item); } private void initEvent(){ mapType.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {//地图类型选择 @Override public void onCheckedChanged(RadioGroup radioGroup, int i) { if (i==nombtn.getId()){ mMapView.getMap().setMapType(com.baidu.mapapi.map.BaiduMap.MAP_TYPE_NORMAL);//普通地图 }else if (i==sabtn.getId()){ mMapView.getMap().setMapType(com.baidu.mapapi.map.BaiduMap.MAP_TYPE_SATELLITE);//卫星地图 } } }); lubtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { mMapView.getMap().setTrafficEnabled(b);//调用路况图 } }); rebtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) { mMapView.getMap().setBaiduHeatMapEnabled(b);//调用热力图 } }); setButton_Home.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, SetHomeLocationActivity.class); // 获取EditText中的经度和纬度 intent.putExtra("longitude", longitude); intent.putExtra("latitude", latitude); startActivity(intent); } }); } private void initView() { // 地图初始化 mMapView = (MapView) findViewById(R.id.bmapView); //回到当前定位 ibLocation = (ImageButton) findViewById(R.id.ib_location); mMapView.showScaleControl(false); // 设置比例尺是否可见(true 可见/false不可见) //mMapView.showZoomControls(false); // 设置缩放控件是否可见(true 可见/false不可见) mMapView.removeViewAt(1);// 删除百度地图Logo mBaiduMap = mMapView.getMap(); mBaiduMap.setOnMarkerClickListener(new com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener() {//地图的点击事件 @Override public boolean onMarkerClick(com.baidu.mapapi.map.Marker marker) { final String info = (String) marker.getExtraInfo().get("info"); Toast.makeText(MainActivity.this, info, Toast.LENGTH_SHORT).show(); return true; } }); } public void initLocation() { //添加隐私合规政策 com.baidu.location.LocationClient.setAgreePrivacy(true); // 开启定位图层 mBaiduMap.setMyLocationEnabled(true); // 定位初始化 if (mLocClient == null) { try { mLocClient = new com.baidu.location.LocationClient(this); } catch (Exception e) { e.printStackTrace(); } } if (mLocClient != null) { MyLocationListener myListener = new MyLocationListener(); mLocClient.registerLocationListener(myListener); com.baidu.location.LocationClientOption option = new com.baidu.location.LocationClientOption(); option.setLocationMode(com.baidu.location.LocationClientOption.LocationMode.Hight_Accuracy);// 设置高精度定位 option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系,bd09ll 百度经纬度坐标 option.setScanSpan(0);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的 option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要 option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近” option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到 option.setIgnoreKillProcess(false);//可选,默认false,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认杀死 option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集 mLocClient.setLocOption(option); mLocClient.start();//开始定位 } } public void resetLocation(View view) { markerLatitude = 0; initLocation(); marker.remove();//清除标点 } public void mapOnClick() { // 设置marker图标 bitmap = com.baidu.mapapi.map.BitmapDescriptorFactory.fromResource(R.drawable.icon_marka); mBaiduMap.setOnMapClickListener(new com.baidu.mapapi.map.BaiduMap.OnMapClickListener() { @Override public void onMapPoiClick(com.baidu.mapapi.map.MapPoi mapPoi) { } //此方法就是点击地图监听 @Override public void onMapClick(com.baidu.mapapi.model.LatLng latLng) { //获取经纬度 markerLatitude = latLng.latitude; markerLongitude = latLng.longitude; //先清除图层 mBaiduMap.clear(); // 定义Maker坐标点 com.baidu.mapapi.model.LatLng point = new com.baidu.mapapi.model.LatLng(markerLatitude, markerLongitude); // 构建MarkerOption,用于在地图上添加Marker com.baidu.mapapi.map.MarkerOptions options = new com.baidu.mapapi.map.MarkerOptions().position(point) .icon(bitmap); // 在地图上添加Marker,并显示 //mBaiduMap.addOverlay(options); marker = (com.baidu.mapapi.map.Marker) mBaiduMap.addOverlay(options); Bundle bundle = new Bundle(); bundle.putSerializable("info", "纬度:" + markerLatitude + " 经度:" + markerLongitude); marker.setExtraInfo(bundle);//将bundle值传入marker中,给baiduMap设置监听时可以得到它 if (markerLatitude >= (Latitude-0.01) && markerLongitude >=(Longitude-0.01) && markerLatitude <= (Latitude+0.01) && markerLongitude <=(Longitude+0.01)) { AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).setTitle("转跳远端控制").setMessage("此时已经定位至家的附近,是否转跳远端控制").setIcon(R.mipmap.ic_launcher).setPositiveButton("确定", new DialogInterface.OnClickListener() {//添加"Yes"按钮 @Override public void onClick(DialogInterface dialogInterface, int i) { Intent intent_DW = new Intent();//转跳活动 intent_DW.setClass(MainActivity.this, OneNetActivity.class); startActivity(intent_DW); MainActivity.this.finish(); }}).setNegativeButton("取消", new DialogInterface.OnClickListener() {//添加取消 @Override public void onClick(DialogInterface dialogInterface, int i) { Toast.makeText(MainActivity.this, "好的,收到主人", Toast.LENGTH_SHORT).show(); }}).create(); alertDialog.show(); } //点击地图之后重新定位 initLocation(); } }); } public class MyLocationListener extends com.baidu.location.BDAbstractLocationListener { @Override public void onReceiveLocation(com.baidu.location.BDLocation location){ Toast.makeText(MainActivity.this, location.getAddrStr(), Toast.LENGTH_SHORT).show(); // MapView 销毁后不在处理新接收的位置 if (mMapView == null) { return; } double resultLatitude; double resultLongitude; if (markerLatitude == 0) {//自动定位 resultLatitude = location.getLatitude(); resultLongitude = location.getLongitude(); ibLocation.setVisibility(View.GONE); } else {//标点定位 resultLatitude = markerLatitude; resultLongitude = markerLongitude; ibLocation.setVisibility(View.VISIBLE); } com.baidu.mapapi.map.MyLocationData locData = new com.baidu.mapapi.map.MyLocationData.Builder() .accuracy(location.getRadius())// 设置定位数据的精度信息,单位:米 .direction(location.getDirection()) // 此处设置开发者获取到的方向信息,顺时针0-360 .latitude(resultLatitude) .longitude(resultLongitude) .build(); mBaiduMap.setMyLocationData(locData);// 设置定位数据, 只有先允许定位图层后设置数据才会生效 com.baidu.mapapi.model.LatLng latLng = new com.baidu.mapapi.model.LatLng(resultLatitude, resultLongitude); com.baidu.mapapi.map.MapStatus.Builder builder = new com.baidu.mapapi.map.MapStatus.Builder(); builder.target(latLng).zoom(20.0f); mBaiduMap.animateMapStatus(com.baidu.mapapi.map.MapStatusUpdateFactory.newMapStatus(builder.build())); } } @Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理 mMapView.onResume(); } @Override protected void onPause() { super.onPause(); //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理 mMapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); // 退出时销毁定位 mLocClient.stop(); // 关闭定位图层 mBaiduMap.setMyLocationEnabled(false); // 在activity执行onDestroy时必须调用mMapView.onDestroy() mMapView.onDestroy(); }}
新增加的设置地址活动——SetHomeLocationActivity代码:
package com.example.lbstest;import android.annotation.SuppressLint;import android.content.Intent;import android.os.Bundle;import android.text.TextUtils;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;public class SetHomeLocationActivity extends AppCompatActivity { private EditText etAddress; private EditText etLongitude; private EditText etLatitude; private Button btnClear;//清空当前框内全部数据 private Button btnBtnUpData;//点击自动根据地址或经纬度补全信息 private Button btnGetLocation;//获取当前地址,并显示在输入框内 private Button btnSetHome;//设置完成,返回地图界面 private Button btnBtnGoBack;//直接返回地图界面 private double mLongitude = 0; private double mLatitude = 0; private int Set_flg = 1;//设置地址是否成功标记位 private int Set_false_flg = 0;//并未设置地址,保留原有地址返回地图定位界面 private com.baidu.location.LocationClient mLocClient; @SuppressLint("MissingInflatedId") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.set_home_location); etAddress = findViewById(R.id.et_address);//地址 etLongitude = findViewById(R.id.et_latitude);//经度 etLatitude = findViewById(R.id.et_longitude);//纬度 Toast.makeText(this, "此时是默认地址,如需重新设置,可清空数据", Toast.LENGTH_LONG).show(); mLongitude = getIntent().getDoubleExtra("longitude", 0.0); mLatitude = getIntent().getDoubleExtra("latitude", 0.0); etLatitude.setText(String.valueOf(mLatitude)); etLongitude.setText(String.valueOf(mLongitude)); btnClear = findViewById(R.id.btn_set_home_location_clear); btnBtnUpData = findViewById(R.id.btn_set_home_location_upData); btnGetLocation = findViewById(R.id.btn_set_home_location_confirm); btnSetHome = findViewById(R.id.btn_set_home_ok_goBack_diTu); btnBtnGoBack = findViewById(R.id.btn_goBack); btnClear.setOnClickListener(new View.OnClickListener() {//点击按钮清空已输入的数据信息 @Override public void onClick(View v) { etAddress.setText(""); etLongitude.setText(""); etLatitude.setText(""); } }); btnBtnUpData.setOnClickListener(new View.OnClickListener() {//通过按钮将地址或经纬度补全 @Override public void onClick(View v) { String address = etAddress.getText().toString().trim(); String latitude = etLatitude.getText().toString().trim(); String longitude = etLongitude.getText().toString().trim(); if (!TextUtils.isEmpty(address)) { // 使用Geocode API查询经纬度信息 // 创建地理编码检索实例 com.baidu.mapapi.search.geocode.GeoCoder geoCoder = com.baidu.mapapi.search.geocode.GeoCoder.newInstance(); // 设置地理编码检索监听者 geoCoder.setOnGetGeoCodeResultListener(new com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener() { @Override public void onGetGeoCodeResult(com.baidu.mapapi.search.geocode.GeoCodeResult result) {if (result == null || result.getLocation() == null) Toast.makeText(SetHomeLocationActivity.this, "未能找到对应的经纬度信息", Toast.LENGTH_SHORT).show();else { etLatitude.setText(String.valueOf(result.getLocation().latitude)); etLongitude.setText(String.valueOf(result.getLocation().longitude));} } @Override public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {// 不需要实现该方法 } }); // 发起地理编码检索请求 geoCoder.geocode(new com.baidu.mapapi.search.geocode.GeoCodeOption().city("").address(address)); } else if (!TextUtils.isEmpty(latitude) && !TextUtils.isEmpty(longitude)) { // 使用Reverse Geocode API查询地址信息 // 创建反地理编码检索实例 com.baidu.mapapi.search.geocode.GeoCoder geoCoder = com.baidu.mapapi.search.geocode.GeoCoder.newInstance(); // 设置反地理编码检索监听者 geoCoder.setOnGetGeoCodeResultListener(new com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener() { @Override public void onGetGeoCodeResult(com.baidu.mapapi.search.geocode.GeoCodeResult result) {// 不需要实现该方法 } @Override public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {if (result == null || result.getAddress() == null) { Toast.makeText(SetHomeLocationActivity.this, "未能找到对应的地址信息", Toast.LENGTH_SHORT).show();} else { etAddress.setText(result.getAddress());} } }); // 发起反地理编码检索请求 com.baidu.mapapi.model.LatLng latLng = new com.baidu.mapapi.model.LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude)); geoCoder.reverseGeoCode(new com.baidu.mapapi.search.geocode.ReverseGeoCodeOption().location(latLng)); } } }); btnGetLocation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 创建百度地图LocationClient实例 try { mLocClient = new com.baidu.location.LocationClient(SetHomeLocationActivity.this); } catch (Exception e) { e.printStackTrace(); } // 配置定位参数 com.baidu.location.LocationClientOption option = new com.baidu.location.LocationClientOption(); option.setCoorType("bd09ll"); option.setIsNeedAddress(true); mLocClient.setLocOption(option); // 设置定位监听器 mLocClient.registerLocationListener(new com.baidu.location.BDAbstractLocationListener() { @Override public void onReceiveLocation(com.baidu.location.BDLocation location) { // 获取详细地址信息 String address = location.getAddrStr(); etAddress.setText(address); // 获取纬度和经度 double latitude = location.getLatitude(); double longitude = location.getLongitude(); etLatitude.setText(String.valueOf(latitude)); etLongitude.setText(String.valueOf(longitude)); // 停止定位 mLocClient.stop(); } }); // 启动定位 mLocClient.start(); } }); btnSetHome.setOnClickListener(new View.OnClickListener() {//返回有用信息到MainActivity活动中,即返回经纬度数据 @Override public void onClick(View v) { if (checkInput()) { // 设置家庭地址信息并返回地图界面 mLongitude = Double.parseDouble(etLongitude.getText().toString()); mLatitude = Double.parseDouble(etLatitude.getText().toString()); Intent intent = new Intent(SetHomeLocationActivity.this, MainActivity.class); intent.putExtra("Longitude", mLongitude); intent.putExtra("Latitude", mLatitude); intent.putExtra("Set_home_flg",Set_flg);//告诉MainActivity活动已经设置成功 startActivity(intent); } else { Toast.makeText(SetHomeLocationActivity.this, "请至少输入家庭地址、经度和纬度中的一项、并补全信息", Toast.LENGTH_SHORT).show(); } } }); btnBtnGoBack.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(SetHomeLocationActivity.this, MainActivity.class); intent.putExtra("Set_home_flg",Set_false_flg);//告诉MainActivity活动并未设置 startActivity(intent); } }); } // 检查输入数据是否为空 private boolean checkInput() { if (TextUtils.isEmpty(etAddress.getText().toString().trim()) && (TextUtils.isEmpty(etLongitude.getText().toString().trim()) ||TextUtils.isEmpty(etLatitude.getText().toString().trim()))) {//经纬度要两个都有才能进行设置,属于一个数据 return false; }else if((TextUtils.isEmpty(etLatitude.getText().toString().trim()) && TextUtils.isEmpty(etLongitude.getText().toString().trim())) ||TextUtils.isEmpty(etLatitude.getText().toString().trim())|| TextUtils.isEmpty(etLongitude.getText().toString().trim())){//经纬度都为空,其中一个为空 String address = etAddress.getText().toString().trim(); if (!TextUtils.isEmpty(address)) { // 使用Geocode API查询经纬度信息 // 创建地理编码检索实例 com.baidu.mapapi.search.geocode.GeoCoder geoCoder = com.baidu.mapapi.search.geocode.GeoCoder.newInstance(); // 设置地理编码检索监听者 geoCoder.setOnGetGeoCodeResultListener(new com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener() { @Override public void onGetGeoCodeResult(com.baidu.mapapi.search.geocode.GeoCodeResult result) { if (result == null || result.getLocation() == null)Toast.makeText(SetHomeLocationActivity.this, "未能找到对应的经纬度信息", Toast.LENGTH_SHORT).show(); else {etLatitude.setText(String.valueOf(result.getLocation().latitude));etLongitude.setText(String.valueOf(result.getLocation().longitude)); } } @Override public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) { // 不需要实现该方法 } }); // 发起地理编码检索请求 geoCoder.geocode(new com.baidu.mapapi.search.geocode.GeoCodeOption().city("").address(address)); } return false; } return true; } @Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理 } @Override protected void onPause() { super.onPause(); //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理 } @Override protected void onDestroy() { super.onDestroy(); // 退出时销毁定位 mLocClient.stop(); }}
然后是新增加活动的layout文件,具体代码如下:
okok,以上就是新增加的功能,具体功能也不介绍了,具体功能实现在代码中以经有很多注释。
来源地址:https://blog.csdn.net/Uncoverlove/article/details/129875469
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341