一、SmartRefreshLayout
传统Adapter的优化
- 回顾ListView配合Adapter显示数据
布局中设置ListView控件
设计Item子布局
自定义Adapter并重写getView()等方法
加载子布局页面及控件
给控件绑定数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0bMWvNMs-1610011416462)(Android综合应用.assets/image-20201104154050119.png)]
重复创建,效率低下
- 解决方式
在继承BaseAdapter的自定义类里面创建一个内部类
static class ViewHolder{
private TextView tvName;
private TextView tvInfo;
}
起到缓存View的目的,避免重复创建
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(null == convertView) {
//加载item布局文件,赋值给convertView
convertView = LayoutInflater.from(context)
.inflate(layout, null);
holder = new ViewHolder();
//创建Item中的控件对象
holder.tvName = convertView.findViewById(R.id.tv_name);
holder.tvInfo = convertView.findViewById(R.id.tv_info);
//在convertView中缓存holder对象
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//给控件对象赋值
Student stu = stus.get(position);
holder.tvName.setText(stu.getName());
holder.tvInfo.setText(stu.getInfo());
return convertView;
}
SmartRefreshLayout控件的使用
- 使用步骤
第一步:导入依赖:
//添加SmartRefreshLayout依赖
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0'
implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.1'
第二步:添加智能刷新控件(可自己设计刷新头和刷新尾样式)
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--自定义Header样式-->
<pl.droidsonroids.gif.GifImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@mipmap/eat"/>
<ListView
android:id="@+id/lv_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
设置刷新样式
-
方式一:全局方式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7nBbd2ie-1610011416465)(Android综合应用.assets/image-20201104155643278.png)]
public class MyApplication extends Application {
static {
//设置Header样式
SmartRefreshLayout.setDefaultRefreshHeaderCreator(
new DefaultRefreshHeaderCreator() {
@NonNull
@Override
public RefreshHeader createRefreshHeader(@NonNull Context context, @NonNull RefreshLayout layout) {
//创建Header样式
BezierRadarHeader header =
new BezierRadarHeader(context);
return header;
}
}
);
//设置Footer样式
SmartRefreshLayout.setDefaultRefreshFooterCreator(
new DefaultRefreshFooterCreator() {
@NonNull
@Override
public RefreshFooter createRefreshFooter(@NonNull Context context, @NonNull RefreshLayout layout) {
//实例化一种Footer样式
FalsifyFooter footer =
new FalsifyFooter(context);
return footer;
}
}
);
}
}
- 方式二:XML方式
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.scwang.smartrefresh.layout.header.ClassicsHeader
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:id="@+id/lv_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.scwang.smartrefresh.layout.footer.BallPulseFooter
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
- 方式三:java方式
//设置 Header 为 贝塞尔雷达 样式
refreshLayout.setRefreshHeader(new BezierCircleHeader(this)).setHorizontalFadingEdgeEnabled(true);
//设置 Footer 为 球脉冲 样式
refreshLayout.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale));
三种方式优先级:java>xml>application
第三步:给智能刷新控件设置监听器
//给智能刷新控件注册下拉刷新事件监听器
refreshLayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(@NonNull RefreshLayout refreshLayout) {
refreshData();
refreshLayout.finishRefresh();
}
});
//给智能刷新控件注册上拉加载更多事件监听器
refreshLayout.setOnLoadMoreListener(new onl oadMoreListener() {
@Override
public void onl oadMore(@NonNull RefreshLayout refreshLayout) {
//加载更多数据(假设超过10条数据则加载完毕)
if(stus.size() < 10) {
loadMoreData();
//通知加载数据完毕
refreshLayout.finishLoadMore();
} else {
//通知没有更多数据可加载
refreshLayout.finishLoadMoreWithNoMoreData();
}
}
});
二、EventBus
传统页面跳转实现(带返回值)
Intent intent = new Intent();
//设置目的地Activity类
intent.setClass(MainActivity.this,NewActivity.class);
//跳转时需要携带数据
intent.putExtra("name", names[position]);
intent.putExtra("phone", "1234565");
intent.putExtra("email", "123132ees");
intent.putExtra("position",position);
startActivityForResult(intent,LOGIN_REQUEST);
//接收返回的响应数据,并且刷新界面
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
//requestCode跳转时的请求码
//resultCode返回响应的结果码
//data返回响应的Intent对象
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == LOGIN_REQUEST && resultCode == 200){
//获得从NewActivity响应的数据
String name = data.getStringExtra("name");
//修改数据源
names[currentPosition]=name;
//刷新ListView
adapter.notifyDataSetChanged();
}
}
EventBus的使用
- 类似访问者/订阅者模式,EventBus包含3个元素
时间,订阅者,发布者
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RNpclaVP-1610011416466)(Android综合应用.assets/image-20201104162520610.png)]
- 两种事件类型:普通事件、粘性事件
两种事件的区别:
1)相同点:都必须要注册EventBus
2)普通事件只有注册以后发布的事件才能收到,粘性事件可以收到注册前发布的粘性事件;订阅了粘性事件后也可以收到普通的事件
- 用法
第一步:导入依赖
implementation 'org.greenrobot:eventbus:3.2.0'
第二步:获取EventBus对象
EventBus eventBus = EventBus.getDefault();
第三步:注册EventBus
eventBus.register(MainActivity.this);
//取消注册
//eventBus.unregister(MainActivity.this);
第四步:定义事件类
/**
* 自定义EventBus事件
*/
public class MyEvent {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "MyEvent{" +
"msg='" + msg + '\'' +
'}';
}
}
第五步:发布事件
//定义事件对象
MyEvent event = new MyEvent();
event.setMsg("天气晴朗,出来晒被子了");
//发布事件
EventBus.getDefault().post(event);
//粘性事件
EventBus.getDefault().postSticky(event);
//移除粘性事件
//removeStickyEvent(事件)
//移除所有粘性事件
//removeAllStickyEvents()
第六步:订阅者编写事件回调方法
//订阅普通事件,只能接收普通事件
@Subscribe
//订阅粘性事件后可以接收到注册EventBus前发布的粘性事件
//@Subscribe(sticky = true, threadMode = ThreadMode.ASYNC)
public void onEvent(MyEvent event){
tvMsg.setText(event.getMsg());
}
五种线程模式
1)POSTING:事件回调方法的执行在发布事件的线程中
2)MAIN:事件回调方法的执行在主线程中
3)MAINORDERED:事件回调方法的执行在主线程的事件队列
4)BACKGROUND:事件回调方法的执行在后台线程中
5)ASYNC:事件回调方法的执行在后台单独的一个线程中,可以用来执行耗时任务
三、Glide
Glide用法
第一步:引入依赖
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
第二步:添加权限
<!--如果需要加载网络图片-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name= "android.permission.ACCESS_NETWORK_STATE"/>
<!--要从本地文件夹或 DCIM 或图库中加载图片-->
<uses-permission android:name= "android.permission.READ_EXTERNAL_STORAGE" />
<!--如果要将 Glide 的缓存存储到SD 卡上-->
<uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" />
第三步:加载图片
- 加载网络图片
String imgUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1603099775034&di=74dce1068c65de1a0d869e69906eb507&imgtype=0&src=http%3A%2F%2Fa0.att.hudong.com%2F56%2F12%2F01300000164151121576126282411.jpg";
Glide.with(this).load(imgUrl).into(ivImg);
- 加载一个网络动图
String imgUrl = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3278720085,289405952&fm=26&gp=0.jpg";
Glide.with(this).asGif().load(gifImg).into(ivImg);
- 加载Assets目录下的图片
try {
//将Assets目录的图片解析成Bitmap
AssetManager assets = getAssets();
InputStream in = assets.open("notexist.jpg");
Bitmap bitmap = BitmapFactory.decodeStream(in);
//使用Glide框架加载Bitmap
Glide.with(this).load(bitmap).into(ivImg);
} catch (IOException e) {
e.printStackTrace();
}
- 加载raw目录下的图片
Glide.with(this).load(R.raw.man).into(ivImg);
- 设置占位符的请求选项,加载网络图片
String url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1603101761728&di=721ae5232e882c8cf1f247355b4cf068&imgtype=0&src=http%3A%2F%2Fa0.att.hudong.com%2F70%2F91%2F01300000261284122542917592865.jpg";
Glide.with(this)
.load(url)
.circleCrop()//转换策略,特别适合头像的显示
// .fitCenter()
// .centerCrop()
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)//默认磁盘缓存策略
// .diskCacheStrategy(DiskCacheStrategy.NONE)//不缓存
.placeholder(R.mipmap.loading)//正在加载时显示的图片
.error(R.mipmap.failure)//永久加载失败时显示的图片
.fallback(R.mipmap.notexist)//表示图片地址为null时显示的图片
.into(ivImg);
- GeneratedAPI
GlideApp.with(this)
.asGif()
.load("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3278720085,289405952&fm=26&gp=0.jpg")
.placeholder(R.mipmap.loading)
.circleCrop()
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(ivImg);
四、Gson
Gson的用法
Grade
public class Grade {
private String gName;
public String getgName() {
return gName;
}
public void setgName(String gName) {
this.gName = gName;
}
@Override
public String toString() {
return "Grade{" +
"gName='" + gName + '\'' +
'}';
}
}
Student
public class Student {
private String name;
private int age;
private transient String transientProp;
private static String college;
private Grade grade;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getTransientProp() {
return transientProp;
}
public void setTransientProp(String transientProp) {
this.transientProp = transientProp;
}
public static String getCollege() {
return college;
}
public static void setCollege(String college) {
Student.college = college;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
", transientProp='" + transientProp + '\'' +
", college=" + college +
", grade=" + grade +
'}';
}
}
第一步:导入依赖
implementation 'com.google.code.gson:gson:2.8.6'
第二步:初始化Gson对象(new方法)
Gson gson = new Gson();
gson.toJson(1); // ==> 1
gson.toJson("abcd"); // ==> "abcd"
gson.toJson(new Long(10)); // ==> 10
int[] values = { 1 };
gson.toJson(values); // ==> [1]
第二步:初始化Gson对象(GsonBuilder)
Gson gson = new GsonBuilder()//创建GsonBuilder对象
.setPrettyPrinting()//格式化输出
.serializeNulls()//允许输出Null值属性
.setDateFormat("YY:MM:dd")//日期格式化
.create();//创建Gson对象
第三步:Gson串操作
- 普通对象
序列化
//实例化Student对象
Student student = new Student();
student.setName("July");
student.setAge(20);
student.setTransientProp("transient属性");
student.setCollege("软件学院");
//student对象序列化
String json = gson.toJson(student);
//显示Json串到文本框
tvJson.setText(json);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SrBZ21Q6-1610011416468)(Android综合应用.assets/image-20201104170625484.png)]
为什么显示为null值呢???
因为javaBean属性中出现transient和static修饰,Gson是不会序列化的,所以显示为null
反序列化
//得到Json串
String json = tvJson.getText().toString();
//对Json串反序列化
Student student = gson.fromJson(json, Student.class);
//把反序列化后的对象显示在文本框
tvObj.setText(student.toString());
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bmF3jrU8-1610011416469)(Android综合应用.assets/image-20201104171457564.png)]
- 嵌套类的对象
序列化
Student stu = new Student();
stu.setName("李雷");
stu.setAge(18);
stu.setBirthday(new Date());
Grade grade = new Grade();
grade.setgName("Android");
stu.setGrade(grade);
//序列化
String json = gson.toJson(stu);
tvJson.setText(json);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-usWLpwrg-1610011416470)(Android综合应用.assets/image-20201104171624388.png)]
反序列化
String json = tvJson.getText().toString();
//反序列化
Student stu = gson.fromJson(json, Student.class);
tvObj.setText(stu.toString());
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ps4GypuZ-1610011416471)(Android综合应用.assets/image-20201104171634863.png)]
- 对象数组
序列化
Student[] stus = new Student[1];
Student stu = new Student();
stu.setName("李雷");
stu.setAge(18);
stu.setBirthday(new Date());
Grade grade = new Grade();
grade.setgName("Android");
stu.setGrade(grade);
stus[0] = stu;
//序列化
String json = gson.toJson(stus);
tvJson.setText(json);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ExSICa4j-1610011416471)(Android综合应用.assets/image-20201104171952309.png)]
反序列化
String json = tvJson.getText().toString();
//反序列化
Student[] stus = gson.fromJson(json, Student[].class);
for(int i = 0; i < stus.length; i++){
tvObj.setText(stus[i].toString() + ";" + tvObj.getText().toString());
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kz84eliX-1610011416472)(Android综合应用.assets/image-20201104172000373.png)]
- 对象集合
序列化
List<Student> stus = new ArrayList<>();
Student stu1 = new Student();
stu1.setName("李雷");
stu1.setAge(18);
stus.add(stu1);
Student stu2 = new Student();
stu2.setName("韩梅梅");
stu2.setAge(18);
stus.add(stu2);
//序列化
String json = gson.toJson(stus);
tvJson.setText(json);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vuoGWd2a-1610011416473)(Android综合应用.assets/image-20201104172111626.png)]
反序列化
String json = tvJson.getText().toString();
//反序列化
//1. 得到集合的类型
Type type = new TypeToken<List<Student>>(){}.getType();
//2. 反序列化
List<Student> stus = gson.fromJson(json, type);
tvObj.setText(stus.toString());
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oE42nlKb-1610011416474)(Android综合应用.assets/image-20201104172117409.png)]
五、OkHttp
OkHttp使用方法
-
同步和异步的区别:
同步方式是发送请求后,就会进入阻塞状态,直到收到响应。同一时刻只能有一个任务发起,synchronized关键字锁住了整个代码,如果当前OkhttpClient已经执行了一个同步任务,如果这个任务没有释放锁,那么新发起的请求将被阻塞,直到当前任务释放锁
异步方式是在回调中处理响应的,同一时刻可以发起多个请求,因为异步请求每一个都是在一个独立的线程,由两个队列管理,并且synchronized只锁住了代码校验是否执行的部分。
-
OKhttp中请求任务的管理是由dispatcher负责的,负责请求的分发和发起。实际执行请求的是ConnctionPool。
第一步:导入依赖
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
第二步:创建OkHttpClient对象(new)
OkHttpClient okHttpClient = new OkHttpClient();
第二步:创建OkHttpClient对象(Bulder)
okHttpClient = new OkHttpClient.Builder()
//可以添加网络请求参数,如网络超时连接时间等
.build();
无参数的同步的Get请求
第三步:创建Request请求对象
Request.Builder reqBuilder = new Request.Builder();
//设置Builder参数
reqBuilder.url("http://www.baidu.com");
//通过Builder对象创建Request对象
Reqsuet request = reqBuilder.build();
第四步:创建Call对象
Call call = okHttpClient.newCall(request);
第五步:发起请求并获取响应(同步)
try {
Response response = call.execute();
//获取响应中的内容
ResponseBody body = response.body();
//获取响应中包含的字符串信息
String result = body.string();
Log.i("phz", result);
} catch (IOException e) {
e.printStackTrace();
}
url末尾带参数的异步的get请求
第三步:创建请求对象
Request request = new Request.Builder()
.url(ServerConfig.SERVER_HOME
+ "WithNoParamRequest?info=签到")
.build();
第四步:创建call对象
Call call = okHttpClient.newCall(request);
第五步:异步方式提交请求并获取响应
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.i("phz", "请求失败");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
//获取服务端返回的数据(假设是字符串)
String result = response.body().string();
Log.i("phz", result);
//通知界面信息改变
Message msg = handler.obtainMessage();
msg.what = 1;
msg.obj = result;
handler.sendMessage(msg);
}
});
使用POST方式提交Form表单数据
第三步:创建Request请求对象(提前准备好Form表单数据封装)
//创建FormBody对象
FormBody formBody =
new FormBody.Builder()
.add("name", "张三")
.add("course", "Android综合应用")
.build();
//创建请求对象
Request request = new Request.Builder()
.url(ServerConfig.SERVER_HOME + "WithFormParamRequest")
// .method("POST", formBody)
.post(formBody)
.build();
第四步:创建call对象
Call call = okHttpClient.newCall(request);
第五步: 提交请求并获取响应
try {
Response response = call.execute();
//获取响应的字符串信息
String result = response.body().string();
Message msg = handler.obtainMessage();
msg.what = 1;
msg.obj = result;
handler.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
提交普通字符串数据
第三步:创建Request对象
//1) 使用RequestBody封装请求数据
//获取待传输数据对应的MIME类型
MediaType type = MediaType.parse("text/plain");
//创建RequestBody对象
RequestBody reqBody = RequestBody.create(
"{'name':'李四','course':'Android'}",
type
);
//2) 创建请求对象
Request request = new Request.Builder()
.url(ServerConfig.SERVER_HOME + "JsonStringParamRequest")
.post(reqBody)
.build();
第四步:创建CALL对象
Call call = okHttpClient.newCall(request);
第五步:提交请求并获取响应
//4. 提交请求并获取响应
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.i("phz", "请求失败");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String result = response.body().string();
Message msg = handler.obtainMessage();
msg.what = 1;
msg.obj = result;
handler.sendMessage(msg);
}
});
从本地files目录下上传一个PDF文件给服务器
第三步:创建请求对象
//获取待上传的pdf文件
String pdf = getFilesDir().getAbsolutePath() + "/test.pdf";
File file = new File(pdf);
//获取待上传文件的MIME类型
MediaType type = MediaType.parse("application/pdf");
//创建RequestBody对象,并封装数据
RequestBody reqBody = RequestBody.create(
file,//待上传的数据
type //数据对应的MIME类型
);
Request request = new Request.Builder()
.url(ServerConfig.SERVER_HOME + "UpPDFRequest")
.post(reqBody)
.build();
第四步:创建CALL对象
Call call = okHttpClient.newCall(request);
第五步:异步方式提交请求并获取响应
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.i("phz", "请求失败");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
//获取服务端返回的数据
String result = response.body().string();
//使用handler将数据封装在Message中,并发布出去,以备显示在UI控件中
Message msg = handler.obtainMessage();
msg.what = 1;
msg.obj = result;
handler.sendMessage(msg);
}
});
从服务端下载图片
第三步:创建请求对象
Request request = new Request.Builder()
.url(ServerConfig.SERVER_HOME + "DownLoadImgRequest")
.build();
第四步: 创建CALL对象
Call call = okHttpClient.newCall(request);
第五步:发起异步请求并获取响应
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.i("phz", "请求图片失败");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
//获取服务端返回的网络输入流
InputStream in = response.body().byteStream();
//第1种:获取本地文件输出流,经过流的循环读写实现图片拷贝
//第2种:通过BitmapFactory将输入流解析成一个Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(in);
//通过Message发布
Message msg = handler.obtainMessage();
msg.what = 2;
msg.obj = bitmap;
handler.sendMessage(msg);
}
});
从服务端获取图片资源路径,使用Glide框架显示图片
第三步:创建请求对象
Request request = new Request.Builder()
.url(ServerConfig.SERVER_HOME + "DownLoadImgNameRequest")
.build();
第四步:创建CALL对象
Call call = okHttpClient.newCall(request);
第五步:发起请求获取网络路径
try {
Response response = call.execute();
String img = response.body().string();
Message msg = handler.obtainMessage();
msg.what = 3;
msg.obj = img;
handler.sendMessage(msg);
}catch (IOException e){
e.printStackTrace();
}
第六步:通过资源路径下载图片
//获取图片资源路径
String imgUrl = (String) msg.obj;
Glide.with(MainActivity.this)
.load(imgUrl)
.into(ivImg);
六、百度地图
简单使用
申请密钥
地址
http://lbsyun.baidu.com/apiconsole/key
创建应用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oenWermz-1610011416475)(Android综合应用.assets/image-20201105090519752.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gesSdDcW-1610011416476)(Android综合应用.assets/image-20201105090551192.png)]
获取SHA1
- 进去C:\Users\PengHuAnZhi.android
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vYPaE820-1610011416476)(Android综合应用.assets/image-20201105090749817.png)]
- 输入
keytool -v -list -keystore debug.keystore
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bfT6axxo-1610011416477)(Android综合应用.assets/image-20201105090821101.png)]
- 密码android
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1rxpLkVc-1610011416478)(Android综合应用.assets/image-20201105090859869.png)]
输入SHA1和包名
30:13:80:F5:23:29:BB:FA:A3:44:89:28:F1:48:61:CF:18:AC:D8:53
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sc5lwUN3-1610011416478)(Android综合应用.assets/image-20201105091027203.png)]
提交,得到AK
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E9OgBwMb-1610011416479)(Android综合应用.assets/image-20201105091134112.png)]
配置环境
将SDK开发库文件进行解压缩得到:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JUUmRgIT-1610011416480)(Android综合应用.assets/image-20201105091305759.png)]
全部引入工程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCgd8RMw-1610011416480)(Android综合应用.assets/image-20201105091359256.png)]
配置gradle
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-go8xmjxw-1610011416481)(Android综合应用.assets/image-20201105091551449.png)]
同步后:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C0J5HbKJ-1610011416482)(Android综合应用.assets/image-20201105091626839.png)]
配置AK
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="79FANr89amki22Uc4i7oxqD69hjkkLx2" />
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-khcl837F-1610011416482)(Android综合应用.assets/image-20201105091726574.png)]
添加所需权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
简单使用
在布局中添加控件
<com.baidu.mapapi.map.MapView
android:id="@+id/mvMap"
android:layout_width="match_parent"
android:layout_height="match_parent" />
在应用程序创建时初始化 SDK引用的Context 全局变量,创建地图Activity
// 在使用SDK各组件之前初始化context信息,传入ApplicationContext
// 注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(getApplicationContext());
重新生命周期方法,管理地图生命周期
@Override
protected void onDestroy() {
super.onDestroy();
// 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
// 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
// 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mMapView.onPause();
}
基础地图
获取地图控件
MapView mvMap = findViewById(R.id.mvMap);
获取地图控制器
BaiduMap baiduMap = mvMap.getMap();
获取地图UI控制器
UiSettings uiSettings = baiduMap.getUiSettings();
地图类型
//显示普通地图(默认地图形式)
baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
//显示卫星地图
baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
//空白地图
baiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
实时交通图
//显示交通图(默认不显示交通图)
baiduMap.setTrafficEnabled(true);
热力图
//显示热力图(默认不显示热力图)
baiduMap.setBaiduHeatMapEnabled(true);
地图控制
logo
- 设置logo位置
mvMap.setLogoPosition(LogoPosition.logoPostionCenterBottom);
position - 枚举类LogoPosition
logoPostionCenterBottom 屏幕中下位置
logoPostionCenterTop 屏幕中上位置
logoPostionleftBottom 屏幕左下位置
logoPostionleftTop 屏幕左上位置
logoPostionRightBottom 屏幕右下位置
logoPostionRightTop 屏幕右上位置
- 删除logo
//获取地图上方id为1的View(Logo的位置id=1)
//mpView.removeViewAt(1) 霸王删除 不仅仅能删logo,再删则删放大 缩小图标,再删则删比例尺图标
View logo = mvMap.getChildAt(1);
//隐藏Logo的View
if (null != logo && logo instanceof ImageView) {
logo.setVisibility(View.INVISIBLE);
}
指南针
- 是否显示
Log.i("phz", "默认指南针显示状态:" +uiSettings.isCompassEnabled());
- 设置显示
//设置显示指南针
baiduMap.setCompassEnable(true);
uiSettings.setCompassEnabled(true);
//设置指南针位置
baiduMap.setCompassPosition(new Point(800,700));
//设置指南针图标
baiduMap.setCompassIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.znz));
比例尺
- 是否显示(默认显示)
mvMap.showZoomControls(true);
- 获取比例尺大小
mvMap.getMapLevel()
- 通过设置地图更新来重新设置比例尺位置
baiduMap.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
//改变比例尺和放大缩小图标位置
//设置放大缩小按钮位置
mvMap.setZoomControlsPosition(new Point(800, 200));
//设置比例尺位置
mvMap.setScaleControlPosition(new Point(200, 300));
}
});
- 设置比例尺放大缩小范围
max - [3-21] 且 max > min, 否则无效
min - [3-21] 且 max > min, 否则无效
百度地图的缩放级别从3~21,共19个级别,如下:
5m,10m, 20m, 50m, 100m, 200m, 500m, 1km, 2km, 5km, 10km, 20km, 25km, 50km, 100km, 200km, 500km, 1000km, 2000km。
缩放级别对应为21、20、19、18、17、16、15、14、13、12、11、10、9、8、7、6、5、4、3。
baiduMap.setMaxAndMinZoomLevel(18, 9);
//获取当前允许的最大的比例尺
float max = baiduMap.getMaxZoomLevel();
//获取当前允许的最小的比例尺
float min = baiduMap.getMinZoomLevel();
- 设置当前地图的缩放级别(默认比例尺大小)
//1. 创建一个地图状态更新对象
MapStatusUpdate statusUpdate = MapStatusUpdateFactory.zoomTo(18);
//2. 通过百度地图控制器应用状态更新
baiduMap.setMapStatus(statusUpdate);
俯视图效果
//创建俯视图的MapStatus对象
MapStatus mapStatus = new MapStatus.Builder()
.overlook(-45)//俯视范围:(-45,0)
.build();
//1 创建俯视图的MapStatusUpdate对象
MapStatusUpdate statusUpdate =
MapStatusUpdateFactory.newMapStatus(mapStatus);
//2 通过百度控制器应用地图状态更新
baiduMap.setMapStatus(statusUpdate);
地图覆盖物
所有叠加或覆盖到地图的内容,我们统称为地图覆盖物。如文本、标注、几何图形 、信息窗口等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ABFPPDKT-1610011416483)(Android综合应用.assets/image-20201105095846419.png)]
单一标注覆盖物
第一步:创建标注覆盖物对象,并设置其参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Yjdbuf4-1610011416484)(Android综合应用.assets/image-20201105100230363.png)]
//获取图标(BitmapDescriptor对象)
BitmapDescriptor bDescriptor = BitmapDescriptorFactory
.fromResource(R.mipmap.red_marker);
//创建覆盖物显示位置的坐标对象
//116.404017,39.915122
LatLng position = new LatLng(39.915122, 116.404017);
//如果覆盖物包含额外信息,需通过Bundle封装额外信息
Bundle bundle = new Bundle();
bundle.putString("info", "首都北京欢迎您");
MarkerOptions markerOptions = new MarkerOptions()
.icon(bDescriptor)//必须项,设置覆盖物图标
.position(position)//必须项,设置覆盖物位置
.draggable(true)// 可选项,设置是否允许拖拽
.alpha(0.8f)//可选项,设置透明度
.rotate(-45)//可选项,设置旋转角度
.extraInfo(bundle);//可选项,用于封装额外信息
第二步:在地图上显示覆盖物对象
Marker marker = (Marker) baiduMap.addOverlay(markerOptions);
获取额外信息
//通过marker对象获取额外的信息
Bundle extraInfo = marker.getExtraInfo();
Log.i("phz", extraInfo.getString("info"));
添加标注覆盖物集合
第一步:定义标注覆盖物集合对象
List<OverlayOptions> markerOptionsList = new ArrayList<>();
第二步:创建标注覆盖物对象,并添加到集合中
Bundle bundle1 = new Bundle();
bundle1.putString("info", "info1");
OverlayOptions options1 = new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.green_marker))
.position(new LatLng(39.625, 117.834))
.draggable(true)
.extraInfo(bundle1);
markerOptionsList.add(options1);
Bundle bundle2 = new Bundle();
bundle2.putString("info", "info2");
OverlayOptions options2 = new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.blue_marker))
.position(new LatLng(38.925, 116.034))
.draggable(true)
.extraInfo(bundle2);
markerOptionsList.add(options2);
第三步:显示覆盖物集合
baiduMap.addOverlays(markerOptionsList);
标注覆盖物
将上面两种覆盖物显示
//显示一个单一的标注覆盖物
showSingleMarkerOption();
//显示标注覆盖物集合
showListMarkerOption();
给百度地图控制器注册标注覆盖物事件
// 注册标注覆盖物点击事件监听器
baiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
//获取当前的info信息
Bundle bundle = marker.getExtraInfo();
String msg = bundle.getString("info");
Toast.makeText(
getApplicationContext(),
msg,
Toast.LENGTH_SHORT
).show();
return true;
}
});
//注册标注覆盖物拖拽事件监听器
baiduMap.setOnMarkerDragListener(new BaiduMap.OnMarkerDragListener() {
@Override
public void onMarkerDrag(Marker marker) {
//正在拖拽时触发
}
@Override
public void onMarkerDragEnd(Marker marker) {
//拖拽结束后触发
//获取拖拽结束后的位置的坐标对象
LatLng position = marker.getPosition();
Log.i("phz", "当前坐标:" + position.toString());
//获取经度和纬度值
double lat = position.latitude;//获取纬度
double lng = position.longitude;//获取经度
Toast.makeText(
getApplicationContext(),
lat + ":" + lng,//经纬度坐标字符串
Toast.LENGTH_SHORT
).show();
}
@Override
public void onMarkerDragStart(Marker marker) {
//开始拖拽前触发
}
});
点覆盖物
第一步:创建覆盖物显示位置的坐标对象(点的中心坐标)
LatLng position = new LatLng(39.915129, 116.405558);
第二步:创建覆盖物选项对象,并设置相关参数
DotOptions dotOptions = new DotOptions()
.center(position)//点的中心坐标
.color(0xaa0000ff)//点的颜色
.radius(100)//点的半径
.zIndex(5);//在Z轴方向上的位置
第三步:在地图上显示覆盖物
Dot dot = (Dot) baiduMap.addOverlay(dotOptions);
dot.setRadius(150);
多边形覆盖物
第一步:显示多边形覆盖物
List<LatLng> points = new ArrayList<>();
第二步:向集合中添加定点
points.add(new LatLng(30.975, 116.212));
points.add(new LatLng(39.527, 116.725));
points.add(new LatLng(39.625, 116.825));
points.add(new LatLng(40.012, 116.935));
第三步:创建多边形覆盖物选项对象
PolygonOptions polygonOptions = new PolygonOptions()
.points(points)//设置多边形的各个定点坐标
.fillColor(0xff00ff00)//填充颜色
.zIndex(3);
第四步:显示
baiduMap.addOverlay(polygonOptions);
几何图形覆盖物
//显示点覆盖物
showDotOptions();
//显示多边形覆盖物
showPolygonOptions();
文字覆盖物
设置文字坐标
LatLng position = new LatLng(39.914082, 116.407913);
创建文字覆盖物选项对象
TextOptions textOptions = new TextOptions()
.position(position)//文本位置坐标
.text("*东")//文本
.fontColor(0xffaa2233)//文本颜色
.bgColor(0x33333333)//背景色
.fontSize(50)//文本大小
.rotate(180)//文本旋转角度
.typeface(Typeface.DEFAULT_BOLD);
显示
baiduMap.addOverlay(textOptions);
图层覆盖物
第一步:获取图像的BitmapDescriptor对象
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(R.mipmap.ly);
第二步:创建用于显示覆盖物位置的LatLngBounds对象
LatLngBounds latLngBounds = new LatLngBounds.Builder()
.include(new LatLng(39.919829, 116.399261))//西南方坐标
.include(new LatLng(39.929125, 116.407166))//东北方坐标
.build();
第三步:创建图层覆盖物选项对象
GroundOverlayOptions groundOverlayOptions =
new GroundOverlayOptions()
.image(bitmapDescriptor)//覆盖物图像
.transparency(0.4f)//透明度
.positionFromBounds(latLngBounds)//显示位置
.zIndex(2);
第四步:显示
baiduMap.addOverlay(groundOverlayOptions);
简单形式的弹出窗覆盖物
第一步:创建弹出窗覆盖物显示的View对象
Button btn = new Button(getApplicationContext());
btn.setText("简单的弹出窗覆盖物");
btn.setTextSize(50);
btn.setTextColor(Color.DKGRAY);
btn.setBackgroundResource(R.mipmap.national_flag);
第二步:创建弹出窗覆盖物显示的经纬度坐标对象
LatLng position = new LatLng(
39.909179,
116.368337
);
第三步:创建弹出窗覆盖物对象
infoWindow1 = new InfoWindow(
btn,
position,
0
);
第四步:显示
baiduMap.showInfoWindow(infoWindow1);
复杂布局的弹出窗覆盖物
第一步:弹出窗覆盖物View对象
View view = LayoutInflater.from(getApplicationContext())
.inflate(R.layout.infowindow_layout,
null);
第二步:获取View的BitmapDescriptor对象
BitmapDescriptor bp = BitmapDescriptorFactory.fromView(view);
第三步:创建弹出窗覆盖物显示的经纬度坐标对象
LatLng position = new LatLng(
39.909179,
116.434164
);
第四步:创建Infowindow的点击事件监听器
InfoWindow.OnInfoWindowClickListener listener =
new InfoWindow.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick() {
//隐藏InfoWinwdow对象
baiduMap.hideInfoWindow();
}
};
第五步:创建InfoWindow对象
infoWindow2 = new InfoWindow(
bp,
position,
0,
listener
);
第六步:显示
baiduMap.showInfoWindow(infoWindow2);
定位
环境配置
导入库文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rKEPznF0-1610011416484)(Android综合应用.assets/image-20201105102329005.png)]
添加定位service
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote">
<intent-filter>
<action android:name="com.baidu.location.service_v5.0.0" />
</intent-filter>
</service>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-osqyKTGj-1610011416485)(Android综合应用.assets/image-20201105102413656.png)]
添加权限
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 这个权限用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 这个权限用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
使用步骤
工具类
package com.example.ch6baidumapdemo;
import com.baidu.location.BDLocation;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.utils.CoordinateConverter;
public class GlobalTool {
/**
* 将百度坐标转换成GPS坐标工具类
*
* @author fuys
*/
public final static double a = 6378245.0;
public final static double ee = 0.00669342162296594323;
// 判断坐标是否在中国
public static boolean outOfChina(BDLocation bdLocation) {
double lat = bdLocation.getLatitude();
double lon = bdLocation.getLongitude();
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
if ((119.962 < lon && lon < 121.750) && (21.586 < lat && lat < 25.463))
return true;
return false;
}
public final static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
public static BDLocation BAIDU_to_WGS84(BDLocation bdLocation) {
if (outOfChina(bdLocation)) {
return bdLocation;
}
double x = bdLocation.getLongitude() - 0.0065;
double y = bdLocation.getLatitude() - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
bdLocation.setLongitude(z * Math.cos(theta));
bdLocation.setLatitude(z * Math.sin(theta));3
return GCJ02_to_WGS84(bdLocation);
}
public static BDLocation GCJ02_to_WGS84(BDLocation bdLocation) {
if (outOfChina(bdLocation)) {
return bdLocation;
}
BDLocation tmpLocation = new BDLocation();
tmpLocation.setLatitude(bdLocation.getLatitude());
tmpLocation.setLongitude(bdLocation.getLongitude());
BDLocation tmpLatLng = WGS84_to_GCJ02(tmpLocation);
double tmpLat = 2 * bdLocation.getLatitude() - tmpLatLng.getLatitude();
double tmpLng = 2 * bdLocation.getLongitude()
- tmpLatLng.getLongitude();
for (int i = 0; i < 0; ++i) {
tmpLocation.setLatitude(bdLocation.getLatitude());
tmpLocation.setLongitude(bdLocation.getLongitude());
tmpLatLng = WGS84_to_GCJ02(tmpLocation);
tmpLat = 2 * tmpLat - tmpLatLng.getLatitude();
tmpLng = 2 * tmpLng - tmpLatLng.getLongitude();
}
bdLocation.setLatitude(tmpLat);
bdLocation.setLongitude(tmpLng);
return bdLocation;
}
public static BDLocation WGS84_to_GCJ02(BDLocation bdLocation) {
if (outOfChina(bdLocation)) {
return bdLocation;
}
double dLat = transformLat(bdLocation.getLongitude() - 105.0,
bdLocation.getLatitude() - 35.0);
double dLon = transformLon(bdLocation.getLongitude() - 105.0,
bdLocation.getLatitude() - 35.0);
double radLat = bdLocation.getLatitude() / 180.0 * Math.PI;
double magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0)
/ ((a * (1 - ee)) / (magic * sqrtMagic) * Math.PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * Math.PI);
bdLocation.setLatitude(bdLocation.getLatitude() + dLat);
bdLocation.setLongitude(bdLocation.getLongitude() + dLon);
return bdLocation;
}
public static double transformLat(double x, double y) {
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
+ 0.2 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x
* Math.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0
* Math.PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y
* Math.PI / 30.0)) * 2.0 / 3.0;
return ret;
}
public static double transformLon(double x, double y) {
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
* Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x
* Math.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0
* Math.PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x
/ 30.0 * Math.PI)) * 2.0 / 3.0;
return ret;
}
/**
* 百度api里面把GPS坐标转换成百度坐标
*/
public static LatLng transGpsToBaiduLatLng(LatLng desLatLng1){
//GPS转百度
// 将GPS设备采集的原始GPS坐标转换成百度坐标
CoordinateConverter converter = new CoordinateConverter();
converter.from(CoordinateConverter.CoordType.GPS);
// sourceLatLng待转换坐标
converter.coord(desLatLng1);
LatLng desLatLng = converter.convert();
double la = desLatLng.latitude;
double ln = desLatLng.longitude;
LatLng ll = new LatLng(la, ln);
return ll;
}
}
第一步:获取BaiduMap
MapView mpView = findViewById(R.id.mvMap);
BaiduMap baiduMap = mpView.getMap();
第二步:获取定位客户端类的对象
locClient = new LocationClient(getApplicationContext());
第三步:获取得客户端选项类的对象
LocationClient locOption = new LocationClientOption();
第四步:设置定位参数
//打开GPS
locOption.setOpenGps(true);
//设置扫描间隔时间
locOption.setScanSpan(1000);
//设置定位模式(高精度定位模式)
locOption.setLocationMode(
LocationClientOption.LocationMode.Hight_Accuracy);
//设置坐标系
locOption.setCoorType("wgs84");
//设置是否需要地址信息
locOption.setIsNeedAddress(true);
第五步:将设置的定位参数应用给定位客户端
locClient.setLocOption(locOption);
第六步:启动定位
locClient.start();
//开启图层定位
baiduMap.setMyLocationEnabled(true);
第七步:注册定位监听器,为了将得的数据显示在地图上
locClient.registerLocationListener(
new BDAbstractLocationListener() {
@Override
public void onReceiveLocation(BDLocation bdLocation) {
//获取纬度信息
double lat = bdLocation.getLatitude();
//获取经度信息
double lng = bdLocation.getLongitude();
LatLng position = new LatLng(
lat,
lng
);
//获取当前定位时间
String locTime = bdLocation.getTime();
Log.i("lww", locTime);
//转换成百度坐标
LatLng baiduLatLng = GlobalTool.transGpsToBaiduLatLng(position);
//在地图上显示当前位置
showLocPostionOnMap(baiduLatLng);
}
});
/**
* 将定位的坐标显示在地图上
* @param baiduLatLng
*/
private void showLocPostionOnMap(LatLng baiduLatLng) {
//1. 设置坐标显示的图标信息
MyLocationConfiguration config =
new MyLocationConfiguration(
MyLocationConfiguration.LocationMode.COMPASS,//显示位置罗盘态
true,//是否允许显示方向信息
BitmapDescriptorFactory.fromResource(R.mipmap.blue_marker)
);
//2. 设置显示的样式
baiduMap.setMyLocationConfiguration(config);
//设置定位数据
MyLocationData locData = new MyLocationData.Builder()
.latitude(baiduLatLng.latitude)
.longitude(baiduLatLng.longitude)
.build();
//设置定位位置
baiduMap.setMyLocationData(locData);
//3. 把地图移动到定位位置
//创建MapStatusUpdate对象
MapStatusUpdate statusUpdate =
MapStatusUpdateFactory.newLatLng(baiduLatLng);
//给地图应用当前状态更新
baiduMap.animateMapStatus(statusUpdate);
}