org.bcsphere.bluetooth.BluetoothSamAPI.java Source code

Java tutorial

Introduction

Here is the source code for org.bcsphere.bluetooth.BluetoothSamAPI.java

Source

/*
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
    
     http://www.apache.org/licenses/LICENSE-2.0
    
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
*/
package org.bcsphere.bluetooth;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile.ServiceListener;
import android.content.Context;
import android.util.Log;

import org.bcsphere.bluetooth.tools.Tools;
import com.samsung.android.sdk.bt.gatt.BluetoothGatt;
import com.samsung.android.sdk.bt.gatt.BluetoothGattAdapter;
import com.samsung.android.sdk.bt.gatt.BluetoothGattCallback;
import com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic;
import com.samsung.android.sdk.bt.gatt.BluetoothGattDescriptor;
import com.samsung.android.sdk.bt.gatt.BluetoothGattServer;
import com.samsung.android.sdk.bt.gatt.BluetoothGattServerCallback;
import com.samsung.android.sdk.bt.gatt.BluetoothGattService;
import com.samsung.android.sdk.bt.gatt.MutableBluetoothGattCharacteristic;
import com.samsung.android.sdk.bt.gatt.MutableBluetoothGattDescriptor;
import com.samsung.android.sdk.bt.gatt.MutableBluetoothGattService;

public class BluetoothSamAPI implements BluetoothAPI {

    private static final String TAG = "BluetoothSamAPI";

    private static int serviceNumber = -1;

    private static int addedServiceNumber = 0;

    private boolean scanning = false;

    private BluetoothGatt bluetoothGatt;

    private BluetoothAdapter bluetoothAdapter;

    private BluetoothGattServer bluetoothGattServer;

    private List<BluetoothDevice> bluetoothDevices;

    private CallbackContext addServiceCallBack;

    private Map<String, CallbackContext> mapGetRssiCallBack;

    private Map<String, CallbackContext> mapConnectCallBack;

    private Map<String, CallbackContext> mapDisconnectCallBack;

    private Map<Object, CallbackContext> mapReadValueCallBack;

    private Map<Object, CallbackContext> mapWriteValueCallBack;

    private Map<String, CallbackContext> mapGetServicesCallBack;

    private Map<String, CallbackContext> mapAddListenerCallBack;

    private Map<Object, CallbackContext> mapSetNotificationCallBack;

    private Map<String, CallbackContext> mapGetDeviceAllDataCallBack;

    private Map<String, Integer> mapRssiData;

    private Map<String, byte[]> mapDeviceAdvData;

    private Map<String, BluetoothGattService> mapRemoteServices;

    private Map<String, List<BluetoothGattService>> mapDeviceServices;

    @Override
    public void setContext(Context context) {
        Log.i(TAG, "setContext");
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        BluetoothGattAdapter.getProfileProxy(context, serviceListener, BluetoothGattAdapter.GATT);
        BluetoothGattAdapter.getProfileProxy(context, serviceListener, BluetoothGattAdapter.GATT_SERVER);
        while (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
            if (bluetoothGatt != null) {
                break;
            }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void openBluetooth(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "openBluetooth");
        bluetoothAdapter.enable();
    }

    @Override
    public void getBluetoothState(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "getBluetoothState");
        boolean state = bluetoothAdapter.isEnabled();
        JSONObject jsonObject = new JSONObject();
        if (state) {
            Tools.addProperty(jsonObject, Tools.BLUETOOTH_STATE, Tools.IS_TRUE);
        } else {
            Tools.addProperty(jsonObject, Tools.BLUETOOTH_STATE, Tools.IS_FALSE);
        }
        callbackContext.success(jsonObject);
    }

