Android项目实战之百度地图地点签到功能
作者:江南233 发布时间:2022-09-04 09:30:47
标签:android,地点签到,百度地图
前言:先写个简单的地点签到功能,如果日后有时间细写的话,会更加好好研究一下百度地图api,做更多逻辑判断。
这里主要是调用百度地图中的场景定位中的签到场景。通过官方文档进行api集成。通过GPS的定位功能,获取地理位置,时间,用户名进行存储。之后通过日历显示历史签到记录。
效果图:
/**百度地图sdk**/
implementation files('libs/BaiduLBS_Android.jar')
/**日历选择器**/
implementation 'com.prolificinteractive:material-calendarview:1.4.3'
签到布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_ffffff"
android:orientation="vertical"
tools:context=".activity.SignInActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/sign_calendar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/color_000000"
android:textSize="18sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/check_in_area" />
<View style="@style/horizontal_line_style" />
<LinearLayout
android:id="@+id/line_sign_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
android:src="@mipmap/sign_in_address" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/sign_in_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:textColor="@color/color_000000"
android:textSize="20sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="@string/sign_in_time" />
<TextView
android:id="@+id/sign_in_time"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/sign_address"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_sign_again"
android:layout_width="120dp"
android:layout_height="40dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:background="@drawable/btn_round_border"
android:text="@string/sign_again"
android:textAllCaps="false"
android:textColor="@color/colorPrimary"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
<Button
android:id="@+id/btn_sign_in"
style="@style/style_button"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_marginTop="50dp"
android:background="@drawable/btn_negative_nomal"
android:text="@string/signIn"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
SignInActivity.java
public class SignInActivity extends BaseActivity {
@BindView(R.id.sign_calendar)
TextView signCalender;
@BindView(R.id.line_sign_result)
LinearLayout lineSignResult;
@BindView(R.id.sign_in_result)
TextView signInResult;
@BindView(R.id.sign_in_time)
TextView signInTime;
@BindView(R.id.sign_address)
TextView signAddress;
@BindView(R.id.btn_sign_in)
Button btnSignIn;
private LocationService mLocationService;
private boolean isAgain = false;
SignIn signIn = new SignIn();
MyUser myUser = BmobUser.getCurrentUser(MyUser.class);
@Override
protected int contentViewID() {
return R.layout.activity_sign_in;
}
@Override
protected void initialize() {
setTopTitle(getString(R.string.signIn), true);
setLeftBtnFinish();
setDate();
setLocation();
querySignInState();
}
/**
* 查询今日签到状态
*/
private void querySignInState() {
BmobQuery<SignIn> signInBmobQuery = new BmobQuery<SignIn>();
signInBmobQuery.addWhereEqualTo("username", myUser.getUsername());
signInBmobQuery.addWhereEqualTo("date", FormatUtils.getDateTimeString(Calendar.getInstance().getTime(), FormatUtils.template_Date));
signInBmobQuery.findObjects(new FindListener<SignIn>() {
@Override
public void done(List<SignIn> object, BmobException e) {
if (e == null) {
if (object.isEmpty()){
isAgain = false;
btnSignIn.setVisibility(View.VISIBLE);
} else {
isAgain = true;
SignIn signIn = object.get(0);
btnSignIn.setVisibility(View.GONE);
lineSignResult.setVisibility(View.VISIBLE);
signAddress.setText(signIn.getAddress());
signInTime.setText(signIn.getTime());
signInResult.setText(getString(R.string.sign_in_success));
}
} else {
isAgain = false;
}
}
});
}
private void setLocation() {
// 初始化 LocationClient
mLocationService = new LocationService(this);
// 注册监听
mLocationService.registerListener(mListener);
LocationClientOption option = mLocationService.getOption();
// 签到场景 只进行一次定位返回最接近真实位置的定位结果(定位速度可能会延迟1-3s)
option.setLocationPurpose(LocationClientOption.BDLocationPurpose.SignIn);
// 设置定位参数
mLocationService.setLocationOption(option);
}
/*****
*
* 定位结果回调,重写onReceiveLocation方法
*
*/
private BDAbstractLocationListener mListener = new BDAbstractLocationListener() {
/**
* 定位请求回调函数
*
* @param location 定位结果
*/
@Override
public void onReceiveLocation(BDLocation location) {
if (null != location && location.getLocType() != BDLocation.TypeServerError &&
location.getLocType() != BDLocation.TypeOffLineLocationFail &&
location.getLocType() != BDLocation.TypeCriteriaException) {
String address = location.getAddrStr(); //获取详细地址信息
if (!isAgain) {
saveSignIn(address);
} else {
updateSignIn(address);
}
} else {
signInResult.setText(getString(R.string.sign_in_failure));
}
}
};
private void setDate() {
String dateString = FormatUtils.getDateTimeString(Calendar.getInstance().getTime(), FormatUtils.template_Date);
String weekString = DateUtils.getDayOfWeek();
String CalendarString = dateString + " " + weekString;
signCalender.setText(CalendarString);
}
@OnClick({R.id.btn_sign_in, R.id.btn_sign_again})
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_sign_in:
signIn();
break;
case R.id.btn_sign_again:
isAgain = true;
signIn();
break;
default:
}
}
/**
* 更新签到数据
* @param address
*/
private void updateSignIn(String address) {
Calendar calendar = Calendar.getInstance();
SignIn newSignIn = new SignIn();
newSignIn.setUsername(myUser.getUsername());
newSignIn.setAddress(address);
signIn.setDate(FormatUtils.getDateTimeString(calendar.getTime(), FormatUtils.template_Date));
signIn.setTime(FormatUtils.getDateTimeString(calendar.getTime(), FormatUtils.template_Time));
newSignIn.update(signIn.getObjectId(), new UpdateListener() {
@Override
public void done(BmobException e) {
if (e == null) {
signAddress.setText(address);
signInTime.setText(FormatUtils.getDateTimeString(Calendar.getInstance().getTime(), FormatUtils.template_Time));
signInResult.setText(getString(R.string.sign_in_success));
ToastUtils.showShort(SignInActivity.this, getString(R.string.sign_in_success));
} else {
ToastUtils.showShort(SignInActivity.this, getString(R.string.sign_in_failure));
}
}
});
}
/**
* 保存签到数据
* @param address
*/
private void saveSignIn(String address) {
Calendar calendar = Calendar.getInstance();
signIn.setUsername(myUser.getUsername());
signIn.setAddress(address);
signIn.setDate(FormatUtils.getDateTimeString(calendar.getTime(), FormatUtils.template_Date));
signIn.setTime(FormatUtils.getDateTimeString(calendar.getTime(), FormatUtils.template_Time));
signIn.save(new SaveListener<String>() {
@Override
public void done(String s, BmobException e) {
if (e == null) {
btnSignIn.setVisibility(View.GONE);
lineSignResult.setVisibility(View.VISIBLE);
signAddress.setText(address);
signInTime.setText(FormatUtils.getDateTimeString(Calendar.getInstance().getTime(), FormatUtils.template_Time));
signInResult.setText(getString(R.string.sign_in_success));
ToastUtils.showShort(SignInActivity.this, getString(R.string.sign_in_success));
} else {
ToastUtils.showShort(SignInActivity.this, getString(R.string.sign_in_failure));
}
}
});
}
/**
* 签到
*/
private void signIn() {
if (mLocationService.isStart()) {
mLocationService.requestLocation();
return;
}
//签到只需调用startLocation即可
mLocationService.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mLocationService != null) {
mLocationService.unregisterListener(mListener);
mLocationService.stop();
}
}
}
历史签到布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_ffffff"
tools:context=".activity.MySignInActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical">
<com.prolificinteractive.materialcalendarview.MaterialCalendarView
android:id="@+id/materialCalendarView_sign_in"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="@color/white"
android:clipChildren="false"
app:mcv_calendarMode="month"
app:mcv_dateTextAppearance="@style/MaterialCalendarTextStyelNormal"
app:mcv_firstDayOfWeek="sunday"
app:mcv_selectionColor="#D203A9F4"
app:mcv_showOtherDates="all"
app:mcv_tileSize="match_parent"
app:mcv_tileWidth="match_parent" />
<View
style="@style/horizontal_line_style"/>
<LinearLayout
android:id="@+id/line_my_sign_in"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:visibility="gone"
android:orientation="horizontal">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="5dp"
android:src="@mipmap/sign_in_address" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_000000"
android:textSize="18sp"
android:text="@string/sign_in_time"/>
<TextView
android:id="@+id/my_sign_in_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_000000"
android:textSize="18sp"
android:layout_marginLeft="5dp"/>
<TextView
android:id="@+id/my_sign_in_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_000000"
android:textSize="18sp"
android:layout_marginLeft="5dp"/>
</LinearLayout>
<TextView
android:id="@+id/my_sign_in_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
MySignInActivity.java
public class MySignInActivity extends BaseActivity implements OnDateSelectedListener {
@BindView(R.id.my_sign_in_date)
TextView mySignInDate;
@BindView(R.id.my_sign_in_time)
TextView mySignInTime;
@BindView(R.id.my_sign_in_address)
TextView mySignInAddress;
@BindView(R.id.line_my_sign_in)
LinearLayout lineMySignIn;
@BindView(R.id.materialCalendarView_sign_in)
MaterialCalendarView widget;
MyUser myUser = BmobUser.getCurrentUser(MyUser.class);
private List<CalendarDay> calendarDays = new ArrayList<>();
@Override
protected int contentViewID() {
return R.layout.activity_my_sign_in;
}
@Override
protected void initialize() {
setTopTitle(getString(R.string.my_sign_in), true);
setLeftBtnFinish();
widget.setSelectedDate(CalendarDay.today());
widget.state().edit().setMaximumDate(CalendarDay.today()).commit();
widget.setOnDateChangedListener(this);
initDate();
querySignInState(Calendar.getInstance());
}
private void initDate() {
BmobQuery<SignIn> signInBmobQuery = new BmobQuery<SignIn>();
signInBmobQuery.addWhereEqualTo("username", myUser.getUsername());
signInBmobQuery.findObjects(new FindListener<SignIn>() {
@Override
public void done(List<SignIn> object, BmobException e) {
if (e == null) {
if (!object.isEmpty()) {
for (SignIn signIn : object) {
Date date = DateUtils.strToDate(signIn.getDate() + " " + signIn.getTime());
calendarDays.add(CalendarDay.from(date));
}
widget.addDecorator(new EventDecorator(ContextCompat.getColor(MySignInActivity.this, R.color.color_1396aa), calendarDays));
}
} else {
LogUtils.e(e.getMessage());
ToastUtils.showShort(MySignInActivity.this, getString(R.string.query_failure));
}
}
});
}
@Override
public void onDateSelected(@NonNull MaterialCalendarView widget, @NonNull CalendarDay date, boolean selected) {
querySignInState(date.getCalendar());
}
private void querySignInState(Calendar calendar) {
BmobQuery<SignIn> signInBmobQuery = new BmobQuery<SignIn>();
signInBmobQuery.addWhereEqualTo("username", myUser.getUsername());
signInBmobQuery.addWhereEqualTo("date", FormatUtils.getDateTimeString(calendar.getTime(), FormatUtils.template_Date));
signInBmobQuery.findObjects(new FindListener<SignIn>() {
@Override
public void done(List<SignIn> object, BmobException e) {
if (e == null) {
if (!object.isEmpty()) {
lineMySignIn.setVisibility(View.VISIBLE);
SignIn signIn = object.get(0);
mySignInDate.setText(signIn.getDate());
mySignInTime.setText(signIn.getTime());
mySignInAddress.setText(signIn.getAddress());
} else {
lineMySignIn.setVisibility(View.GONE);
}
} else {
ToastUtils.showShort(MySignInActivity.this, getString(R.string.query_failure));
}
}
});
}
}
日历小圆点装饰,重写 DayViewDecorator
public class EventDecorator implements DayViewDecorator {
private int color;
private HashSet<CalendarDay> dates;
public EventDecorator(int color, Collection<CalendarDay> dates) {
this.color = color;
this.dates = new HashSet<>(dates);
}
@Override
public boolean shouldDecorate(CalendarDay day) {
return dates.contains(day);
}
@Override
public void decorate(DayViewFacade view) {
view.addSpan(new DotSpan(7, color));
}
}
来源:https://blog.csdn.net/qq_39131246/article/details/105397002


