|
@@ -0,0 +1,172 @@
|
|
|
|
+package com.wdkl.nursewatch.service;
|
|
|
|
+
|
|
|
|
+import android.app.Service;
|
|
|
|
+import android.content.Intent;
|
|
|
|
+import android.os.Binder;
|
|
|
|
+import android.os.IBinder;
|
|
|
|
+import android.os.RemoteException;
|
|
|
|
+import android.support.annotation.Nullable;
|
|
|
|
+import android.util.Log;
|
|
|
|
+
|
|
|
|
+import org.altbeacon.beacon.Beacon;
|
|
|
|
+import org.altbeacon.beacon.BeaconConsumer;
|
|
|
|
+import org.altbeacon.beacon.BeaconManager;
|
|
|
|
+import org.altbeacon.beacon.BeaconParser;
|
|
|
|
+import org.altbeacon.beacon.RangeNotifier;
|
|
|
|
+import org.altbeacon.beacon.Region;
|
|
|
|
+//import org.jetbrains.annotations.NotNull;
|
|
|
|
+import org.json.JSONArray;
|
|
|
|
+import org.json.JSONObject;
|
|
|
|
+
|
|
|
|
+import java.util.Collection;
|
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
|
+import java.util.concurrent.LinkedBlockingQueue;
|
|
|
|
+import java.util.concurrent.ThreadFactory;
|
|
|
|
+import java.util.concurrent.ThreadPoolExecutor;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
+
|
|
|
|
+import okhttp3.MediaType;
|
|
|
|
+import okhttp3.OkHttpClient;
|
|
|
|
+import okhttp3.Request;
|
|
|
|
+import okhttp3.RequestBody;
|
|
|
|
+
|
|
|
|
+public class BeaconService extends Service implements BeaconConsumer, RangeNotifier {
|
|
|
|
+
|
|
|
|
+ public static final String SERVER_ID_KEY = BeaconService.class.getName() + ".SERVER_ID_KEY";
|
|
|
|
+
|
|
|
|
+ public static final String NURSE_ID_KEY = BeaconService.class.getName() + ".NURSE_ID_KEY";
|
|
|
|
+
|
|
|
|
+ public static final String NURSE_NAME_KEY = BeaconService.class.getName() + ".NURSE_NAME_KEY";
|
|
|
|
+
|
|
|
|
+ private static final String TAG = "BeaconService";
|
|
|
|
+
|
|
|
|
+ private static final String UPDATE_BEACON_INFO_URL = "http://id.wdklian.com:10018/api/Beacon/UpdateBeaconPosition";
|
|
|
|
+
|
|
|
|
+ private static final String BEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24";
|
|
|
|
+
|
|
|
|
+ private static final ExecutorService BEACON_HANDLER = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new BeaconThreadFactory());
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private BeaconManager beaconManager;
|
|
|
|
+
|
|
|
|
+ private String serverId;
|
|
|
|
+
|
|
|
|
+ private String nurseId;
|
|
|
|
+
|
|
|
|
+ private String nurseName;
|
|
|
|
+
|
|
|
|
+ private final OkHttpClient okHttpClient = new OkHttpClient();
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onCreate() {
|
|
|
|
+ super.onCreate();
|
|
|
|
+
|
|
|
|
+ this.beaconManager = BeaconManager.getInstanceForApplication(this.getApplicationContext());
|
|
|
|
+
|
|
|
|
+ this.beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(BEACON_FORMAT));
|
|
|
|
+
|
|
|
|
+// this.beaconManager.setBackgroundMode(true);
|
|
|
|
+
|
|
|
|
+ this.beaconManager.setForegroundScanPeriod(5000);
|
|
|
|
+ this.beaconManager.setForegroundBetweenScanPeriod(5000);
|
|
|
|
+
|
|
|
|
+ this.beaconManager.bind(this);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Nullable
|
|
|
|
+ @Override
|
|
|
|
+ public IBinder onBind(Intent intent) {
|
|
|
|
+ return new Binder();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onDestroy() {
|
|
|
|
+ super.onDestroy();
|
|
|
|
+
|
|
|
|
+ this.beaconManager.unbind(this);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public int onStartCommand(Intent intent, int flags, int startId) {
|
|
|
|
+
|
|
|
|
+ serverId = intent.getStringExtra(SERVER_ID_KEY);
|
|
|
|
+ nurseId = intent.getStringExtra(NURSE_ID_KEY);
|
|
|
|
+ nurseName = intent.getStringExtra(NURSE_NAME_KEY);
|
|
|
|
+
|
|
|
|
+ return super.onStartCommand(intent, flags, startId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onBeaconServiceConnect() {
|
|
|
|
+ this.beaconManager.removeAllRangeNotifiers();
|
|
|
|
+ this.beaconManager.addRangeNotifier(this);
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ this.beaconManager.startRangingBeaconsInRegion(new Region("", null, null, null));
|
|
|
|
+ } catch (RemoteException e) {
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void didRangeBeaconsInRegion(Collection<Beacon> collection, Region region) {
|
|
|
|
+ BEACON_HANDLER.execute(() -> {
|
|
|
|
+ if (collection.size() > 0) {
|
|
|
|
+ final JSONObject obj = new JSONObject();
|
|
|
|
+ try {
|
|
|
|
+ obj.put("humanId", nurseId);
|
|
|
|
+ obj.put("humanName", nurseName);
|
|
|
|
+ obj.put("serverId", serverId);
|
|
|
|
+
|
|
|
|
+ final JSONArray array = new JSONArray();
|
|
|
|
+ for (Beacon beacon : collection) {
|
|
|
|
+ final JSONObject tmp = new JSONObject();
|
|
|
|
+ tmp.put("name", beacon.getBluetoothName());
|
|
|
|
+ tmp.put("address", beacon.getBluetoothAddress());
|
|
|
|
+ tmp.put("UUID", beacon.getId1().toString());
|
|
|
|
+ tmp.put("major", beacon.getId2().toInt());
|
|
|
|
+ tmp.put("minor", beacon.getId3().toInt());
|
|
|
|
+ tmp.put("txPower", beacon.getTxPower());
|
|
|
|
+ tmp.put("RSSI", beacon.getRssi());
|
|
|
|
+ tmp.put("distance", beacon.getDistance());
|
|
|
|
+
|
|
|
|
+ array.put(tmp);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ obj.put("beaconInfos", array);
|
|
|
|
+
|
|
|
|
+ final Request request = new Request.Builder()
|
|
|
|
+ .url(UPDATE_BEACON_INFO_URL)
|
|
|
|
+ .put(RequestBody.create(obj.toString(), MediaType.parse("application/json")))
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+ okHttpClient.newCall(request).execute();
|
|
|
|
+ } catch (Exception ignore) {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static final class BeaconThreadFactory implements ThreadFactory {
|
|
|
|
+ private static final String BEACON_THREAD_NAME = "BeaconThread";
|
|
|
|
+
|
|
|
|
+ private final ThreadGroup threadGroup;
|
|
|
|
+
|
|
|
|
+ BeaconThreadFactory() {
|
|
|
|
+ final SecurityManager securityManager = System.getSecurityManager();
|
|
|
|
+ this.threadGroup = securityManager != null ? securityManager.getThreadGroup() : Thread.currentThread().getThreadGroup();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Thread newThread(Runnable runnable) {
|
|
|
|
+ final Thread thread = new Thread(this.threadGroup, runnable, BEACON_THREAD_NAME);
|
|
|
|
+ if (thread.isDaemon()) {
|
|
|
|
+ thread.setDaemon(false);
|
|
|
|
+ }
|
|
|
|
+ if (thread.getPriority() != Thread.NORM_PRIORITY) {
|
|
|
|
+ thread.setPriority(Thread.NORM_PRIORITY);
|
|
|
|
+ }
|
|
|
|
+ return thread;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|