    @Override
    public void startScan(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "startScan");
        if (!isInitialized(callbackContext)) {
            return;
        }
        if (mapDeviceAdvData == null) {
            mapDeviceAdvData = new HashMap<String, byte[]>();
        }
        if (mapRssiData == null) {
            mapRssiData = new HashMap<String, Integer>();
        }
        bluetoothDevices = new ArrayList<BluetoothDevice>();
        UUID[] uuids = Tools.getUUIDs(json);
        boolean result = false;
        if (uuids == null || uuids.length < 1) {
            result = bluetoothGatt.startScan();
        } else {
            result = bluetoothGatt.startScan(uuids);
        }
        if (!result) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        scanning = true;
        Tools.sendSuccessMsg(callbackContext);
    }

    @Override
    public void getScanData(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "getScanData");
        JSONArray jsonDevices = new JSONArray();
        for (BluetoothDevice device : bluetoothDevices) {
            String deviceID = device.getAddress();
            JSONObject jsonDevice = new JSONObject();
            Tools.addProperty(jsonDevice, Tools.DEVICE_ID, deviceID);
            Tools.addProperty(jsonDevice, Tools.DEVICE_NAME, device.getName());
            Tools.addProperty(jsonDevice, Tools.IS_CONNECTED, bluetoothGatt.getConnectedDevices().contains(device));
            Tools.addProperty(jsonDevice, Tools.RSSI, mapRssiData.get(deviceID));
            Tools.addProperty(jsonDevice, Tools.ADVERTISEMENT_DATA,
                    Tools.decodeAdvData(mapDeviceAdvData.get(deviceID)));
            jsonDevices.put(jsonDevice);
        }
        callbackContext.success(jsonDevices);
    }

    @Override
    public void stopScan(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "stopScan");
        if (!isInitialized(callbackContext)) {
            return;
        }
        if (scanning) {
            bluetoothGatt.stopScan();
            scanning = false;
        }
        Tools.sendSuccessMsg(callbackContext);
    }

    @Override
    public void connect(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "connect");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        if (deviceID == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (isConnected(device)) {
            Tools.sendSuccessMsg(callbackContext);
            return;
        }
        if (mapConnectCallBack == null) {
            mapConnectCallBack = new HashMap<String, CallbackContext>();
        }
        mapConnectCallBack.put(deviceID, callbackContext);
        bluetoothGatt.connect(device, false);
    }

    @Override
    public void disconnect(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "disconnect");
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        if (deviceID == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (!isConnected(device)) {
            Tools.sendSuccessMsg(callbackContext);
            return;
        }
        if (mapDisconnectCallBack == null) {
            mapDisconnectCallBack = new HashMap<String, CallbackContext>();
        }
        mapDisconnectCallBack.put(deviceID, callbackContext);
        bluetoothGatt.cancelConnection(device);
    }

    @Override
    public void getConnectedDevices(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "getConnectedDevices");
        if (!isInitialized(callbackContext)) {
            return;
        }
        @SuppressWarnings("unchecked")
        List<BluetoothDevice> bluetoothDevices = bluetoothGatt.getConnectedDevices();
        JSONArray jsonDevices = new JSONArray();
        for (BluetoothDevice device : bluetoothDevices) {
            JSONObject jsonDevice = new JSONObject();
            Tools.addProperty(jsonDevice, Tools.DEVICE_ID, device.getAddress());
            Tools.addProperty(jsonDevice, Tools.DEVICE_NAME, device.getName());
            jsonDevices.put(jsonDevice);
        }
        callbackContext.success(jsonDevices);
    }

    @Override
    public void getPairedDevices(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "getPairedDevices");
        if (!isInitialized(callbackContext)) {
            return;
        }
        Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
        JSONArray jsonDevices = new JSONArray();
        for (BluetoothDevice device : bondedDevices) {
            JSONObject jsonDevice = new JSONObject();
            Tools.addProperty(jsonDevice, Tools.DEVICE_ID, device.getAddress());
            Tools.addProperty(jsonDevice, Tools.DEVICE_NAME, device.getName());
            jsonDevices.put(jsonDevice);
        }
        callbackContext.success(jsonDevices);
    }

    @Override
    public void createPair(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "createPair");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        if (deviceID == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (device == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        if (bluetoothAdapter.getBondedDevices().contains(device)) {
            Tools.sendSuccessMsg(callbackContext);
            return;
        }
        JSONObject jsonObject = new JSONObject();
        Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
        try {
            if (Tools.creatBond(device.getClass(), device)) {
                Tools.addProperty(jsonObject, Tools.MES, Tools.SUCCESS);
                callbackContext.success(jsonObject);
            } else {
                Tools.addProperty(jsonObject, Tools.MES, Tools.ERROR);
                callbackContext.success(jsonObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void removePair(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "removePair");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        if (deviceID == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (device == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        JSONObject jsonObject = new JSONObject();
        Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
        try {
            if (Tools.removeBond(device.getClass(), device)) {
                Tools.addProperty(jsonObject, Tools.MES, Tools.SUCCESS);
                callbackContext.success(jsonObject);
            } else {
                Tools.addProperty(jsonObject, Tools.MES, Tools.ERROR);
                callbackContext.success(jsonObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void getServices(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "getServices");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        if (deviceID == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (!isConnected(device)) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        if (mapGetServicesCallBack == null) {
            mapGetServicesCallBack = new HashMap<String, CallbackContext>();
        }
        mapGetServicesCallBack.put(deviceID, callbackContext);
        bluetoothGatt.discoverServices(device);
    }

    @Override
    public void getCharacteristics(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "getCharacteristics");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        String serviceIndex = Tools.getData(json, Tools.SERVICE_INDEX);
        String[] args = new String[] { deviceID, serviceIndex };
        if (!isNullOrEmpty(args, callbackContext)) {
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (!isConnected(device)) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }

        if (serviceIndex == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        JSONObject jsonObject = new JSONObject();
        Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
        JSONArray characteristics = new JSONArray();
        int size = getService(deviceID, serviceIndex).getCharacteristics().size();
        for (int i = 0; i < size; i++) {
            BluetoothGattCharacteristic bluetoothGattCharacteristic = getCharacteristic(deviceID, serviceIndex,
                    String.valueOf(i));
            UUID charateristicUUID = bluetoothGattCharacteristic.getUuid();
            JSONObject characteristic = new JSONObject();
            Tools.addProperty(characteristic, Tools.CHARACTERISTIC_INDEX, i);
            Tools.addProperty(characteristic, Tools.CHARACTERISTIC_UUID, charateristicUUID);
            Tools.addProperty(characteristic, Tools.CHARACTERISTIC_NAME, Tools.lookup(charateristicUUID));
            Tools.addProperty(characteristic, Tools.CHARACTERISTIC_PROPERTY,
                    Tools.decodeProperty(bluetoothGattCharacteristic.getProperties()));
            characteristics.put(characteristic);
        }
        Tools.addProperty(jsonObject, Tools.CHARACTERISTICS, characteristics);
        callbackContext.success(jsonObject);
    }

    @Override
    public void getDescriptors(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "getDescriptors");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        String serviceIndex = Tools.getData(json, Tools.SERVICE_INDEX);
        String characteristicIndex = Tools.getData(json, Tools.CHARACTERISTIC_INDEX);
        String[] args = new String[] { deviceID, serviceIndex, characteristicIndex };
        if (!isNullOrEmpty(args, callbackContext)) {
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (!isConnected(device)) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        JSONObject jsonObject = new JSONObject();
        Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
        JSONArray descriptors = new JSONArray();
        @SuppressWarnings("unchecked")
        List<BluetoothGattDescriptor> listBluetoothGattDescriptors = getCharacteristic(deviceID, serviceIndex,
                characteristicIndex).getDescriptors();
        int length = listBluetoothGattDescriptors.size();
        for (int i = 0; i < length; i++) {
            UUID uuid = listBluetoothGattDescriptors.get(i).getUuid();
            JSONObject descriptor = new JSONObject();
            Tools.addProperty(descriptor, Tools.DESCRIPTOR_INDEX, i);
            Tools.addProperty(descriptor, Tools.DESCRIPTOR_UUID, uuid);
            Tools.addProperty(descriptor, Tools.DESCRIPTOR_NAME, Tools.lookup(uuid));
            descriptors.put(descriptor);
        }
        Tools.addProperty(jsonObject, Tools.DESCRIPTORS, descriptors);
        callbackContext.success(jsonObject);
    }

    @Override
    public void writeValue(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "writeValue");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        String serviceIndex = Tools.getData(json, Tools.SERVICE_INDEX);
        String characteristicIndex = Tools.getData(json, Tools.CHARACTERISTIC_INDEX);
        String descriptorIndex = Tools.getData(json, Tools.DESCRIPTOR_INDEX);
        String writeValue = Tools.getData(json, Tools.WRITE_VALUE);
        String writeType = Tools.getData(json, Tools.WRITE_TYPE);
        String[] args = new String[] { deviceID, serviceIndex, characteristicIndex, writeType, writeValue };
        if (!isNullOrEmpty(args, callbackContext)) {
            return;
        }
        if (descriptorIndex == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (!isConnected(device)) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        byte[] value = Tools.parsingCodingFormat(writeValue, writeType);
        if (mapWriteValueCallBack == null) {
            mapWriteValueCallBack = new HashMap<Object, CallbackContext>();
        }
        if ("".equals(descriptorIndex)) {
            writeCharacteristic(deviceID, serviceIndex, characteristicIndex, value, callbackContext);
        } else {
            writeDescriptor(deviceID, serviceIndex, characteristicIndex, descriptorIndex, value, callbackContext);
        }
    }

    @Override
    public void readValue(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "readValue");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        String serviceIndex = Tools.getData(json, Tools.SERVICE_INDEX);
        String characteristicIndex = Tools.getData(json, Tools.CHARACTERISTIC_INDEX);
        String descriptorIndex = Tools.getData(json, Tools.DESCRIPTOR_INDEX);
        String[] args = new String[] { deviceID, serviceIndex, characteristicIndex };
        if (!isNullOrEmpty(args, callbackContext)) {
            return;
        }
        if (descriptorIndex == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (!isConnected(device)) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        if (mapReadValueCallBack == null) {
            mapReadValueCallBack = new HashMap<Object, CallbackContext>();
        }
        if ("".equals(descriptorIndex)) {
            readCharacteristic(deviceID, serviceIndex, characteristicIndex, callbackContext);
        } else {
            readDescriptor(deviceID, serviceIndex, characteristicIndex, descriptorIndex, callbackContext);
        }
    }

    @Override
    public void setNotification(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "setNotification");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        String serviceIndex = Tools.getData(json, Tools.SERVICE_INDEX);
        String characteristicIndex = Tools.getData(json, Tools.CHARACTERISTIC_INDEX);
        String enable = Tools.getData(json, Tools.ENABLE);
        String[] args = new String[] { deviceID, serviceIndex, characteristicIndex, enable };
        if (!isNullOrEmpty(args, callbackContext)) {
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (!isConnected(device)) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothGattCharacteristic bluetoothGattCharacteristic = getCharacteristic(deviceID, serviceIndex,
                characteristicIndex);
        BluetoothGattDescriptor bluetoothGattDescriptor = bluetoothGattCharacteristic
                .getDescriptor(Tools.NOTIFICATION_UUID);
        if ("true".equalsIgnoreCase(enable)) {
            bluetoothGatt.setCharacteristicNotification(bluetoothGattCharacteristic, true);
            bluetoothGattDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        } else {
            bluetoothGatt.setCharacteristicNotification(bluetoothGattCharacteristic, false);
            bluetoothGattDescriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
        }
        if (mapSetNotificationCallBack == null) {
            mapSetNotificationCallBack = new HashMap<Object, CallbackContext>();
        }
        mapSetNotificationCallBack.put(bluetoothGattCharacteristic, callbackContext);
        boolean result = bluetoothGatt.writeDescriptor(bluetoothGattDescriptor);
        Log.i(TAG, "setNotification is " + result);
    }

    @Override
    public void getDeviceAllData(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "getDeviceAllData");
        if (!isInitialized(callbackContext)) {
            return;
        }
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        if (deviceID == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (!isConnected(device)) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        if (mapDeviceServices == null) {
            mapDeviceServices = new HashMap<String, List<BluetoothGattService>>();
        }
        if (mapGetDeviceAllDataCallBack == null) {
            mapGetDeviceAllDataCallBack = new HashMap<String, CallbackContext>();
        }
        mapGetDeviceAllDataCallBack.put(deviceID, callbackContext);
        bluetoothGatt.discoverServices(device);
    }

    @Override
    public void addServices(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "addService");
        JSONObject jsonServices = Tools.getObjectFromArray(json);
        JSONArray jsonArray = Tools.getArray(json, Tools.SERVICES);
        if (mapRemoteServices == null) {
            mapRemoteServices = new HashMap<String, BluetoothGattService>();
        }
        addServiceCallBack = callbackContext;
        serviceNumber = jsonServices.length();
        for (int i = 0; i < jsonServices.length(); i++) {
            String serviceIndex = Tools.getData(jsonArray, Tools.UINQUE_ID);
            String serviceType = Tools.getData(jsonArray, Tools.SERVICE_TYPE);
            String strServiceUUID = Tools.getData(jsonArray, Tools.SERVICE_UUID);
            String[] args = new String[] { serviceIndex, serviceType, strServiceUUID };
            if (!isNullOrEmpty(args, callbackContext)) {
                return;
            }
            UUID serviceUUID = UUID.fromString(strServiceUUID);
            MutableBluetoothGattService bluetoothGattService = createService(serviceUUID, serviceType);
            JSONArray jsonCharacteristics = Tools.getArray(jsonArray, Tools.CHARACTERISTICS);
            addCharacteristics(bluetoothGattService, jsonCharacteristics, callbackContext);
            if (bluetoothGattServer.addService(bluetoothGattService)) {
                mapRemoteServices.put(serviceIndex, bluetoothGattService);
            }
        }

    }

    private void addCharacteristics(MutableBluetoothGattService bluetoothGattService, JSONArray jsonCharacteristics,
            CallbackContext callbackContext) {
        int characterLength = jsonCharacteristics.length();
        for (int j = 0; j < characterLength; j++) {
            String characteristicValueType = Tools.getData(jsonCharacteristics, j, Tools.CHARACTERISTIC_VALUE_TYPE);
            String characteristicValue = Tools.getData(jsonCharacteristics, j, Tools.CHARACTERISTIC_VALUE);
            String strCharacteristicUUID = Tools.getData(jsonCharacteristics, j, Tools.CHARACTERISTIC_UUID);
            String[] args = new String[] { characteristicValueType, characteristicValue, strCharacteristicUUID };
            if (!isNullOrEmpty(args, callbackContext)) {
                return;
            }
            UUID characteristicUUID = UUID.fromString(strCharacteristicUUID);
            int characterProperty = Tools
                    .encodeProperty(Tools.getArray(jsonCharacteristics, j, Tools.CHARACTERISTIC_PROPERTY));
            int characterPermission = Tools
                    .encodePermission(Tools.getArray(jsonCharacteristics, j, Tools.CHARACTERISTIC_PERMISSION));
            MutableBluetoothGattCharacteristic bluetoothGattCharacteristic = createCharacteristic(
                    characteristicUUID, characterProperty, characterPermission, characteristicValueType,
                    characteristicValue);
            JSONArray jsonDescriptors = Tools.getArray(jsonCharacteristics, j, Tools.DESCRIPTORS);
            addDescriptors(bluetoothGattCharacteristic, jsonDescriptors, callbackContext);
            bluetoothGattService.addCharacteristic(bluetoothGattCharacteristic);
        }
    }

    private void addDescriptors(MutableBluetoothGattCharacteristic bluetoothGattCharacteristic,
            JSONArray jsonDescriptors, CallbackContext callbackContext) {
        int descLength = jsonDescriptors.length();
        for (int k = 0; k < descLength; k++) {
            String descriptorValue = Tools.getData(jsonDescriptors, k, Tools.DESCRIPTOR_VALUE);
            String strDescriptorUUID = Tools.getData(jsonDescriptors, k, Tools.DESCRIPTOR_UUID);
            String descriptorValueType = Tools.getData(jsonDescriptors, k, Tools.DESCRIPTOR_VALUE_TYPE);
            UUID descriptorsUUID = UUID.fromString(strDescriptorUUID);
            int descriptorsPermission = Tools
                    .encodePermission(Tools.getArray(jsonDescriptors, k, Tools.DESCRIPTOR_PERMISSION));
            MutableBluetoothGattDescriptor bluetoothGattDescriptor = createDescriptor(descriptorsUUID,
                    descriptorsPermission, descriptorValueType, descriptorValue);
            bluetoothGattCharacteristic.addDescriptor(bluetoothGattDescriptor);
        }
    }

    @Override
    public void removeService(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "removeService");
        if (bluetoothGattServer == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        String serviceIndex = Tools.getData(json, Tools.SERVICE_INDEX);
        if ("".equals(serviceIndex)) {
            bluetoothGattServer.clearServices();
            bluetoothGattServer = null;
            Tools.sendSuccessMsg(callbackContext);
        } else {
            bluetoothGattServer.removeService(mapRemoteServices.get(serviceIndex));
            Tools.sendSuccessMsg(callbackContext);
        }
    }

    @Override
    public void getRssi(JSONArray json, CallbackContext callbackContext) {
        Log.i(TAG, "getRssi");
        String deviceID = Tools.getData(json, Tools.DEVICE_ID);
        if (deviceID == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceID);
        if (!isConnected(device)) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        if (mapGetRssiCallBack == null) {
            mapGetRssiCallBack = new HashMap<String, CallbackContext>();
        }
        if (mapRssiData == null) {
            mapRssiData = new HashMap<String, Integer>();
        }
        mapGetRssiCallBack.put(deviceID, callbackContext);
        bluetoothGatt.readRemoteRssi(device);
    }

    private MutableBluetoothGattService createService(UUID uuid, String serviceType) {
        int type = -1;
        if ("0".equals(serviceType)) {
            type = BluetoothGattService.SERVICE_TYPE_PRIMARY;
        } else {
            type = BluetoothGattService.SERVICE_TYPE_SECONDARY;
        }
        return new MutableBluetoothGattService(uuid, type);
    }

    private MutableBluetoothGattCharacteristic createCharacteristic(UUID uuid, int property, int permission,
            String valueType, String value) {
        MutableBluetoothGattCharacteristic bluetoothGattCharacteristic = new MutableBluetoothGattCharacteristic(
                uuid, property, permission);
        byte[] charValue = Tools.parsingCodingFormat(value, valueType);
        bluetoothGattCharacteristic.setValue(charValue);
        return bluetoothGattCharacteristic;
    }

    private MutableBluetoothGattDescriptor createDescriptor(UUID uuid, int permission, String valueType,
            String value) {
        MutableBluetoothGattDescriptor bluetoothGattDescriptor = new MutableBluetoothGattDescriptor(uuid,
                permission);
        byte[] desValue = Tools.parsingCodingFormat(value, valueType);
        bluetoothGattDescriptor.setValue(desValue);
        return bluetoothGattDescriptor;
    }

    private boolean writeCharacteristic(String deviceID, String serviceIndex, String characteristicIndex,
            byte[] value, CallbackContext callbackContext) {
        BluetoothGattCharacteristic bluetoothGattCharacteristic = getCharacteristic(deviceID, serviceIndex,
                characteristicIndex);
        mapWriteValueCallBack.put(bluetoothGattCharacteristic, callbackContext);
        bluetoothGattCharacteristic.setValue(value);
        return bluetoothGatt.writeCharacteristic(bluetoothGattCharacteristic);
    }

    private boolean writeDescriptor(String deviceID, String serviceIndex, String characteristicIndex,
            String descriptorIndex, byte[] value, CallbackContext callbackContext) {
        BluetoothGattDescriptor bluetoothGattDescriptor = getDescriptor(deviceID, serviceIndex, characteristicIndex,
                descriptorIndex);
        mapWriteValueCallBack.put(bluetoothGattDescriptor, callbackContext);
        bluetoothGattDescriptor.setValue(value);
        return bluetoothGatt.writeDescriptor(bluetoothGattDescriptor);
    }

    private boolean readCharacteristic(String deviceID, String serviceIndex, String characteristicIndex,
            CallbackContext callbackContext) {
        BluetoothGattCharacteristic bluetoothGattCharacteristic = getCharacteristic(deviceID, serviceIndex,
                characteristicIndex);
        mapReadValueCallBack.put(bluetoothGattCharacteristic, callbackContext);
        return bluetoothGatt.readCharacteristic(bluetoothGattCharacteristic);
    }

    private boolean readDescriptor(String deviceID, String serviceIndex, String characteristicIndex,
            String descriptorIndex, CallbackContext callbackContext) {
        BluetoothGattDescriptor bluetoothGattDescriptor = getDescriptor(deviceID, serviceIndex, characteristicIndex,
                descriptorIndex);
        mapReadValueCallBack.put(bluetoothGattDescriptor, callbackContext);
        return bluetoothGatt.readDescriptor(bluetoothGattDescriptor);
    }

    private BluetoothGattDescriptor getDescriptor(String deviceID, String serviceIndex, String characteristicIndex,
            String descriptorIndex) {
        return (BluetoothGattDescriptor) getCharacteristic(deviceID, serviceIndex, characteristicIndex)
                .getDescriptors().get(Integer.parseInt(descriptorIndex));
    }

    private BluetoothGattCharacteristic getCharacteristic(String deviceID, String serviceIndex,
            String characteristicIndex) {
        return (BluetoothGattCharacteristic) getService(deviceID, serviceIndex).getCharacteristics()
                .get(Integer.parseInt(characteristicIndex));
    }

    private BluetoothGattService getService(String deviceID, String serviceIndex) {
        return mapDeviceServices.get(deviceID).get(Integer.parseInt(serviceIndex));
    }

    private String getDeviceID(BluetoothGattService service) {
        String deviceID = "";
        Iterator<Entry<String, List<BluetoothGattService>>> it = mapDeviceServices.entrySet().iterator();
        while (it.hasNext()) {
            Entry<String, List<BluetoothGattService>> bluetoothEntry = it.next();
            if (bluetoothEntry.getValue().contains(service)) {
                deviceID = bluetoothEntry.getKey();
                break;
            }
        }
        return deviceID;
    }

    private String getServiceIndex(BluetoothGattService service) {
        String serviceIndex = "";
        Iterator<Entry<String, List<BluetoothGattService>>> it = mapDeviceServices.entrySet().iterator();
        while (it.hasNext()) {
            List<BluetoothGattService> bluetoothGattServices = it.next().getValue();
            int index = bluetoothGattServices.indexOf(service);
            if (index != -1) {
                serviceIndex = String.valueOf(index);
                break;
            }
        }
        return serviceIndex;
    }

    private String getCharacteristicIndex(BluetoothGattService service,
            BluetoothGattCharacteristic characteristic) {
        return String.valueOf(service.getCharacteristics().indexOf(characteristic));
    }

    private BluetoothProfile.ServiceListener serviceListener = new ServiceListener() {

        @Override
        public void onServiceDisconnected(int profile) {
            if (null != bluetoothGatt) {
                bluetoothGatt.unregisterApp();
                bluetoothGatt = null;
            }
            if (null != bluetoothGattServer) {
                bluetoothGattServer.unregisterApp();
                bluetoothGattServer = null;
            }
        }

        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if ((proxy instanceof BluetoothGatt) && bluetoothGatt == null) {
                bluetoothGatt = (BluetoothGatt) proxy;
                bluetoothGatt.registerApp(bluetoothGattCallback);
            }
            if ((proxy instanceof BluetoothGattServer) && bluetoothGattServer == null) {
                bluetoothGattServer = (BluetoothGattServer) proxy;
                bluetoothGattServer.registerApp(bluetoothGattServerCallback);
            }
        }
    };

    private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {

        @Override
        public void onCharacteristicChanged(BluetoothGattCharacteristic characteristic) {
            Log.i(TAG, "onCharacteristicChanged");
            super.onCharacteristicChanged(characteristic);
            String deviceID = getDeviceID(characteristic.getService());
            CallbackContext callbackContext = null;
            if (mapSetNotificationCallBack != null) {
                callbackContext = mapSetNotificationCallBack.get(characteristic);
            }
            if (callbackContext != null) {
                JSONObject jsonObject = new JSONObject();
                Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
                Tools.addProperty(jsonObject, Tools.SERVICE_INDEX, getServiceIndex(characteristic.getService()));
                Tools.addProperty(jsonObject, Tools.CHARACTERISTIC_INDEX,
                        getCharacteristicIndex(characteristic.getService(), characteristic));
                Tools.addProperty(jsonObject, Tools.VALUE, Tools.encodeBase64(characteristic.getValue()));
                Tools.addProperty(jsonObject, Tools.DATE, Tools.getDateString());
                PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, jsonObject);
                pluginResult.setKeepCallback(true);
                callbackContext.sendPluginResult(pluginResult);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGattCharacteristic characteristic, int status) {
            Log.i(TAG, "onCharacteristicRead");
            super.onCharacteristicRead(characteristic, status);
            String deviceID = getDeviceID(characteristic.getService());
            CallbackContext callbackContext = null;
            if (mapReadValueCallBack != null) {
                callbackContext = mapReadValueCallBack.get(characteristic);
            }
            if (callbackContext != null) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    JSONObject jsonObject = new JSONObject();
                    Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
                    Tools.addProperty(jsonObject, Tools.VALUE, Tools.encodeBase64(characteristic.getValue()));
                    Tools.addProperty(jsonObject, Tools.DATE, Tools.getDateString());
                    callbackContext.success(jsonObject);
                } else {
                    Tools.sendErrorMsg(callbackContext);
                }
                mapReadValueCallBack.remove(deviceID);
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(characteristic, status);
            Log.i(TAG, "onCharacteristicWrite");
            String deviceID = getDeviceID(characteristic.getService());
            CallbackContext callbackContext = mapWriteValueCallBack.get(characteristic);
            if (callbackContext != null) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    Tools.sendSuccessMsg(callbackContext);
                } else {
                    Tools.sendErrorMsg(callbackContext);
                }
                mapWriteValueCallBack.remove(deviceID);
            }
        }

        @Override
        public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
            super.onConnectionStateChange(device, status, newState);
            Log.i(TAG, "onConnectionStateChange");
            String deviceID = device.getAddress();
            CallbackContext connectCallbackContext = null;
            CallbackContext disConnectCallbackContext = null;
            JSONObject jsonObject = new JSONObject();
            if (mapConnectCallBack != null) {
                connectCallbackContext = mapConnectCallBack.get(deviceID);
            }
            if (mapDisconnectCallBack != null) {
                disConnectCallbackContext = mapDisconnectCallBack.get(deviceID);
            }
            if (disConnectCallbackContext == null && mapAddListenerCallBack != null) {
                disConnectCallbackContext = mapAddListenerCallBack.get(Tools.DISCONNECT);
            }
            if (connectCallbackContext != null) {
                if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
                    Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
                    Tools.addProperty(jsonObject, Tools.MES, Tools.SUCCESS);
                    connectCallbackContext.success(jsonObject);
                } else {
                    Tools.sendErrorMsg(connectCallbackContext);
                }
                mapConnectCallBack.remove(deviceID);
                return;
            }
            if (disConnectCallbackContext != null) {
                Log.i(TAG, "device: " + deviceID + " disconnect!");
                if (newState == BluetoothProfile.STATE_DISCONNECTED && status == BluetoothGatt.GATT_SUCCESS) {
                    Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
                    Tools.addProperty(jsonObject, Tools.MES, Tools.SUCCESS);
                    PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, jsonObject);
                    pluginResult.setKeepCallback(true);
                    disConnectCallbackContext.sendPluginResult(pluginResult);
                } else {
                    Tools.sendErrorMsg(disConnectCallbackContext);
                }
                mapDisconnectCallBack.remove(deviceID);
            }
        }

        @Override
        public void onReadRemoteRssi(BluetoothDevice device, int rssi, int status) {
            super.onReadRemoteRssi(device, rssi, status);
            Log.i(TAG, "onReadRemoteRssi");
            String deviceID = device.getAddress();
            CallbackContext callbackContext = null;
            if (mapGetRssiCallBack != null) {
                callbackContext = mapGetRssiCallBack.get(deviceID);
            }
            if (callbackContext != null) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    JSONObject jsonObject = new JSONObject();
                    Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
                    Tools.addProperty(jsonObject, Tools.RSSI, Integer.toString(rssi));
                    callbackContext.success(jsonObject);
                } else {
                    Tools.sendErrorMsg(callbackContext);
                }
                mapGetRssiCallBack.remove(deviceID);
            }
        }

        @Override
        public void onDescriptorRead(BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorRead(descriptor, status);
            Log.i(TAG, "onDescriptorRead");
            String deviceID = getDeviceID(descriptor.getCharacteristic().getService());
            CallbackContext callbackContext = mapReadValueCallBack.get(deviceID);
            if (callbackContext != null) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    JSONObject jsonObject = new JSONObject();
                    Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
                    Tools.addProperty(jsonObject, Tools.VALUE, Tools.encodeBase64(descriptor.getValue()));
                    Tools.addProperty(jsonObject, Tools.DATE, Tools.getDateString());
                    callbackContext.success(jsonObject);
                } else {
                    Tools.sendErrorMsg(callbackContext);
                }
                mapReadValueCallBack.remove(deviceID);
            }
        }

        @Override
        public void onDescriptorWrite(BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(descriptor, status);
            Log.i(TAG, "onDescriptorWrite");
            String deviceID = getDeviceID(descriptor.getCharacteristic().getService());
            CallbackContext writeValueCallbackContext = null;
            if (mapWriteValueCallBack != null) {
                writeValueCallbackContext = mapWriteValueCallBack.get(descriptor);
            }
            if (writeValueCallbackContext != null) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    Tools.sendSuccessMsg(writeValueCallbackContext);
                } else {
                    Tools.sendErrorMsg(writeValueCallbackContext);
                }
                mapWriteValueCallBack.remove(deviceID);
            }

        }

        @Override
        public void onServicesDiscovered(BluetoothDevice device, int status) {
            super.onServicesDiscovered(device, status);
            Log.i(TAG, "onServicesDiscovered");
            String deviceID = device.getAddress();
            @SuppressWarnings("unchecked")
            List<BluetoothGattService> listServices = bluetoothGatt.getServices(device);
            JSONObject jsonObject = new JSONObject();
            Tools.addProperty(jsonObject, Tools.DEVICE_ID, deviceID);
            JSONArray services = new JSONArray();
            int index = 0;
            for (Iterator<BluetoothGattService> it = listServices.iterator(); it.hasNext();) {
                BluetoothGattService bluetoothGattService = it.next();
                UUID uuid = bluetoothGattService.getUuid();
                JSONObject service = new JSONObject();
                Tools.addProperty(service, Tools.SERVICE_INDEX, index++);
                Tools.addProperty(service, Tools.SERVICE_UUID, uuid);
                Tools.addProperty(service, Tools.SERVICE_NAME, Tools.lookup(uuid));
                services.put(service);
            }
            Tools.addProperty(jsonObject, Tools.SERVICES, services);
            if (mapDeviceServices == null) {
                mapDeviceServices = new HashMap<String, List<BluetoothGattService>>();
            }
            mapDeviceServices.put(deviceID, listServices);
            CallbackContext getServicesCallback = null;
            CallbackContext getDeviceAllDataCallback = null;
            if (mapGetServicesCallBack != null) {
                getServicesCallback = mapGetServicesCallBack.get(deviceID);
            }
            if (mapGetDeviceAllDataCallBack != null) {
                getDeviceAllDataCallback = mapGetDeviceAllDataCallBack.get(deviceID);
            }
            int serviceLength = listServices.size();
            if (getServicesCallback != null) {
                getServicesCallback.success(jsonObject);
                mapGetServicesCallBack.remove(deviceID);
            }
            if (getDeviceAllDataCallback != null) {
                JSONArray deviceAllData = null;
                try {
                    deviceAllData = jsonObject.getJSONArray(Tools.SERVICES);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                for (int i = 0; i < serviceLength; i++) {
                    JSONObject service = null;
                    try {
                        service = (JSONObject) deviceAllData.get(i);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    JSONArray characteristics = new JSONArray();
                    @SuppressWarnings("unchecked")
                    List<BluetoothGattCharacteristic> bluetoothGattCharacteristics = getService(deviceID,
                            Integer.toString(i)).getCharacteristics();
                    int charaLength = bluetoothGattCharacteristics.size();
                    for (int j = 0; j < charaLength; j++) {
                        JSONObject characteristic = new JSONObject();
                        BluetoothGattCharacteristic bluetoothGattCharacteristic = bluetoothGattCharacteristics
                                .get(j);
                        UUID uuid = bluetoothGattCharacteristic.getUuid();
                        Tools.addProperty(characteristic, Tools.CHARACTERISTIC_UUID, uuid);
                        Tools.addProperty(characteristic, Tools.CHARACTERISTIC_INDEX, j);
                        Tools.addProperty(characteristic, Tools.CHARACTERISTIC_NAME, Tools.lookup(uuid));
                        Tools.addProperty(characteristic, Tools.CHARACTERISTIC_PROPERTY,
                                Tools.decodeProperty(bluetoothGattCharacteristic.getProperties()));
                        JSONArray descriptors = new JSONArray();
                        @SuppressWarnings("unchecked")
                        List<BluetoothGattDescriptor> listDescriptors = bluetoothGattCharacteristic
                                .getDescriptors();
                        for (int k = 0; k < listDescriptors.size(); k++) {
                            JSONObject descriptor = new JSONObject();
                            BluetoothGattDescriptor bluetoothGattDescriptor = listDescriptors.get(k);
                            UUID descriptorUUID = bluetoothGattDescriptor.getUuid();
                            Tools.addProperty(descriptor, Tools.DESCRIPTOR_UUID, descriptorUUID);
                            Tools.addProperty(descriptor, Tools.DESCRIPTOR_INDEX, k);
                            Tools.addProperty(descriptor, Tools.DESCRIPTOR_NAME, Tools.lookup(descriptorUUID));
                            descriptors.put(descriptor);
                        }
                        Tools.addProperty(characteristic, Tools.DESCRIPTORS, descriptors);
                        characteristics.put(characteristic);
                    }
                    Tools.addProperty(service, Tools.CHARACTERISTICS, characteristics);
                }
                Tools.addProperty(jsonObject, Tools.SERVICES, deviceAllData);
                getDeviceAllDataCallback.success(jsonObject);
                mapGetDeviceAllDataCallBack.remove(deviceID);
            }
        }

        @Override
        public void onScanResult(BluetoothDevice device, int rssi, byte[] scanRecord) {
            super.onScanResult(device, rssi, scanRecord);
            Log.i(TAG, "onScanResult");
            if (!bluetoothDevices.contains(device)) {
                String deviceID = device.getAddress();
                bluetoothDevices.add(device);
                mapRssiData.put(deviceID, rssi);
                mapDeviceAdvData.put(deviceID, scanRecord);
            }
        }
    };

    private BluetoothGattServerCallback bluetoothGattServerCallback = new BluetoothGattServerCallback() {

        @Override
        public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset,
                BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
            Log.i(TAG, "onCharacteristicReadRequest");
        }

        @Override
        public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
                BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded,
                int offset, byte[] value) {
            super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded,
                    offset, value);
            Log.i(TAG, "onCharacteristicWriteRequest");
        }

        @Override
        public void onServiceAdded(int status, BluetoothGattService bluetoothGattService) {
            super.onServiceAdded(status, bluetoothGattService);
            Log.i(TAG, "onServiceAdded");
            if (status == BluetoothGatt.GATT_SUCCESS) {
                addedServiceNumber++;
                if (addedServiceNumber == serviceNumber) {
                    if (addServiceCallBack != null) {
                        Tools.sendSuccessMsg(addServiceCallBack);
                    }
                    addedServiceNumber = 0;
                }
            }
        }
    };

    private boolean isInitialized(CallbackContext callbackContext) {
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled() || bluetoothGatt == null) {
            Tools.sendErrorMsg(callbackContext);
            return false;
        }
        return true;
    }

    private boolean isConnected(BluetoothDevice device) {
        if (device == null) {
            return false;
        }
        return bluetoothGatt.getConnectedDevices().contains(device)
                && bluetoothGatt.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED;
    }

    @Override
    public void addEventListener(JSONArray json, CallbackContext callbackContext) {
        String eventName = Tools.getData(json, Tools.EVENT_NAME);
        if (eventName == null) {
            Tools.sendErrorMsg(callbackContext);
            return;
        }
        if (mapAddListenerCallBack == null) {
            mapAddListenerCallBack = new HashMap<String, CallbackContext>();
        }
        mapAddListenerCallBack.put(eventName, callbackContext);
    }

    private boolean isNullOrEmpty(String[] args, CallbackContext callbackContext) {
        if (args == null) {
            Tools.sendErrorMsg(callbackContext);
            return false;
        }
        int length = args.length;
        for (int i = 0; i < length; i++) {
            String str = args[i];
            if (str == null || str.isEmpty()) {
                Tools.sendErrorMsg(callbackContext);
                return false;
            }
        }
        return true;
    }

}