Android实战 地点签到功能(百度地图)

前言:先写个简单的地点签到功能,如果日后有时间细写的话,会更加好好研究一下百度地图api,做更多逻辑判断。

定位签到功能是基于百度地图API开发的,主要应用部分是场景定位中的签到场景。首页点击签到提示,进入签到界面,判断逻辑先查询数据中是否有今日签到数据,如果有直接显示签到成功界面。否则显示签到按钮,点击签到按钮,通过百度地图API获取定位的详细地址,将数据存入数据库,显示签到成功。

历史签到界面是通过日历的形式显示用户所有的签到记录。查询用户所有签到数据,如果有数据的日期,则有圆点装饰。点击日期显示当日的签到记录,根据日期查询数据库。

效果图:

    

    /**百度地图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 = 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;
                    btnSignIn.setVisibility(View.VISIBLE);
                }
            }
        });
    }

    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);
        newSignIn.setDate(FormatUtils.getDateTimeString(calendar.getTime(), FormatUtils.template_Date));
        newSignIn.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));
  }
}

 

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江南:-)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值