Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.baitrading.bes.ui;
- import android.os.Bundle;
- import android.text.InputType;
- import android.util.Log;
- import android.view.View;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.view.animation.LinearInterpolator;
- import android.widget.ImageView;
- import android.widget.TextView;
- import com.baitrading.bes.AppConfig;
- import com.baitrading.bes.Constant;
- import com.baitrading.bes.R;
- import com.baitrading.bes.SyncUtil;
- import com.baitrading.bes.common.LLog;
- import com.baitrading.bes.common.OttoBus;
- import com.baitrading.bes.common.events.BleOptEvent;
- import com.baitrading.bes.common.events.RssiUpdateEvent;
- import com.baitrading.bes.entity.AntiLostSettings;
- import com.baitrading.bes.ui.view.InfoDialog;
- import com.baitrading.bes.ui.view.TitleBar;
- import com.baitrading.bes.util.Prefs;
- import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
- import com.squareup.otto.Subscribe;
- import com.suke.widget.SwitchButton;
- import org.angmarch.views.NiceSpinner;
- import java.text.DecimalFormat;
- import java.util.Arrays;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Timer;
- import java.util.TimerTask;
- import butterknife.BindView;
- import butterknife.ButterKnife;
- /**
- * @author Administrator
- */
- public class LuggageGuardActivity extends BaseActivity {
- public static final String TAG = LuggageGuardActivity.class.getSimpleName();
- private static final String DOT = ".";
- @BindView(R.id.distance_state_img)
- ImageView distanceStateImg;
- @BindView(R.id.finding_state_txt)
- TextView findingStateTxt;
- @BindView(R.id.anti_lost_level_spinner)
- NiceSpinner antiLostLevelSpinner;
- @BindView(R.id.alarm_mode_spinner)
- NiceSpinner alarmModeSpinner;
- @BindView(R.id.help_center_view)
- View helpCenterView;
- @BindView(R.id.distance_txt)
- TextView distanceTxt;
- @BindView(R.id.anti_lost_txt)
- TextView antiLostTxt;
- @BindView(R.id.title_bar)
- TitleBar titleBar;
- @BindView(R.id.search_switch)
- SwitchButton mSearchSwitch;
- @BindView(R.id.luggage_guard_switch)
- SwitchButton mLuggageGuardSwitch;
- private Animation operatingAnim;
- /**
- * 最后一次读取到的 rssi ,用以比较来发现远近的变化
- */
- private int lastRSSI;
- /**
- * 根据 rssi 查找设备,变远还是走近
- */
- private boolean isSearching = false;
- /**
- * 防丢失使能状态,根据 rssi 算出距离
- */
- private boolean antiLostEnable = false;
- /**
- * 正在读取 rssi ,查找设备 或 防丢失,其中一个功能开启了,则这个是正在读取
- */
- private boolean readingRssi;
- private Timer mReadRssiTimer;
- private int antiLostLevel;
- private int alarmType;
- private InfoDialog alertDialog;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_luggage_guard);
- ButterKnife.bind(this);
- OttoBus.getInstance().register(this);
- titleBar.setOnTitleBarClickListener(new TitleBar.OnTitleBarClickListener() {
- @Override
- public void onLeftClick() {
- onBackPressed();
- }
- @Override
- public void onTitleClick() {
- }
- @Override
- public void onRightClick() {
- }
- });
- operatingAnim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.alpha_distance_scan);
- operatingAnim.setInterpolator(new LinearInterpolator());
- final List<String> levelSet = new LinkedList<>(Arrays.asList("Low", "Normal", "High"));
- antiLostLevelSpinner.attachDataSource(levelSet);
- antiLostLevelSpinner.addOnItemClickListener((parent, view, position, id) -> {
- // 调节防丢失的灵敏度
- AntiLostSettings.setAntiLostLevel(getApplicationContext(), position);
- });
- final List<String> modeSet = new LinkedList<>(Arrays.asList(getString(R.string.vibrate_only), getString(R.string.alarm_only), getString(R.string.vibrate_and_alarm)));
- alarmModeSpinner.attachDataSource(modeSet);
- alarmModeSpinner.addOnItemClickListener((parent, view, position, id) -> {
- AntiLostSettings.setAntiLostAlarmType(getApplicationContext(), position);
- });
- mSearchSwitch.setOnCheckedChangeListener((view, isChecked) -> {
- // 点击按钮切换搜索状态
- isSearching = isChecked;
- if (isSearching) {
- // 开启搜索功能,如果当前没有在读取 rssi ,那么开启之
- if (!readingRssi) {
- startReadRssi();
- }
- } else {
- // 关闭搜索设备功能,如果此时没有开启防丢失,那么就不再需要读取 rssi,关闭之
- if (!antiLostEnable) {
- stopReadRssi();
- }
- }
- });
- mLuggageGuardSwitch.setOnCheckedChangeListener((view, isChecked) -> {
- antiLostEnable = isChecked;
- Prefs.with(getApplicationContext()).writeBoolean(Constant.KEY_ANTI_LOST_ALARM_ENABLE, antiLostEnable);
- if (antiLostEnable) {
- // 开启防丢失功能,如果此时没有在读取 rssi ,则开启之
- Log.d(TAG, "允许了 anti lost");
- if (!readingRssi) {
- startReadRssi();
- }
- } else {
- // 关闭防丢失功能,如果当前是没有在搜索设备,那么关闭之
- Log.d(TAG, "禁止了 anti lost");
- if (!isSearching) {
- readRssiCount = 0;
- rssiTotal = 0;
- stopReadRssi();
- }
- }
- });
- }
- @Override
- protected void onResume() {
- super.onResume();
- // 是否已经开启了防丢失
- antiLostEnable = Prefs.with(getApplicationContext()).readBoolean(Constant.KEY_ANTI_LOST_ALARM_ENABLE, false);
- mLuggageGuardSwitch.setChecked(antiLostEnable);
- antiLostLevel = AntiLostSettings.getAntiLostLevel(getApplicationContext());
- antiLostLevelSpinner.setSelectedIndex(antiLostLevel);
- alarmType = AntiLostSettings.getAntiLostAlarmType(getApplicationContext());
- alarmModeSpinner.setSelectedIndex(alarmType);
- mSearchSwitch.setChecked(isSearching);
- // 两个功能中, 有一个开启了,那就开启读取 rssi
- if (isSearching || antiLostEnable) {
- startReadRssi();
- }
- distanceNormal();
- }
- @Override
- public void onPause() {
- super.onPause();
- }
- @Override
- public void onStop() {
- super.onStop();
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- stopReadRssi();
- OttoBus.getInstance().unregister(this);
- }
- private void startReadRssi() {
- if (AppConfig.isDebug) {
- toast("startReadRssi");
- }
- // 开始读取 rssi ,发送指令让设备不再休眠
- SyncUtil.currentNoSleep = true;
- OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.SEND_COMMAND));
- readingRssi = true;
- if (mReadRssiTimer != null) {
- mReadRssiTimer.cancel();
- }
- mReadRssiTimer = new Timer();
- mReadRssiTimer.schedule(new ReadRssiTask(), 1000, 100);
- }
- private void stopReadRssi() {
- if (AppConfig.isDebug) {
- toast("stopReadRssi");
- }
- // 可以休眠了
- readRssiCount = 0;
- rssiTotal = 0;
- SyncUtil.currentNoSleep = false;
- OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.SEND_COMMAND));
- readingRssi = false;
- if (mReadRssiTimer != null) {
- mReadRssiTimer.cancel();
- }
- distanceNormal();
- }
- public class ReadRssiTask extends TimerTask {
- @Override
- public void run() {
- runOnUiThread(() -> {
- OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.READ_RSSI));
- });
- }
- }
- @Subscribe
- public void onRssiUpdateListener(RssiUpdateEvent event) {
- rssiUpdate(event.getRssi());
- }
- /**
- * 当前读取了多少次 rssi
- */
- private int readRssiCount = 0;
- /**
- * 读取周期内的 rssi 总和
- */
- private int rssiTotal = 0;
- /**
- * 读取几次为一个统计周期
- */
- private int readPeriod = 15;
- public void rssiUpdate(int rssi) {
- // 累加
- readRssiCount += 1;
- rssiTotal += rssi;
- if (readRssiCount % readPeriod != 0) {
- // 没到一个周期,不处理
- return;
- } else {
- // 累计够了次数,则计算平均 rssi ,并清 0 rssiTotal
- rssi = rssiTotal / readPeriod;
- rssiTotal = 0;
- // 记录第一次统计的 RSSI,设置为 A 值,用于计算距离
- if (readRssiCount < 19) {
- SyncUtil.RSSI_A = Math.abs(rssi);
- LLog.e("RSSI_A=", SyncUtil.RSSI_A + "");
- }
- }
- // 计算距离
- double distance = getDistance(rssi);
- // 格式化打印日志
- DecimalFormat df = new DecimalFormat("#.00");
- String d = df.format(distance);
- if (d.startsWith(DOT)) {
- d = "0" + d;
- }
- LLog.e(TAG, "rssi:" + rssi + " ; distance: " + d + "m");
- // 如果开启了距离搜索
- if (isSearching) {
- // 两次变化的 rssi 超过 5 才会有比较的意义
- if (Math.abs(Math.abs(rssi) - Math.abs(lastRSSI)) > 5) {
- if (Math.abs(rssi) > Math.abs(lastRSSI)) {
- distanceFarther();
- } else {
- distanceCloser();
- }
- // 将上一次有效的比较值,作为上一次的值,用于下次比较
- lastRSSI = rssi;
- }
- }
- // 开启了防丢失
- if (antiLostEnable) {
- // 判断距离,作出告警
- int antiLostLevel = AntiLostSettings.getAntiLostLevel(getApplicationContext());
- int antiLostDistance = AntiLostSettings.getDistanceByLevel(antiLostLevel);
- if (distance > antiLostDistance) {
- LLog.e(TAG, "防丢失告警");
- if (alertDialog != null && alertDialog.isShowing()) {
- Log.d(TAG, "正在 alarm,不再显示第二次");
- return;
- }
- toast("Luggage Guard");
- showNotification(getApplicationContext(), "Luggage Guard", "Check your Luggage");
- if (alarmModeSpinner.getSelectedIndex() == 0) {
- vibrate(4);
- } else if (alarmModeSpinner.getSelectedIndex() == 1) {
- ringStart();
- SyncUtil.currentFmqLongBuzzer = true;
- } else {
- vibrate(4);
- ringStart();
- SyncUtil.currentFmqLongBuzzer = true;
- }
- // 长鸣告警
- OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.SEND_COMMAND));
- SyncUtil.currentFmqLongBuzzer = false;
- alertDialog = new InfoDialog(this);
- alertDialog.show();
- alertDialog.setTitleTxt("ALERT");
- alertDialog.setMessageTxt("Check Your Luggage");
- alertDialog.setInfoImg(R.drawable.ic_dialog_lost);
- alertDialog.setCenterClickListener("Close", v -> {
- alertDialog.dismiss();
- if (alarmModeSpinner.getSelectedIndex() == 0) {
- vibrateStop();
- } else if (alarmModeSpinner.getSelectedIndex() == 1) {
- ringStop();
- } else {
- vibrateStop();
- ringStop();
- }
- SyncUtil.currentFmqLongBuzzer = false;
- OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.SEND_COMMAND));
- mLuggageGuardSwitch.setChecked(false);
- });
- }
- }
- }
- /**
- * RSSI 转成距离:米
- *
- * @param rssi
- * @return 距离/米
- */
- private double getDistance(int rssi) {
- double distance = 0;
- double absRSSI = Math.abs(rssi);
- double a = SyncUtil.RSSI_A;
- double n = SyncUtil.RSSI_n;
- double pow = (absRSSI - a) / (10 * n);
- distance = Math.pow(10, pow);
- return distance;
- }
- private void distanceNormal() {
- distanceStateImg.setVisibility(View.INVISIBLE);
- findingStateTxt.setText("");
- }
- private void distanceCloser() {
- distanceStateImg.setVisibility(View.VISIBLE);
- distanceStateImg.setImageResource(R.drawable.ic_closer);
- distanceStateImg.setAnimation(operatingAnim);
- operatingAnim.start();
- findingStateTxt.setText("");
- }
- private void distanceFarther() {
- distanceStateImg.setVisibility(View.VISIBLE);
- distanceStateImg.setImageResource(R.drawable.ic_farther);
- distanceStateImg.setAnimation(operatingAnim);
- operatingAnim.start();
- findingStateTxt.setText("");
- }
- public void changeA(View view) {
- final QMUIDialog.EditTextDialogBuilder builder = new QMUIDialog.EditTextDialogBuilder(this);
- builder.setTitle("当前 A 值")
- .setPlaceholder("A")
- .setInputType(InputType.TYPE_CLASS_NUMBER)
- .addAction("cancel", (dialog, index) -> dialog.dismiss())
- .addAction("ok", (dialog, index) -> {
- CharSequence text = builder.getEditText().getText();
- if (text != null && text.length() > 0) {
- try {
- float a = Float.parseFloat(text.toString());
- SyncUtil.RSSI_A = a;
- dialog.dismiss();
- } catch (NumberFormatException e) {
- toast("must input number");
- }
- } else {
- toast("year can't empty");
- }
- })
- .show();
- builder.getEditText().setText(SyncUtil.RSSI_A + "");
- }
- public void changeN(View view) {
- final QMUIDialog.EditTextDialogBuilder builder = new QMUIDialog.EditTextDialogBuilder(this);
- builder.setTitle("当前 n 值")
- .setPlaceholder("n")
- .setInputType(InputType.TYPE_CLASS_NUMBER)
- .addAction("cancel", (dialog, index) -> dialog.dismiss())
- .addAction("ok", (dialog, index) -> {
- CharSequence text = builder.getEditText().getText();
- if (text != null && text.length() > 0) {
- try {
- float n = Float.parseFloat(text.toString());
- SyncUtil.RSSI_n = n;
- dialog.dismiss();
- } catch (NumberFormatException e) {
- toast("must input number");
- }
- } else {
- toast("year can't empty");
- }
- })
- .show();
- builder.getEditText().setText(SyncUtil.RSSI_n + "");
- }
- }
Add Comment
Please, Sign In to add comment