| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636 |
- package com.doorknocker.bluetooth;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import android.annotation.SuppressLint;
- import android.app.Service;
- import android.bluetooth.BluetoothAdapter;
- import android.bluetooth.BluetoothDevice;
- import android.bluetooth.BluetoothGatt;
- import android.bluetooth.BluetoothGattCallback;
- import android.bluetooth.BluetoothGattCharacteristic;
- import android.bluetooth.BluetoothGattDescriptor;
- import android.bluetooth.BluetoothGattService;
- import android.bluetooth.BluetoothManager;
- import android.bluetooth.BluetoothProfile;
- import android.bluetooth.le.BluetoothLeScanner;
- import android.bluetooth.le.ScanCallback;
- import android.bluetooth.le.ScanResult;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.content.SharedPreferences;
- import android.os.Binder;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.os.PowerManager;
- import android.os.PowerManager.WakeLock;
- import android.util.Log;
- import com.doorknocker.Constant;
- import com.doorknocker.model.DoorItem;
- public class BLEService extends Service {
- public static final String SERVERSBROADCASTINF = "com.mt.service_inf";
- public static final String SERVERSBROADCASTINF_KEY = "key";
- private int currentVersion;
- /**
- * 开门的距离,正式上线之后要从配置文件中获取
- */
- private int openDistance = -75;
- @Override
- public void onCreate() {
- super.onCreate();
- System.out.println("onCreate BLEService");
- // mHandler.sendEmptyMessage(REFLASH_PROTECT_SERVICE);
- if (!initBle()) {
- return;
- }
-
- /**
- * 如果安卓版本低于4.3就不要往下执行了。
- */
- currentVersion = android.os.Build.VERSION.SDK_INT;
- if (Constant.MIN_OS_VERSION > currentVersion) {
- return;
- }
-
- // 默认开门距离
- SharedPreferences preferences = getSharedPreferences(Constant.NAME_CONFIG, Context.MODE_PRIVATE);
- openDistance = preferences.getInt(Constant.KEY_DOOR_DISTANCE_DEFAULT, -75);
- initBroadcastReceiver();
- getDoorInfFromDB();
- scanBle();
- acquireWakeLock();
- }
- // 申请电源锁,禁止休眠
- private WakeLock mWakeLock = null;
- private void acquireWakeLock() {
- if (null == mWakeLock) {
- PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this
- .getClass().getCanonicalName());
- if (null != mWakeLock) {
- mWakeLock.acquire();
- }
- }
- }
- // 释放设备电源锁
- private void releaseWakeLock() {
- if (null != mWakeLock) {
- mWakeLock.release();
- mWakeLock = null;
- }
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- System.out.println("onStartCommand1");
- return START_STICKY;
- }
- // 获取门列表
- private DBAdapter db;
- private SharedPreferences prefs;
- private Map<String, DoorItem> doormap = new HashMap<String, DoorItem>();
- private void getDoorInfFromDB() {
- db = new DBAdapter(getApplicationContext());
- // 查看是否有权限
- SharedPreferences preferences = getSharedPreferences(
- Constant.NAME_CONFIG, Context.MODE_PRIVATE);
- boolean hasPermission = preferences.getBoolean(
- Constant.HAS_DOOR_PERMITION, false);
- if (!hasPermission) {
- return;
- }
- // 获取列表
- db.open();
- doormap = db.getAllClockListMap();
- if (doormap == null) {
- System.out.println("has no doors");
- }
- db.close();
- }
- public BluetoothManager mBluetoothManager;
- public BluetoothAdapter mBluetoothAdapter;
- //private BluetoothLeScanner scanner;
- public BluetoothGatt mBluetoothGatt;
- private List<MTBeacon> scan_devices = new ArrayList<MTBeacon>();
- // 初始化BLE
- @SuppressLint("NewApi")
- private boolean initBle() {
- System.out.println("initBle");
- mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
- if (null == mBluetoothManager) {
- System.out.println("获取 mBluetoothManager失败");
- return false;
- }
- mBluetoothAdapter = mBluetoothManager.getAdapter();
- if (null == mBluetoothAdapter) {
- System.out.println("获取 mBluetoothAdapter失败");
- return false;
- }
- //scanner = mBluetoothAdapter.getBluetoothLeScanner();
- return true;
- }
- // 扫描设备
- private Handler search_timer = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- new OpenDoorThread().start();
- }
- };
-
- @SuppressLint("NewApi")
- private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
- @Override
- public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
- int i = 0;
- MTBeacon beacon_tmp = new MTBeacon(device, rssi, scanRecord);
- // 是否为ibeacon
- if (!beacon_tmp.isIsClock()) {
- return;
- }
-
- for (i = 0; i < scan_devices.size(); i++) {
- if (0 == device.getAddress().compareTo(
- scan_devices.get(i).GetDevice().getAddress())) {
- scan_devices.get(i).ReflashInf(device, rssi, scanRecord); // 更新信息
- return;
- }
- }
- // 如果没有,就添加
- scan_devices.add(beacon_tmp);
- }
- };
-
- //扫描回调
- /*@SuppressLint("NewApi")
- private ScanCallback mScanCallback = new ScanCallback() {
- public void onBatchScanResults(List<ScanResult> results) {
-
- for (int index = 0, size = results.size(); index < size; index++) {
- ScanResult result = results.get(index);
- MTBeacon beacon_tmp = new MTBeacon(result.getDevice(), result.getRssi(), result.getScanRecord().getBytes());
- // 是否为ibeacon
- if (!beacon_tmp.isIsClock()) {
- return;
- }
-
- if (0 == result.getDevice().getAddress().compareTo(
- scan_devices.get(index).GetDevice().getAddress())) {
- scan_devices.get(index).ReflashInf(result.getDevice(), result.getRssi(), result.getScanRecord().getBytes()); // 更新信息
- return;
- }
-
- // 如果没有,就添加
- scan_devices.add(beacon_tmp);
- }
- };
- };*/
- private void scanBle() {
- search_timer.sendEmptyMessage(0);
- }
- // 开门操作
- private boolean connect_flag = false;
- private boolean notification_flag = false;
- private boolean openclock_flag = false;
- private boolean scan_flag = false; // 是否正在扫描
- private boolean has_permition_clock_flag = false;
- private boolean timeout_flag = false; // 超时标志
- private final int REFLASH_PROTECT_SERVICE = 1;
- private Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- if (msg.what == 0) {
- timeout_flag = true;
- return;
- }
- if (msg.what == REFLASH_PROTECT_SERVICE) {
- Intent intent = new Intent(getApplicationContext(),
- ProtectService.class);
- startService(intent);
- mHandler.sendEmptyMessageDelayed(REFLASH_PROTECT_SERVICE, 10000);
- return;
- }
- };
- };
- @SuppressLint("NewApi")
- private class OpenDoorThread extends Thread {
- @Override
- public void run() {
- super.run();
- try {
- if (!mBluetoothAdapter.isEnabled()) {
- search_timer.sendEmptyMessageDelayed(0, 1000);
- scan_flag = true;
- return;
- }
- if (scan_flag) {
- // System.out.println("停止扫描");
- LogText.writeStr(" 设备数量->" + scan_devices.size());
- Log.i("bluetooth", "设备数量==================================" + scan_devices.size());
- mBluetoothAdapter.stopLeScan(mLeScanCallback);
- //scanner.stopScan(mScanCallback);
- for (MTBeacon mtbeacon : scan_devices) {
- // System.out.println("getClockID-->"
- // + mtbeacon.getClockID());
- DoorItem clock = doormap.get(mtbeacon.getClockID());
- System.out.println("ID->" + mtbeacon.getClockID());
- if (clock == null) { // 判断此锁是否存在于权限中
- LogText.writeStr("没有权限->" + mtbeacon.getClockID());
- Log.i("bluetooth", "没有权限===================================");
- continue;
- }
- has_permition_clock_flag = true;
- if (mtbeacon.GetAveragerssi() < openDistance) { // 判断距离
- LogText.writeStr("距离太远->"
- + mtbeacon.GetAveragerssi());
- Log.i("bluetooth", "距离太远===================================");
- continue;
- }
- if ((System.currentTimeMillis() - clock
- .getLast_open_time()) < 10000) { // 判断距离上次开锁多久了
- LogText.writeStr("距离上次开锁还不到10s");
- Log.i("bluetooth", "距离上次开锁还不到10s===================================");
- continue;
- }
- if (!connectBLETimeout(mtbeacon, 5000)) {
- LogText.writeStr(" 连接超时");
- disConectBle();
- Log.i("bluetooth", "连接超时===================================");
- continue;
- }
- if (getService()) { // 获取通道
- if (!setNotifiTimeout(500)) {
- LogText.writeStr(" 设置通知超时");
- disConectBle();
- Log.i("bluetooth", "设置通知超时===================================");
- continue;
- }
- // 密码验证
- if (!writeData(cmdCharacteristic,
- "AT+PWD[" + clock.getPassword() + "]", 500)) {
- LogText.writeStr(" 密码验证超时");
- disConectBle();
- Log.i("bluetooth", "密码验证超时===================================");
- continue;
- }
- if (!recive_msg.equals("You Are User\r\n")) {
- LogText.writeStr(" 密码配对错误");
- Log.i("bluetooth", "密码配对错误===================================");
- continue;
- }
- // 开门命令
- // writeData(cmdCharacteristic, "AT+SOPEN", 500);
- if (!writeData(cmdCharacteristic, "AT+SOPEN", 500)) {
- LogText.writeStr(" 开门超时");
- disConectBle();
- Log.i("bluetooth", "开门超时===================================");
- continue;
- }
- if (!recive_msg.equals("OK+SOPEN\r\n")) {
- LogText.writeStr(" 开门失败");
- Log.i("bluetooth", "开门失败===================================");
- continue;
- }
- broadcastUpdate(SERVERSBROADCASTINF, "开锁成功");
- LogText.writeStr("开锁成功");
- Log.i("bluetooth", "开锁成功===================================");
- clock.setLast_open_time(System.currentTimeMillis()); // 设置这次开锁时间
- }
- disConectBle();
- sleep(500);
- }
- scan_devices.clear();
- if (has_permition_clock_flag) {
- // search_timer.sendEmptyMessage(0);
- search_timer.sendEmptyMessageDelayed(0, 100);
- } else {
- search_timer.sendEmptyMessageDelayed(0, 5000);
- }
- has_permition_clock_flag = false;
- scan_flag = false; // 设置为没有扫描状态
- } else {
- broadcastUpdate(SERVERSBROADCASTINF, "开始扫描");
- LogText.writeStr(" 开始扫描");
- Log.i("bluetooth", "开始扫描===================================");
- mBluetoothAdapter.startLeScan(mLeScanCallback);
- //scanner.startScan(mScanCallback);
- search_timer.sendEmptyMessageDelayed(0, 900); // 扫描1s
- scan_flag = true; // 设置为真正扫描状态
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- // 连接超时判断函数
- private boolean connectBLETimeout(MTBeacon mtbeacon, int millsec) {
- timeout_flag = false;
- connect_flag = false;
- if (!mBluetoothAdapter.isEnabled()) {
- return false;
- }
- conectBle(mtbeacon.GetDevice()); // 连接设备
- mHandler.sendEmptyMessageDelayed(0, millsec);
- while (!connect_flag) {
- if (timeout_flag) {
- return false;
- }
- }
- mHandler.removeMessages(0);
- return true;
- }
- // 设置可通知超时判断函数
- private boolean setNotifiTimeout(int millsec) {
- timeout_flag = false;
- notification_flag = false;
- mBluetoothGatt.setCharacteristicNotification(cmdCharacteristic, true);
- return true;
- }
- // 写数据超时判断
- private boolean writeData(BluetoothGattCharacteristic cmdChara,
- String data, int millsec) {
- timeout_flag = false;
- openclock_flag = false;
- if (!mBluetoothAdapter.isEnabled()) {
- return false;
- }
- cmdChara.setValue(data);
- mBluetoothGatt.writeCharacteristic(cmdChara);
- try {
- sleep(millsec);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- if (!openclock_flag) {
- return false;
- }
- return true;
- }
- }
- //
- private String recive_msg;
- private BluetoothGattCharacteristic cmdCharacteristic;
- @SuppressLint("NewApi")
- private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
- @Override
- public void onConnectionStateChange(BluetoothGatt gatt, int status,
- int newState) {
- super.onConnectionStateChange(gatt, status, newState);
- if (newState == BluetoothProfile.STATE_CONNECTED) {
- System.out.println("CONNECTED");
- mBluetoothGatt.discoverServices();
- } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
- System.out.println("UNCONNECTED");
- connect_flag = false;
- }
- }
- @Override
- public void onServicesDiscovered(BluetoothGatt gatt, int status) {
- super.onServicesDiscovered(gatt, status);
- if (status == BluetoothGatt.GATT_SUCCESS) {
- System.out.println("onServicesDiscovered");
- connect_flag = true;
- } else {
- System.out.println("onServicesDiscovered fail-->" + status);
- }
- }
- @Override
- public void onDescriptorRead(BluetoothGatt gatt,
- BluetoothGattDescriptor descriptor, int status) {
- super.onDescriptorRead(gatt, descriptor, status);
- }
- @Override
- public void onCharacteristicRead(BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic, int status) {
- super.onCharacteristicRead(gatt, characteristic, status);
- if (status == BluetoothGatt.GATT_SUCCESS) {
- }
- }
- @Override
- public void onCharacteristicChanged(BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic) {
- super.onCharacteristicChanged(gatt, characteristic);
- recive_msg = characteristic.getStringValue(0);
- openclock_flag = true;
- System.out.println("read->" + characteristic.getStringValue(0));
- }
- @Override
- public void onCharacteristicWrite(BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic, int status) {
- if (status == BluetoothGatt.GATT_SUCCESS) {
- System.out.println("write OK");
- } else {
- System.out.println("write fail");
- }
- super.onCharacteristicWrite(gatt, characteristic, status);
- }
- @Override
- public void onDescriptorWrite(BluetoothGatt gatt,
- BluetoothGattDescriptor descriptor, int status) {
- super.onDescriptorWrite(gatt, descriptor, status);
- notification_flag = true;
- }
- };
- @SuppressLint("NewApi")
- private boolean conectBle(BluetoothDevice mBluetoothDevice) {
- disConectBle();
- BluetoothDevice device_tmp = mBluetoothAdapter
- .getRemoteDevice(mBluetoothDevice.getAddress());
- if (device_tmp == null) {
- System.out.println("device == null");
- return false;
- }
- mBluetoothGatt = device_tmp.connectGatt(getApplicationContext(), false,
- mGattCallback);
- return true;
- }
- // 获取通道号
- @SuppressLint("NewApi")
- private boolean getService() {
- for (BluetoothGattService service : mBluetoothGatt.getServices()) {
- // System.out.println("service_uuid->"+service.getUuid().toString().toUpperCase());
- if (service.getUuid().toString().toUpperCase()
- .equals(MTBeaconUUID.SERVICE_UUID)) {
- for (BluetoothGattCharacteristic gattCharacteristic : service
- .getCharacteristics()) {
- if (gattCharacteristic.getUuid().toString().toUpperCase()
- .equals(MTBeaconUUID.CMD_UUID)) {
- cmdCharacteristic = gattCharacteristic;
- return true;
- }
- }
- }
- }
- return false;
- }
- // 断开连接
- @SuppressLint("NewApi")
- private void disConectBle() {
- if (!mBluetoothAdapter.isEnabled()) {
- return;
- }
- if (mBluetoothGatt != null) {
- mBluetoothGatt.disconnect();
- mBluetoothGatt.close();
- mBluetoothGatt = null;
- }
- connect_flag = false;
- }
- // 发送广播消息
- private void broadcastUpdate(final String action, String value) {
- final Intent intent = new Intent(action);
- intent.putExtra(SERVERSBROADCASTINF_KEY, value);
- sendBroadcast(intent);
- }
- // 初始化广播接收器
- private MyBroadcastReceiver receviver = null;
- private void initBroadcastReceiver() {
- // 创建一个IntentFilter对象,将其action指定为BluetoothDevice.ACTION_FOUND
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Constant.RELOAD_DATA);
- intentFilter.addAction(Constant.RELOAD_OPEN_DOORS_DISTANCE);
- receviver = new MyBroadcastReceiver();
- // 注册广播接收器
- registerReceiver(receviver, intentFilter);
- }
- private class MyBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Constant.RELOAD_DATA)) {
- // 重新加载数据库
- System.out.println("get RELOAD_DATA");
- getDoorInfFromDB();
- return;
- } else if (action.equals(Constant.RELOAD_OPEN_DOORS_DISTANCE)) {
- // 这里得到实际距离,要将实际距离进行转化
- /**
- * 0========-5
- * 10=======-85
- */
- openDistance = getSharedPreferences(Constant.NAME_CONFIG, Context.MODE_PRIVATE).getInt(Constant.KEY_DOOR_DISTANCE, -85);
- if (openDistance > -50) {
- openDistance = -50;
- }
- return;
- } else if (action.equals(Constant.RELOAD_OPEN_DOORS_DISTANCE_DEF)) {
- SharedPreferences preferences = getSharedPreferences(Constant.NAME_CONFIG, Context.MODE_PRIVATE);
- openDistance = preferences.getInt(Constant.KEY_DOOR_DISTANCE_DEFAULT, -75);
- return;
- }
- }
- }
- @Override
- public void onDestroy() {
- LogText.writeStr(" onDestroy");
- super.onDestroy();
- if (receviver != null) {
- unregisterReceiver(receviver);
- }
- // if (receiver != null)
- // unregisterReceiver(receiver);
- // releaseWakeLock();
- releaseWakeLock();
- stopForeground(true);
- }
- public class LocalBinder extends Binder {
- public BLEService getService() {
- return BLEService.this;
- }
- }
- private final IBinder mBinder = new LocalBinder();
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
- }
|