猜你喜欢
- @Autowired注解在抽象类中失效最近在工作中遇到这个问题,在抽象类中使用Autowired这个注解,注入mybatis的dao时,总是
- 在这里,我们将用到finish(),简单介绍一下它的使用:finish()官方解析:Call this when your activity
- 前言随着微软对C#不断发展和更新,C#中对于数组操作的方式也变得越来越多样化。以往要实现过滤数组中的空字符串,都是需要实行循环的方式来排除和
- 最近正式入坑Flutter,首先从环境搭建开始,看了网上好多关于Windows环境搭建的资料,基本都是按官方文档写的,看完的感受是,还不如直
- 这篇文章主要介绍了java多线程加锁以及Condition类的使用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参
- 第一步:输入15个整数第二步:对这15个数进行排序第三部:输入一个数,在后在排好序的数中进行折半查找,判断该数的位置实现代码如下:方法一:选
- 自动登录是我们在软件开发时一个非常常见的功能,例如我们登录 QQ 邮箱:很多网站我们在登录的时候都会看到类似的选项,毕竟总让用户输入用户名密
- SpringBoot 2.1.4 错误处理机制springboot的自动配置中帮我们配置了相关的错误处理组件,例如访问一个不存在的页面,就会
- 1、效果展示2、布局文件<?xml version="1.0" encoding="utf-8"
- synchronized关键字顾名思义,是用于同步互斥的作用的。这里精简的记一下它的使用方法以及意义:1. 当synchronized修饰
- 本文介绍了Android Studio 超级简单的打包生成apk,分享给大家,也给自己留个笔记。为什么要打包:apk文件就是一个包,打包就是
- 1.概述最近一直都在带实习生做项目,发现自己好久没有写博客了,这几天更新会比较频繁,今天玩QQ的时候发现QQ主页菜单滑动效果早就变了,实在忍
- 前言在开发Wpf/SL应用时,经常会遇到不同页面和窗体之间的参数传递的问题。对于这类问题,我们一般通过事件实现数据传递,也可以定义全局静态变
- 问题org.apache.ibatis.binding.BindingException: Invalid bound statement
- Spring AOP复杂的日志记录(自定义注解)做项目中,业务逻辑要求只要对数据库数据进行改动的都需要记录日志(增删改),记录的内容有操作者
- 1. 启用AOPa. 在类上添加@Aspect注解b. 注入该类, 可以使用@Component进行注入到Spring容器中2. 通过Poi
- 一、题目描述题目:同步锁出现的目的就是为了解决多线程安全问题。同步锁的几种方式synchronized1、同步代码块2、同步方法jdk1.5
- C#实现委托namespace Delegate{ delegate void DGSayiHi(string n
- 1、SpringSecurity 本质是一个过滤器链SpringSecurity 采用的是责任链的设计模式,它有一条很长的过滤器链。现在对这
- 本文实例讲述了Android4.0平板开发之隐藏底部任务栏的方法。分享给大家供大家参考,具体如下:getWindow().getDecorV