Browse Source

<集成beacon service>

weizhengliang 5 years ago
parent
commit
e0d98e0d60

+ 9 - 2
app/build.gradle

@@ -24,6 +24,10 @@ android {
         ]
 
     }
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
     buildTypes {
         release {
             minifyEnabled false
@@ -56,7 +60,7 @@ dependencies {
     implementation 'org.greenrobot:eventbus:3.0.0'
     implementation 'com.jakewharton:butterknife:7.0.1'
     implementation 'com.jude:easyrecyclerview:4.4.2'
-    implementation 'com.squareup.okhttp3:okhttp:3.12.0'
+    implementation 'com.squareup.okhttp3:okhttp:4.7.1'
     implementation 'com.android.support:cardview-v7:23.2.0'
     implementation 'cn.jiguang.sdk:jpush:3.1.6'
     // 此处以JPush 3.1.6 版本为例。
@@ -69,5 +73,8 @@ dependencies {
     implementation 'com.alibaba:fastjson:1.2.46'
 
     //ibeancon
-    implementation 'org.altbeacon:android-beacon-library:2.13+'
+    //implementation 'org.altbeacon:android-beacon-library:2.13+'
+    //implementation 'androidx.appcompat:appcompat:1.1.0'
+    implementation 'org.altbeacon:android-beacon-library:2.17'
+    implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
 }

+ 3 - 1
app/src/main/AndroidManifest.xml

@@ -114,7 +114,9 @@
             android:exported="true"
             android:priority="1000"
             android:permission="true"/>
-
+        <service android:name="com.wdkl.nursewatch.service.BeaconService"
+            android:persistent="true"
+            android:priority="999"/>
     </application>
 
 </manifest>

+ 17 - 15
app/src/main/java/com/wdkl/nursewatch/presentation/ui/activities/HomeActivity.java

@@ -30,6 +30,7 @@ import com.wdkl.nursewatch.entity.MessageEntity;
 import com.wdkl.nursewatch.entity.MessageEvent;
 import com.wdkl.nursewatch.presentation.ui.base.BaseActivity;
 import com.wdkl.nursewatch.presentation.ui.views.BatteryView;
+import com.wdkl.nursewatch.service.BeaconService;
 import com.wdkl.nursewatch.utils.NetworkUtil;
 import com.wdkl.nursewatch.utils.PhoneUtils;
 import com.wdkl.nursewatch.utils.ReceiverUtil;
@@ -56,7 +57,7 @@ import java.util.List;
 
 import butterknife.Bind;
 
-public class HomeActivity extends BaseActivity implements View.OnClickListener, BeaconConsumer {
+public class HomeActivity extends BaseActivity implements View.OnClickListener {
 
     @Bind(R.id.tv_home_times)
     TextView tv_home_times;
@@ -92,12 +93,13 @@ public class HomeActivity extends BaseActivity implements View.OnClickListener,
     //ibeancon
     private static final int REQUEST_ENABLE_BT = 1;
     private static final int REQUEST_ENABLE_LOCATION = 1;
-    private static final long DEFAULT_FOREGROUND_SCAN_PERIOD = 2 * 1000L;
-    private static final long DEFAULT_FOREGROUND_BETWEEN_SCAN_PERIOD = 10 * 1000L;
-    private BeaconManager beaconManager;
-    private List<Beacon> beaconList = new ArrayList<>();
+    //private static final long DEFAULT_FOREGROUND_SCAN_PERIOD = 2 * 1000L;
+    //private static final long DEFAULT_FOREGROUND_BETWEEN_SCAN_PERIOD = 10 * 1000L;
+    //private BeaconManager beaconManager;
+    //private List<Beacon> beaconList = new ArrayList<>();
     private boolean isEnabledBT = false;
     private boolean isEnabledLocation = false;
+    private boolean beanconServiceStarted = false;
 
     @Override
     public int getLayoutId() {
@@ -114,10 +116,10 @@ public class HomeActivity extends BaseActivity implements View.OnClickListener,
             tv_home_network_power.setVisibility(View.VISIBLE);
             checkBT();
             checkLocation();
-            Log.d("wzl", "bt: " + isEnabledBT + ", location: " + isEnabledLocation);
-            if (isEnabledBT && isEnabledLocation) {
+            //Log.d("wzl", "bt: " + isEnabledBT + ", location: " + isEnabledLocation);
+            /*if (isEnabledBT && isEnabledLocation) {
                 initBeancon();
-            }
+            }*/
         } else {
             battery_view.setVisibility(View.INVISIBLE);
             tv_home_network_power.setVisibility(View.INVISIBLE);
@@ -202,12 +204,12 @@ public class HomeActivity extends BaseActivity implements View.OnClickListener,
         }
     }
 
-    private void initBeancon() {
+    /*private void initBeancon() {
         beaconManager = BeaconManager.getInstanceForApplication(this);
         beaconManager.setForegroundScanPeriod(DEFAULT_FOREGROUND_SCAN_PERIOD);
         beaconManager.setForegroundBetweenScanPeriod(DEFAULT_FOREGROUND_BETWEEN_SCAN_PERIOD);
         beaconManager.bind(this);
-    }
+    }*/
 
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
@@ -219,12 +221,12 @@ public class HomeActivity extends BaseActivity implements View.OnClickListener,
             isEnabledLocation = true;
         }
 
-        if (isEnabledBT && isEnabledLocation) {
+        /*if (isEnabledBT && isEnabledLocation) {
             initBeancon();
-        }
+        }*/
     }
 
-    @Override
+    /*@Override
     public void onBeaconServiceConnect() {
         beaconManager.removeAllRangeNotifiers();
         beaconManager.addRangeNotifier(new RangeNotifier() {
@@ -253,7 +255,7 @@ public class HomeActivity extends BaseActivity implements View.OnClickListener,
         } catch (Exception e) {
             e.printStackTrace();
         }
-    }
+    }*/
 
     final int TIME_WHAT = 1000;
 
@@ -336,7 +338,7 @@ public class HomeActivity extends BaseActivity implements View.OnClickListener,
         if (null != batteryBroadcastReceiver) {
             unregisterReceiver(batteryBroadcastReceiver);
         }
-        beaconManager.unbind(this);
+        //beaconManager.unbind(this);
     }
 
     @Override

+ 7 - 0
app/src/main/java/com/wdkl/nursewatch/presentation/ui/activities/LoginActivity.java

@@ -16,6 +16,7 @@ import com.wdkl.nursewatch.adapters.MainViewAdapter;
 import com.wdkl.nursewatch.common.Constants;
 import com.wdkl.nursewatch.entity.MessageEvent;
 import com.wdkl.nursewatch.presentation.ui.base.BaseActivity;
+import com.wdkl.nursewatch.service.BeaconService;
 import com.wdkl.nursewatch.utils.LogUtil;
 import com.wdkl.nursewatch.utils.NetworkUtil;
 import com.wdkl.nursewatch.utils.SharedPreferencesUtil;
@@ -204,6 +205,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
                     if (StringUtils.notEmpty(loginMachineId)) {
                         if (NetworkUtil.checkNetworkAvailable()) {
                             WebsocketUtil.getInstance().connect(loginMachineId,nurseID);
+                            //启动蓝牙信标扫描服务
+                            final Intent intent = new Intent(this, BeaconService.class);
+                            intent.putExtra(BeaconService.SERVER_ID_KEY, loginMachineId);
+                            intent.putExtra(BeaconService.NURSE_ID_KEY, nurseID);
+                            intent.putExtra(BeaconService.NURSE_NAME_KEY, nurseName);
+                            startService(intent);
                         }
                     } else {
                         ToastUtil.showToast(LoginActivity.this, "非法二维码!");

+ 172 - 0
app/src/main/java/com/wdkl/nursewatch/service/BeaconService.java

@@ -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;
+        }
+    }
+}