Guest User

Untitled

a guest
Jul 16th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.33 KB | None | 0 0
  1. package com.baitrading.bes.ui;
  2.  
  3. import android.os.Bundle;
  4. import android.text.InputType;
  5. import android.util.Log;
  6. import android.view.View;
  7. import android.view.animation.Animation;
  8. import android.view.animation.AnimationUtils;
  9. import android.view.animation.LinearInterpolator;
  10. import android.widget.ImageView;
  11. import android.widget.TextView;
  12.  
  13. import com.baitrading.bes.AppConfig;
  14. import com.baitrading.bes.Constant;
  15. import com.baitrading.bes.R;
  16. import com.baitrading.bes.SyncUtil;
  17. import com.baitrading.bes.common.LLog;
  18. import com.baitrading.bes.common.OttoBus;
  19. import com.baitrading.bes.common.events.BleOptEvent;
  20. import com.baitrading.bes.common.events.RssiUpdateEvent;
  21. import com.baitrading.bes.entity.AntiLostSettings;
  22. import com.baitrading.bes.ui.view.InfoDialog;
  23. import com.baitrading.bes.ui.view.TitleBar;
  24. import com.baitrading.bes.util.Prefs;
  25. import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
  26. import com.squareup.otto.Subscribe;
  27. import com.suke.widget.SwitchButton;
  28.  
  29. import org.angmarch.views.NiceSpinner;
  30.  
  31. import java.text.DecimalFormat;
  32. import java.util.Arrays;
  33. import java.util.LinkedList;
  34. import java.util.List;
  35. import java.util.Timer;
  36. import java.util.TimerTask;
  37.  
  38. import butterknife.BindView;
  39. import butterknife.ButterKnife;
  40.  
  41. /**
  42. * @author Administrator
  43. */
  44. public class LuggageGuardActivity extends BaseActivity {
  45.  
  46. public static final String TAG = LuggageGuardActivity.class.getSimpleName();
  47. private static final String DOT = ".";
  48.  
  49. @BindView(R.id.distance_state_img)
  50. ImageView distanceStateImg;
  51. @BindView(R.id.finding_state_txt)
  52. TextView findingStateTxt;
  53. @BindView(R.id.anti_lost_level_spinner)
  54. NiceSpinner antiLostLevelSpinner;
  55. @BindView(R.id.alarm_mode_spinner)
  56. NiceSpinner alarmModeSpinner;
  57. @BindView(R.id.help_center_view)
  58. View helpCenterView;
  59. @BindView(R.id.distance_txt)
  60. TextView distanceTxt;
  61. @BindView(R.id.anti_lost_txt)
  62. TextView antiLostTxt;
  63. @BindView(R.id.title_bar)
  64. TitleBar titleBar;
  65. @BindView(R.id.search_switch)
  66. SwitchButton mSearchSwitch;
  67. @BindView(R.id.luggage_guard_switch)
  68. SwitchButton mLuggageGuardSwitch;
  69.  
  70. private Animation operatingAnim;
  71.  
  72. /**
  73. * 最后一次读取到的 rssi ,用以比较来发现远近的变化
  74. */
  75. private int lastRSSI;
  76.  
  77. /**
  78. * 根据 rssi 查找设备,变远还是走近
  79. */
  80. private boolean isSearching = false;
  81.  
  82. /**
  83. * 防丢失使能状态,根据 rssi 算出距离
  84. */
  85. private boolean antiLostEnable = false;
  86.  
  87. /**
  88. * 正在读取 rssi ,查找设备 或 防丢失,其中一个功能开启了,则这个是正在读取
  89. */
  90. private boolean readingRssi;
  91.  
  92. private Timer mReadRssiTimer;
  93. private int antiLostLevel;
  94. private int alarmType;
  95. private InfoDialog alertDialog;
  96.  
  97. @Override
  98. protected void onCreate(Bundle savedInstanceState) {
  99. super.onCreate(savedInstanceState);
  100. setContentView(R.layout.activity_luggage_guard);
  101. ButterKnife.bind(this);
  102. OttoBus.getInstance().register(this);
  103. titleBar.setOnTitleBarClickListener(new TitleBar.OnTitleBarClickListener() {
  104. @Override
  105. public void onLeftClick() {
  106. onBackPressed();
  107. }
  108.  
  109. @Override
  110. public void onTitleClick() {
  111.  
  112. }
  113.  
  114. @Override
  115. public void onRightClick() {
  116.  
  117. }
  118. });
  119. operatingAnim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.alpha_distance_scan);
  120. operatingAnim.setInterpolator(new LinearInterpolator());
  121.  
  122. final List<String> levelSet = new LinkedList<>(Arrays.asList("Low", "Normal", "High"));
  123. antiLostLevelSpinner.attachDataSource(levelSet);
  124. antiLostLevelSpinner.addOnItemClickListener((parent, view, position, id) -> {
  125. // 调节防丢失的灵敏度
  126. AntiLostSettings.setAntiLostLevel(getApplicationContext(), position);
  127. });
  128. final List<String> modeSet = new LinkedList<>(Arrays.asList(getString(R.string.vibrate_only), getString(R.string.alarm_only), getString(R.string.vibrate_and_alarm)));
  129. alarmModeSpinner.attachDataSource(modeSet);
  130. alarmModeSpinner.addOnItemClickListener((parent, view, position, id) -> {
  131. AntiLostSettings.setAntiLostAlarmType(getApplicationContext(), position);
  132. });
  133.  
  134. mSearchSwitch.setOnCheckedChangeListener((view, isChecked) -> {
  135. // 点击按钮切换搜索状态
  136. isSearching = isChecked;
  137. if (isSearching) {
  138. // 开启搜索功能,如果当前没有在读取 rssi ,那么开启之
  139. if (!readingRssi) {
  140. startReadRssi();
  141. }
  142. } else {
  143. // 关闭搜索设备功能,如果此时没有开启防丢失,那么就不再需要读取 rssi,关闭之
  144. if (!antiLostEnable) {
  145. stopReadRssi();
  146. }
  147. }
  148. });
  149.  
  150. mLuggageGuardSwitch.setOnCheckedChangeListener((view, isChecked) -> {
  151. antiLostEnable = isChecked;
  152. Prefs.with(getApplicationContext()).writeBoolean(Constant.KEY_ANTI_LOST_ALARM_ENABLE, antiLostEnable);
  153. if (antiLostEnable) {
  154. // 开启防丢失功能,如果此时没有在读取 rssi ,则开启之
  155. Log.d(TAG, "允许了 anti lost");
  156. if (!readingRssi) {
  157. startReadRssi();
  158. }
  159. } else {
  160. // 关闭防丢失功能,如果当前是没有在搜索设备,那么关闭之
  161. Log.d(TAG, "禁止了 anti lost");
  162. if (!isSearching) {
  163. readRssiCount = 0;
  164. rssiTotal = 0;
  165. stopReadRssi();
  166. }
  167. }
  168. });
  169. }
  170.  
  171. @Override
  172. protected void onResume() {
  173. super.onResume();
  174.  
  175. // 是否已经开启了防丢失
  176. antiLostEnable = Prefs.with(getApplicationContext()).readBoolean(Constant.KEY_ANTI_LOST_ALARM_ENABLE, false);
  177. mLuggageGuardSwitch.setChecked(antiLostEnable);
  178.  
  179. antiLostLevel = AntiLostSettings.getAntiLostLevel(getApplicationContext());
  180. antiLostLevelSpinner.setSelectedIndex(antiLostLevel);
  181. alarmType = AntiLostSettings.getAntiLostAlarmType(getApplicationContext());
  182. alarmModeSpinner.setSelectedIndex(alarmType);
  183.  
  184. mSearchSwitch.setChecked(isSearching);
  185.  
  186. // 两个功能中, 有一个开启了,那就开启读取 rssi
  187. if (isSearching || antiLostEnable) {
  188. startReadRssi();
  189. }
  190. distanceNormal();
  191. }
  192.  
  193. @Override
  194. public void onPause() {
  195. super.onPause();
  196. }
  197.  
  198. @Override
  199. public void onStop() {
  200. super.onStop();
  201. }
  202.  
  203. @Override
  204. public void onDestroy() {
  205. super.onDestroy();
  206. stopReadRssi();
  207. OttoBus.getInstance().unregister(this);
  208. }
  209.  
  210. private void startReadRssi() {
  211. if (AppConfig.isDebug) {
  212. toast("startReadRssi");
  213. }
  214. // 开始读取 rssi ,发送指令让设备不再休眠
  215. SyncUtil.currentNoSleep = true;
  216. OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.SEND_COMMAND));
  217. readingRssi = true;
  218. if (mReadRssiTimer != null) {
  219. mReadRssiTimer.cancel();
  220. }
  221. mReadRssiTimer = new Timer();
  222. mReadRssiTimer.schedule(new ReadRssiTask(), 1000, 100);
  223. }
  224.  
  225. private void stopReadRssi() {
  226. if (AppConfig.isDebug) {
  227. toast("stopReadRssi");
  228. }
  229. // 可以休眠了
  230. readRssiCount = 0;
  231. rssiTotal = 0;
  232. SyncUtil.currentNoSleep = false;
  233. OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.SEND_COMMAND));
  234. readingRssi = false;
  235. if (mReadRssiTimer != null) {
  236. mReadRssiTimer.cancel();
  237. }
  238. distanceNormal();
  239. }
  240.  
  241. public class ReadRssiTask extends TimerTask {
  242. @Override
  243. public void run() {
  244. runOnUiThread(() -> {
  245. OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.READ_RSSI));
  246. });
  247. }
  248. }
  249.  
  250. @Subscribe
  251. public void onRssiUpdateListener(RssiUpdateEvent event) {
  252. rssiUpdate(event.getRssi());
  253. }
  254.  
  255. /**
  256. * 当前读取了多少次 rssi
  257. */
  258. private int readRssiCount = 0;
  259. /**
  260. * 读取周期内的 rssi 总和
  261. */
  262. private int rssiTotal = 0;
  263. /**
  264. * 读取几次为一个统计周期
  265. */
  266. private int readPeriod = 15;
  267.  
  268.  
  269. public void rssiUpdate(int rssi) {
  270. // 累加
  271. readRssiCount += 1;
  272. rssiTotal += rssi;
  273. if (readRssiCount % readPeriod != 0) {
  274. // 没到一个周期,不处理
  275. return;
  276. } else {
  277. // 累计够了次数,则计算平均 rssi ,并清 0 rssiTotal
  278. rssi = rssiTotal / readPeriod;
  279. rssiTotal = 0;
  280.  
  281. // 记录第一次统计的 RSSI,设置为 A 值,用于计算距离
  282. if (readRssiCount < 19) {
  283. SyncUtil.RSSI_A = Math.abs(rssi);
  284. LLog.e("RSSI_A=", SyncUtil.RSSI_A + "");
  285. }
  286. }
  287.  
  288. // 计算距离
  289. double distance = getDistance(rssi);
  290.  
  291. // 格式化打印日志
  292. DecimalFormat df = new DecimalFormat("#.00");
  293. String d = df.format(distance);
  294. if (d.startsWith(DOT)) {
  295. d = "0" + d;
  296. }
  297. LLog.e(TAG, "rssi:" + rssi + " ; distance: " + d + "m");
  298.  
  299. // 如果开启了距离搜索
  300. if (isSearching) {
  301. // 两次变化的 rssi 超过 5 才会有比较的意义
  302. if (Math.abs(Math.abs(rssi) - Math.abs(lastRSSI)) > 5) {
  303. if (Math.abs(rssi) > Math.abs(lastRSSI)) {
  304. distanceFarther();
  305. } else {
  306. distanceCloser();
  307. }
  308. // 将上一次有效的比较值,作为上一次的值,用于下次比较
  309. lastRSSI = rssi;
  310. }
  311. }
  312.  
  313. // 开启了防丢失
  314. if (antiLostEnable) {
  315. // 判断距离,作出告警
  316. int antiLostLevel = AntiLostSettings.getAntiLostLevel(getApplicationContext());
  317. int antiLostDistance = AntiLostSettings.getDistanceByLevel(antiLostLevel);
  318. if (distance > antiLostDistance) {
  319. LLog.e(TAG, "防丢失告警");
  320.  
  321. if (alertDialog != null && alertDialog.isShowing()) {
  322. Log.d(TAG, "正在 alarm,不再显示第二次");
  323. return;
  324. }
  325.  
  326. toast("Luggage Guard");
  327. showNotification(getApplicationContext(), "Luggage Guard", "Check your Luggage");
  328. if (alarmModeSpinner.getSelectedIndex() == 0) {
  329. vibrate(4);
  330. } else if (alarmModeSpinner.getSelectedIndex() == 1) {
  331. ringStart();
  332. SyncUtil.currentFmqLongBuzzer = true;
  333. } else {
  334. vibrate(4);
  335. ringStart();
  336. SyncUtil.currentFmqLongBuzzer = true;
  337. }
  338. // 长鸣告警
  339. OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.SEND_COMMAND));
  340.  
  341. SyncUtil.currentFmqLongBuzzer = false;
  342.  
  343. alertDialog = new InfoDialog(this);
  344. alertDialog.show();
  345. alertDialog.setTitleTxt("ALERT");
  346. alertDialog.setMessageTxt("Check Your Luggage");
  347. alertDialog.setInfoImg(R.drawable.ic_dialog_lost);
  348. alertDialog.setCenterClickListener("Close", v -> {
  349. alertDialog.dismiss();
  350. if (alarmModeSpinner.getSelectedIndex() == 0) {
  351. vibrateStop();
  352. } else if (alarmModeSpinner.getSelectedIndex() == 1) {
  353. ringStop();
  354. } else {
  355. vibrateStop();
  356. ringStop();
  357. }
  358.  
  359. SyncUtil.currentFmqLongBuzzer = false;
  360. OttoBus.getInstance().post(new BleOptEvent(BleOptEvent.SEND_COMMAND));
  361.  
  362. mLuggageGuardSwitch.setChecked(false);
  363. });
  364. }
  365. }
  366. }
  367.  
  368. /**
  369. * RSSI 转成距离:米
  370. *
  371. * @param rssi
  372. * @return 距离/米
  373. */
  374. private double getDistance(int rssi) {
  375. double distance = 0;
  376. double absRSSI = Math.abs(rssi);
  377. double a = SyncUtil.RSSI_A;
  378. double n = SyncUtil.RSSI_n;
  379. double pow = (absRSSI - a) / (10 * n);
  380. distance = Math.pow(10, pow);
  381. return distance;
  382. }
  383.  
  384.  
  385. private void distanceNormal() {
  386. distanceStateImg.setVisibility(View.INVISIBLE);
  387. findingStateTxt.setText("");
  388. }
  389.  
  390. private void distanceCloser() {
  391. distanceStateImg.setVisibility(View.VISIBLE);
  392. distanceStateImg.setImageResource(R.drawable.ic_closer);
  393. distanceStateImg.setAnimation(operatingAnim);
  394. operatingAnim.start();
  395. findingStateTxt.setText("");
  396. }
  397.  
  398. private void distanceFarther() {
  399. distanceStateImg.setVisibility(View.VISIBLE);
  400. distanceStateImg.setImageResource(R.drawable.ic_farther);
  401. distanceStateImg.setAnimation(operatingAnim);
  402. operatingAnim.start();
  403. findingStateTxt.setText("");
  404. }
  405.  
  406. public void changeA(View view) {
  407. final QMUIDialog.EditTextDialogBuilder builder = new QMUIDialog.EditTextDialogBuilder(this);
  408. builder.setTitle("当前 A 值")
  409. .setPlaceholder("A")
  410. .setInputType(InputType.TYPE_CLASS_NUMBER)
  411. .addAction("cancel", (dialog, index) -> dialog.dismiss())
  412. .addAction("ok", (dialog, index) -> {
  413. CharSequence text = builder.getEditText().getText();
  414. if (text != null && text.length() > 0) {
  415. try {
  416. float a = Float.parseFloat(text.toString());
  417. SyncUtil.RSSI_A = a;
  418. dialog.dismiss();
  419. } catch (NumberFormatException e) {
  420. toast("must input number");
  421. }
  422. } else {
  423. toast("year can't empty");
  424. }
  425. })
  426. .show();
  427. builder.getEditText().setText(SyncUtil.RSSI_A + "");
  428. }
  429.  
  430.  
  431. public void changeN(View view) {
  432. final QMUIDialog.EditTextDialogBuilder builder = new QMUIDialog.EditTextDialogBuilder(this);
  433. builder.setTitle("当前 n 值")
  434. .setPlaceholder("n")
  435. .setInputType(InputType.TYPE_CLASS_NUMBER)
  436. .addAction("cancel", (dialog, index) -> dialog.dismiss())
  437. .addAction("ok", (dialog, index) -> {
  438. CharSequence text = builder.getEditText().getText();
  439. if (text != null && text.length() > 0) {
  440. try {
  441. float n = Float.parseFloat(text.toString());
  442. SyncUtil.RSSI_n = n;
  443. dialog.dismiss();
  444. } catch (NumberFormatException e) {
  445. toast("must input number");
  446. }
  447. } else {
  448. toast("year can't empty");
  449. }
  450. })
  451. .show();
  452. builder.getEditText().setText(SyncUtil.RSSI_n + "");
  453. }
  454. }
Add Comment
Please, Sign In to add comment