Repository: xpg/GizwitsBLE
Branch: master
Commit: 82300009aff2
Files: 47
Total size: 167.2 KB
Directory structure:
gitextract_x58tzomf/
├── .gitignore
├── BleLibrary/
│ ├── .classpath
│ ├── .project
│ ├── AndroidManifest.xml
│ ├── libs/
│ │ ├── com.broadcom.bt.jar
│ │ ├── commons-codec-1.8.jar
│ │ └── samsung_ble_sdk_200.jar
│ ├── proguard-project.txt
│ ├── proguard.pro
│ ├── project.properties
│ ├── res/
│ │ ├── values/
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v11/
│ │ │ └── styles.xml
│ │ └── values-v14/
│ │ └── styles.xml
│ └── src/
│ └── com/
│ └── xtremeprog/
│ └── sdk/
│ └── ble/
│ ├── AndroidBle.java
│ ├── BleGattCharacteristic.java
│ ├── BleGattService.java
│ ├── BleRequest.java
│ ├── BleService.java
│ ├── BroadcomBle.java
│ ├── IBle.java
│ ├── IBleRequestHandler.java
│ └── SamsungBle.java
├── BluetoothLeGatt/
│ ├── .classpath
│ ├── .project
│ ├── AndroidManifest.xml
│ ├── libs/
│ │ ├── com.broadcom.bt.jar
│ │ ├── commons-codec-1.8.jar
│ │ └── samsung_ble_sdk_200.jar
│ ├── project.properties
│ ├── res/
│ │ ├── layout/
│ │ │ ├── actionbar_indeterminate_progress.xml
│ │ │ ├── activity_characteristic.xml
│ │ │ ├── gatt_services_characteristics.xml
│ │ │ └── listitem_device.xml
│ │ ├── menu/
│ │ │ ├── characteristic.xml
│ │ │ ├── gatt_services.xml
│ │ │ └── main.xml
│ │ ├── values/
│ │ │ ├── dimens.xml
│ │ │ └── strings.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ └── src/
│ └── com/
│ └── example/
│ └── bluetooth/
│ └── le/
│ ├── BleApplication.java
│ ├── CharacteristicActivity.java
│ ├── DeviceControlActivity.java
│ ├── DeviceScanActivity.java
│ └── Utils.java
├── LICENSE
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
================================================
FILE: BleLibrary/.classpath
================================================
================================================
FILE: BleLibrary/.project
================================================
BleLibrarycom.android.ide.eclipse.adt.ResourceManagerBuildercom.android.ide.eclipse.adt.PreCompilerBuilderorg.eclipse.jdt.core.javabuildercom.android.ide.eclipse.adt.ApkBuildercom.android.ide.eclipse.adt.AndroidNatureorg.eclipse.jdt.core.javanature
================================================
FILE: BleLibrary/AndroidManifest.xml
================================================
================================================
FILE: BleLibrary/proguard-project.txt
================================================
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: BleLibrary/proguard.pro
================================================
-injars bin/blelibrary.jar
-outjars bin/blelibrary-0.1.jar
-libraryjars /Users/teamx/bin/adt-bundle-mac-x86_64-20130917/sdk/platforms/android-18/android.jar
-libraryjars libs/com.broadcom.bt.jar
-libraryjars libs/commons-codec-1.8.jar
-libraryjars libs/samsung_ble_sdk_200.jar
-target 1.6
-useuniqueclassmembernames
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
-renamesourcefileattribute SourceFile
-adaptresourcefilenames **.properties
-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF
-verbose
# Keep - Library. Keep all public and protected classes, fields, and methods.
-keep public class * {
public protected ;
public protected ;
}
# Also keep - Enumerations. Keep the special static methods that are required in
# enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Keep names - Native method names. Keep all native class/method names.
-keepclasseswithmembers,allowshrinking class * {
native ;
}
================================================
FILE: BleLibrary/project.properties
================================================
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-19
android.library=true
================================================
FILE: BleLibrary/res/values/strings.xml
================================================
BleLibrary
================================================
FILE: BleLibrary/res/values/styles.xml
================================================
================================================
FILE: BleLibrary/res/values-v11/styles.xml
================================================
================================================
FILE: BleLibrary/res/values-v14/styles.xml
================================================
================================================
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/AndroidBle.java
================================================
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.xtremeprog.sdk.ble;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.codec.binary.Hex;
import android.annotation.SuppressLint;
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.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;
import com.xtremeprog.sdk.ble.BleRequest.RequestType;
@SuppressLint("NewApi")
public class AndroidBle implements IBle, IBleRequestHandler {
protected static final String TAG = "blelib";
private BleService mService;
private BluetoothAdapter mBtAdapter;
private Map mBluetoothGatts;
// private BTQuery btQuery;
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
mService.bleDeviceFound(device, rssi, scanRecord,
BleService.DEVICE_SOURCE_SCAN);
}
};
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
String address = gatt.getDevice().getAddress();
Log.d(TAG, "onConnectionStateChange " + address + " status "
+ status + " newState " + newState);
if (status != BluetoothGatt.GATT_SUCCESS) {
disconnect(address);
mService.bleGattDisConnected(address);
return;
}
if (newState == BluetoothProfile.STATE_CONNECTED) {
mService.bleGattConnected(gatt.getDevice());
mService.addBleRequest(new BleRequest(
RequestType.DISCOVER_SERVICE, address));
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mService.bleGattDisConnected(address);
disconnect(address);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
String address = gatt.getDevice().getAddress();
Log.d(TAG, "onServicesDiscovered " + address + " status " + status);
if (status != BluetoothGatt.GATT_SUCCESS) {
mService.requestProcessed(address,
RequestType.DISCOVER_SERVICE, false);
return;
}
mService.bleServiceDiscovered(gatt.getDevice().getAddress());
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
String address = gatt.getDevice().getAddress();
Log.d(TAG, "onCharacteristicRead " + address + " status " + status);
if (status != BluetoothGatt.GATT_SUCCESS) {
mService.requestProcessed(address,
RequestType.READ_CHARACTERISTIC, false);
return;
}
// Log.d(TAG, "data " + characteristic.getStringValue(0));
mService.bleCharacteristicRead(gatt.getDevice().getAddress(),
characteristic.getUuid().toString(), status,
characteristic.getValue());
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
String address = gatt.getDevice().getAddress();
Log.d(TAG, "onCharacteristicChanged " + address);
Log.d(TAG, new String(Hex.encodeHex(characteristic.getValue())));
mService.bleCharacteristicChanged(address, characteristic.getUuid()
.toString(), characteristic.getValue());
}
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
String address = gatt.getDevice().getAddress();
Log.d(TAG, "onCharacteristicWrite " + address + " status " + status);
if (status != BluetoothGatt.GATT_SUCCESS) {
mService.requestProcessed(address,
RequestType.WRITE_CHARACTERISTIC, false);
return;
}
mService.bleCharacteristicWrite(gatt.getDevice().getAddress(),
characteristic.getUuid().toString(), status);
};
public void onDescriptorWrite(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status) {
String address = gatt.getDevice().getAddress();
Log.d(TAG, "onDescriptorWrite " + address + " status " + status);
BleRequest request = mService.getCurrentRequest();
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION
|| request.type == RequestType.CHARACTERISTIC_INDICATION
|| request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) {
if (status != BluetoothGatt.GATT_SUCCESS) {
mService.requestProcessed(address,
RequestType.CHARACTERISTIC_NOTIFICATION, false);
return;
}
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), true,
status);
} else if (request.type == RequestType.CHARACTERISTIC_INDICATION) {
mService.bleCharacteristicIndication(address, descriptor
.getCharacteristic().getUuid().toString(), status);
} else {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), false,
status);
}
return;
}
};
};
public AndroidBle(BleService service) {
mService = service;
// btQuery = BTQuery.getInstance();
if (!mService.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH_LE)) {
mService.bleNotSupported();
return;
}
final BluetoothManager bluetoothManager = (BluetoothManager) mService
.getSystemService(Context.BLUETOOTH_SERVICE);
mBtAdapter = bluetoothManager.getAdapter();
if (mBtAdapter == null) {
mService.bleNoBtAdapter();
}
mBluetoothGatts = new HashMap();
}
@Override
public void startScan() {
mBtAdapter.startLeScan(mLeScanCallback);
}
@Override
public void stopScan() {
mBtAdapter.stopLeScan(mLeScanCallback);
}
@Override
public boolean adapterEnabled() {
if (mBtAdapter != null) {
return mBtAdapter.isEnabled();
}
return false;
}
@Override
public boolean connect(String address) {
BluetoothDevice device = mBtAdapter.getRemoteDevice(address);
BluetoothGatt gatt = device.connectGatt(mService, false, mGattCallback);
if (gatt == null) {
mBluetoothGatts.remove(address);
return false;
} else {
// TODO: if state is 141, it can be connected again after about 15
// seconds
mBluetoothGatts.put(address, gatt);
return true;
}
}
@Override
public void disconnect(String address) {
if (mBluetoothGatts.containsKey(address)) {
BluetoothGatt gatt = mBluetoothGatts.remove(address);
if (gatt != null) {
gatt.disconnect();
gatt.close();
}
}
}
@Override
public ArrayList getServices(String address) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null) {
return null;
}
ArrayList list = new ArrayList();
List services = gatt.getServices();
for (BluetoothGattService s : services) {
BleGattService service = new BleGattService(s);
// service.setInfo(btQuery.getGattServiceInfo(s.getUuid()));
list.add(service);
}
return list;
}
@Override
public boolean requestReadCharacteristic(String address,
BleGattCharacteristic characteristic) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null || characteristic == null) {
return false;
}
mService.addBleRequest(new BleRequest(RequestType.READ_CHARACTERISTIC,
gatt.getDevice().getAddress(), characteristic));
return true;
}
public boolean readCharacteristic(String address,
BleGattCharacteristic characteristic) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null) {
return false;
}
return gatt.readCharacteristic(characteristic.getGattCharacteristicA());
}
@Override
public boolean discoverServices(String address) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null) {
return false;
}
boolean ret = gatt.discoverServices();
if (!ret) {
disconnect(address);
}
return ret;
}
@Override
public BleGattService getService(String address, UUID uuid) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null) {
return null;
}
BluetoothGattService service = gatt.getService(uuid);
if (service == null) {
return null;
} else {
return new BleGattService(service);
}
}
@Override
public boolean requestCharacteristicNotification(String address,
BleGattCharacteristic characteristic) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null || characteristic == null) {
return false;
}
mService.addBleRequest(new BleRequest(
RequestType.CHARACTERISTIC_NOTIFICATION, gatt.getDevice()
.getAddress(), characteristic));
return true;
}
@Override
public boolean characteristicNotification(String address,
BleGattCharacteristic characteristic) {
BleRequest request = mService.getCurrentRequest();
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null || characteristic == null) {
return false;
}
boolean enable = true;
if (request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) {
enable = false;
}
BluetoothGattCharacteristic c = characteristic.getGattCharacteristicA();
if (!gatt.setCharacteristicNotification(c, enable)) {
return false;
}
BluetoothGattDescriptor descriptor = c
.getDescriptor(BleService.DESC_CCC);
if (descriptor == null) {
return false;
}
byte[] val_set = null;
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) {
val_set = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
} else if (request.type == RequestType.CHARACTERISTIC_INDICATION) {
val_set = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE;
} else {
val_set = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
}
if (!descriptor.setValue(val_set)) {
return false;
}
return gatt.writeDescriptor(descriptor);
}
@Override
public boolean requestWriteCharacteristic(String address,
BleGattCharacteristic characteristic, String remark) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null || characteristic == null) {
return false;
}
mService.addBleRequest(new BleRequest(RequestType.WRITE_CHARACTERISTIC,
gatt.getDevice().getAddress(), characteristic, remark));
return true;
}
@Override
public boolean writeCharacteristic(String address,
BleGattCharacteristic characteristic) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null) {
return false;
}
Log.d("blelib", new String(Hex.encodeHex(characteristic.getGattCharacteristicA().getValue())));
return gatt
.writeCharacteristic(characteristic.getGattCharacteristicA());
}
@Override
public boolean requestConnect(String address) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt != null && gatt.getServices().size() == 0) {
return false;
}
mService.addBleRequest(new BleRequest(RequestType.CONNECT_GATT, address));
return true;
}
@Override
public String getBTAdapterMacAddr() {
if (mBtAdapter != null) {
return mBtAdapter.getAddress();
}
return null;
}
@Override
public boolean requestIndication(String address,
BleGattCharacteristic characteristic) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null || characteristic == null) {
return false;
}
mService.addBleRequest(new BleRequest(
RequestType.CHARACTERISTIC_INDICATION, gatt.getDevice()
.getAddress(), characteristic));
return true;
}
@Override
public boolean requestStopNotification(String address,
BleGattCharacteristic characteristic) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null || characteristic == null) {
return false;
}
mService.addBleRequest(new BleRequest(
RequestType.CHARACTERISTIC_NOTIFICATION, gatt.getDevice()
.getAddress(), characteristic));
return true;
}
}
================================================
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleGattCharacteristic.java
================================================
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.xtremeprog.sdk.ble;
import java.util.UUID;
import android.annotation.SuppressLint;
import com.xtremeprog.sdk.ble.BleService.BLESDK;
@SuppressLint("NewApi")
public class BleGattCharacteristic {
public static final int PROPERTY_READ = 2;
public static final int PROPERTY_WRITE = 8;
public static final int PROPERTY_NOTIFY = 16;
public static final int PROPERTY_INDICATE = 32;
/**
* Characteristic value format type uint8
*/
public static final int FORMAT_UINT8 = 0x11;
/**
* Characteristic value format type uint16
*/
public static final int FORMAT_UINT16 = 0x12;
/**
* Characteristic value format type uint24 Note: this is not a standard data
* type!
*/
public static final int FORMAT_UINT24 = 0x13;
/**
* Characteristic value format type uint32
*/
public static final int FORMAT_UINT32 = 0x14;
/**
* Characteristic value format type sint8
*/
public static final int FORMAT_SINT8 = 0x21;
/**
* Characteristic value format type sint16
*/
public static final int FORMAT_SINT16 = 0x22;
/**
* Characteristic value format type sint32
*/
public static final int FORMAT_SINT32 = 0x24;
/**
* Characteristic value format type sfloat (16-bit float)
*/
public static final int FORMAT_SFLOAT = 0x32;
/**
* Characteristic value format type float (32-bit float)
*/
public static final int FORMAT_FLOAT = 0x34;
private android.bluetooth.BluetoothGattCharacteristic mGattCharacteristicA;
private com.broadcom.bt.gatt.BluetoothGattCharacteristic mGattCharacteristicB;
private com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic mGattCharacteristicS;
private BLESDK mBleSDK;
private String name;
public BleGattCharacteristic(android.bluetooth.BluetoothGattCharacteristic c) {
mBleSDK = BLESDK.ANDROID;
setGattCharacteristicA(c);
initInfo();
}
public BleGattCharacteristic(
com.broadcom.bt.gatt.BluetoothGattCharacteristic c) {
mBleSDK = BLESDK.BROADCOM;
setGattCharacteristicB(c);
}
public BleGattCharacteristic(
com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic c) {
mBleSDK = BLESDK.SAMSUNG;
setGattCharacteristicS(c);
}
private void initInfo() {
name = "Unknown characteristic";
}
public UUID getUuid() {
if (mBleSDK == BLESDK.ANDROID) {
return getGattCharacteristicA().getUuid();
} else if (mBleSDK == BLESDK.BROADCOM) {
return getGattCharacteristicB().getUuid();
} else if (mBleSDK == BLESDK.SAMSUNG) {
return getGattCharacteristicS().getUuid();
}
return null;
}
protected android.bluetooth.BluetoothGattCharacteristic getGattCharacteristicA() {
return mGattCharacteristicA;
}
public int getProperties() {
if (mBleSDK == BLESDK.ANDROID) {
return getGattCharacteristicA().getProperties();
} else if (mBleSDK == BLESDK.BROADCOM) {
return getGattCharacteristicB().getProperties();
} else if (mBleSDK == BLESDK.SAMSUNG) {
return getGattCharacteristicS().getProperties();
}
return 0;
}
protected com.broadcom.bt.gatt.BluetoothGattCharacteristic getGattCharacteristicB() {
return mGattCharacteristicB;
}
protected void setGattCharacteristicB(
com.broadcom.bt.gatt.BluetoothGattCharacteristic mBCGattCharacteristic) {
this.mGattCharacteristicB = mBCGattCharacteristic;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean setValue(byte[] val) {
if (mBleSDK == BLESDK.ANDROID) {
return getGattCharacteristicA().setValue(val);
} else if (mBleSDK == BLESDK.SAMSUNG) {
return mGattCharacteristicS.setValue(val);
} else if (mBleSDK == BLESDK.BROADCOM) {
return mGattCharacteristicB.setValue(val);
}
return false;
}
public byte[] getValue() {
if (mBleSDK == BLESDK.ANDROID) {
return getGattCharacteristicA().getValue();
} else if (mBleSDK == BLESDK.SAMSUNG) {
return mGattCharacteristicS.getValue();
} else if (mBleSDK == BLESDK.BROADCOM) {
return mGattCharacteristicB.getValue();
}
return null;
}
public boolean setValue(int value, int formatType, int offset) {
if (mBleSDK == BLESDK.ANDROID) {
return getGattCharacteristicA().setValue(value, formatType, offset);
} else if (mBleSDK == BLESDK.SAMSUNG) {
return mGattCharacteristicS.setValue(value, formatType, offset);
} else if (mBleSDK == BLESDK.BROADCOM) {
return mGattCharacteristicB.setValue(value, formatType, offset);
}
return false;
}
public boolean setValue(int mantissa, int exponent, int formatType,
int offset) {
if (mBleSDK == BLESDK.ANDROID) {
return getGattCharacteristicA().setValue(mantissa, exponent,
formatType, offset);
} else if (mBleSDK == BLESDK.SAMSUNG) {
return mGattCharacteristicS.setValue(mantissa, exponent,
formatType, offset);
} else if (mBleSDK == BLESDK.BROADCOM) {
return mGattCharacteristicB.setValue(mantissa, exponent,
formatType, offset);
}
return false;
}
public boolean setValue(String value) {
return setValue(value.getBytes());
}
public String getStringValue(int offset) {
if (mBleSDK == BLESDK.ANDROID) {
return getGattCharacteristicA().getStringValue(offset);
} else if (mBleSDK == BLESDK.SAMSUNG) {
return mGattCharacteristicS.getStringValue(offset);
} else if (mBleSDK == BLESDK.BROADCOM) {
return mGattCharacteristicB.getStringValue(offset);
}
return null;
}
public Float getFloatValue(int formatType, int offset) {
if (mBleSDK == BLESDK.ANDROID) {
return getGattCharacteristicA().getFloatValue(formatType, offset);
} else if (mBleSDK == BLESDK.SAMSUNG) {
return mGattCharacteristicS.getFloatValue(formatType, offset);
} else if (mBleSDK == BLESDK.BROADCOM) {
return mGattCharacteristicB.getFloatValue(formatType, offset);
}
return null;
}
public Integer getIntValue(int formatType, int offset) {
if (mBleSDK == BLESDK.ANDROID) {
if (formatType == FORMAT_UINT24) {
byte[] value = getGattCharacteristicA().getValue();
return byte2uint24(offset, value);
} else {
return getGattCharacteristicA().getIntValue(formatType, offset);
}
} else if (mBleSDK == BLESDK.SAMSUNG) {
if (formatType == FORMAT_UINT24) {
byte[] value = mGattCharacteristicS.getValue();
return byte2uint24(offset, value);
} else {
return mGattCharacteristicS.getIntValue(formatType, offset);
}
} else if (mBleSDK == BLESDK.BROADCOM) {
if (formatType == FORMAT_UINT24) {
byte[] value = mGattCharacteristicB.getValue();
return byte2uint24(offset, value);
} else {
return mGattCharacteristicB.getIntValue(formatType, offset);
}
}
return null;
}
private Integer byte2uint24(int offset, byte[] value) {
if ((offset + 3) > value.length)
return null;
return Integer.valueOf((value[offset] & 0xFF)
| (value[offset + 1] & 0xFF) << 8
| (value[offset + 2] & 0xFF) << 16);
}
protected com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic getGattCharacteristicS() {
return mGattCharacteristicS;
}
protected void setGattCharacteristicS(
com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic mSSGattCharacteristic) {
this.mGattCharacteristicS = mSSGattCharacteristic;
}
protected void setGattCharacteristicA(
android.bluetooth.BluetoothGattCharacteristic mGattCharacteristicA) {
this.mGattCharacteristicA = mGattCharacteristicA;
}
}
================================================
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleGattService.java
================================================
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.xtremeprog.sdk.ble;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothGattCharacteristic;
import com.xtremeprog.sdk.ble.BleService.BLESDK;
@SuppressLint("NewApi")
public class BleGattService {
private BLESDK mBleSDK;
private com.samsung.android.sdk.bt.gatt.BluetoothGattService mGattServiceS;
private com.broadcom.bt.gatt.BluetoothGattService mGattServiceB;
private android.bluetooth.BluetoothGattService mGattServiceA;
private String mName;
public BleGattService(com.samsung.android.sdk.bt.gatt.BluetoothGattService s) {
mBleSDK = BLESDK.SAMSUNG;
mGattServiceS = s;
initInfo();
}
public BleGattService(com.broadcom.bt.gatt.BluetoothGattService s) {
mBleSDK = BLESDK.BROADCOM;
mGattServiceB = s;
initInfo();
}
public BleGattService(android.bluetooth.BluetoothGattService s) {
mBleSDK = BLESDK.ANDROID;
mGattServiceA = s;
initInfo();
}
private void initInfo() {
mName = "Unknown Service";
}
public UUID getUuid() {
if (mBleSDK == BLESDK.BROADCOM) {
return mGattServiceB.getUuid();
} else if (mBleSDK == BLESDK.SAMSUNG) {
return mGattServiceS.getUuid();
} else if (mBleSDK == BLESDK.ANDROID) {
return mGattServiceA.getUuid();
}
return null;
}
public List getCharacteristics() {
ArrayList list = new ArrayList();
if (mBleSDK == BLESDK.BROADCOM) {
for (com.broadcom.bt.gatt.BluetoothGattCharacteristic c : mGattServiceB
.getCharacteristics()) {
list.add(new BleGattCharacteristic(c));
}
} else if (mBleSDK == BLESDK.SAMSUNG) {
for (Object o : mGattServiceS.getCharacteristics()) {
com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic c = (com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic) o;
list.add(new BleGattCharacteristic(c));
}
} else if (mBleSDK == BLESDK.ANDROID) {
for (android.bluetooth.BluetoothGattCharacteristic c : mGattServiceA
.getCharacteristics()) {
list.add(new BleGattCharacteristic(c));
}
}
return list;
}
public BleGattCharacteristic getCharacteristic(UUID uuid) {
if (mBleSDK == BLESDK.ANDROID) {
BluetoothGattCharacteristic c = mGattServiceA
.getCharacteristic(uuid);
if (c != null) {
return new BleGattCharacteristic(c);
}
} else if (mBleSDK == BLESDK.SAMSUNG) {
com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic c = mGattServiceS
.getCharacteristic(uuid);
if (c != null) {
return new BleGattCharacteristic(c);
}
} else if (mBleSDK == BLESDK.BROADCOM) {
com.broadcom.bt.gatt.BluetoothGattCharacteristic c = mGattServiceB
.getCharacteristic(uuid);
if (c != null) {
return new BleGattCharacteristic(c);
}
}
return null;
}
public void setInfo(JSONObject info) {
if (info == null) {
return;
}
try {
setName(info.getString("name"));
} catch (JSONException e) {
e.printStackTrace();
}
}
public String getName() {
return mName;
}
public void setName(String mName) {
this.mName = mName;
}
}
================================================
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleRequest.java
================================================
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.xtremeprog.sdk.ble;
public class BleRequest {
public enum RequestType {
CONNECT_GATT, DISCOVER_SERVICE, CHARACTERISTIC_NOTIFICATION, CHARACTERISTIC_INDICATION, READ_CHARACTERISTIC, READ_DESCRIPTOR, READ_RSSI, WRITE_CHARACTERISTIC, WRITE_DESCRIPTOR, CHARACTERISTIC_STOP_NOTIFICATION
};
public enum FailReason {
START_FAILED, TIMEOUT, RESULT_FAILED
}
public RequestType type;
public String address;
public BleGattCharacteristic characteristic;
public String remark;
public BleRequest(RequestType type, String address) {
this.type = type;
this.address = address;
}
public BleRequest(RequestType type, String address,
BleGattCharacteristic characteristic) {
this.type = type;
this.address = address;
this.characteristic = characteristic;
}
public BleRequest(RequestType type, String address,
BleGattCharacteristic characteristic, String remark) {
this.type = type;
this.address = address;
this.characteristic = characteristic;
this.remark = remark;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof BleRequest)) {
return false;
}
BleRequest br = (BleRequest) o;
return (this.type == br.type && this.address.equals(br.address));
}
}
================================================
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleService.java
================================================
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.xtremeprog.sdk.ble;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.Queue;
import java.util.UUID;
import android.app.Service;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.xtremeprog.sdk.ble.BleRequest.FailReason;
import com.xtremeprog.sdk.ble.BleRequest.RequestType;
public class BleService extends Service {
private static final String TAG = "blelib";
/** Intent for broadcast */
public static final String BLE_NOT_SUPPORTED = "com.xtremeprog.sdk.ble.not_supported";
public static final String BLE_NO_BT_ADAPTER = "com.xtremeprog.sdk.ble.no_bt_adapter";
public static final String BLE_STATUS_ABNORMAL = "com.xtremeprog.sdk.ble.status_abnormal";
/**
* @see BleService#bleRequestFailed
*/
public static final String BLE_REQUEST_FAILED = "com.xtremeprog.sdk.ble.request_failed";
/**
* @see BleService#bleDeviceFound
*/
public static final String BLE_DEVICE_FOUND = "com.xtremeprog.sdk.ble.device_found";
/**
* @see BleService#bleGattConnected
*/
public static final String BLE_GATT_CONNECTED = "com.xtremeprog.sdk.ble.gatt_connected";
/**
* @see BleService#bleGattDisConnected
*/
public static final String BLE_GATT_DISCONNECTED = "com.xtremeprog.sdk.ble.gatt_disconnected";
/**
* @see BleService#bleServiceDiscovered
*/
public static final String BLE_SERVICE_DISCOVERED = "com.xtremeprog.sdk.ble.service_discovered";
/**
* @see BleService#bleCharacteristicRead
*/
public static final String BLE_CHARACTERISTIC_READ = "com.xtremeprog.sdk.ble.characteristic_read";
/**
* @see BleService#bleCharacteristicNotification
*/
public static final String BLE_CHARACTERISTIC_NOTIFICATION = "com.xtremeprog.sdk.ble.characteristic_notification";
/**
* @see BleService#bleCharacteristicIndication
*/
public static final String BLE_CHARACTERISTIC_INDICATION = "com.xtremeprog.sdk.ble.characteristic_indication";
/**
* @see BleService#bleCharacteristicWrite
*/
public static final String BLE_CHARACTERISTIC_WRITE = "com.xtremeprog.sdk.ble.characteristic_write";
/**
* @see BleService#bleCharacteristicChanged
*/
public static final String BLE_CHARACTERISTIC_CHANGED = "com.xtremeprog.sdk.ble.characteristic_changed";
/** Intent extras */
public static final String EXTRA_DEVICE = "DEVICE";
public static final String EXTRA_RSSI = "RSSI";
public static final String EXTRA_SCAN_RECORD = "SCAN_RECORD";
public static final String EXTRA_SOURCE = "SOURCE";
public static final String EXTRA_ADDR = "ADDRESS";
public static final String EXTRA_CONNECTED = "CONNECTED";
public static final String EXTRA_STATUS = "STATUS";
public static final String EXTRA_UUID = "UUID";
public static final String EXTRA_VALUE = "VALUE";
public static final String EXTRA_REQUEST = "REQUEST";
public static final String EXTRA_REASON = "REASON";
/** Source of device entries in the device list */
public static final int DEVICE_SOURCE_SCAN = 0;
public static final int DEVICE_SOURCE_BONDED = 1;
public static final int DEVICE_SOURCE_CONNECTED = 2;
public static final UUID DESC_CCC = UUID
.fromString("00002902-0000-1000-8000-00805f9b34fb");
public enum BLESDK {
NOT_SUPPORTED, ANDROID, SAMSUNG, BROADCOM
}
private final IBinder mBinder = new LocalBinder();
private BLESDK mBleSDK;
private IBle mBle;
private Queue mRequestQueue = new LinkedList();
private BleRequest mCurrentRequest = null;
private static final int REQUEST_TIMEOUT = 10 * 10; // total timeout =
// REQUEST_TIMEOUT *
// 100ms
private boolean mCheckTimeout = false;
private int mElapsed = 0;
private Thread mRequestTimeout;
private String mNotificationAddress;
private Runnable mTimeoutRunnable = new Runnable() {
@Override
public void run() {
Log.d(TAG, "monitoring thread start");
mElapsed = 0;
try {
while (mCheckTimeout) {
// Log.d(TAG, "monitoring timeout seconds: " + mElapsed);
Thread.sleep(100);
mElapsed++;
if (mElapsed > REQUEST_TIMEOUT && mCurrentRequest != null) {
Log.d(TAG, "-processrequest type "
+ mCurrentRequest.type + " address "
+ mCurrentRequest.address + " [timeout]");
bleRequestFailed(mCurrentRequest.address,
mCurrentRequest.type, FailReason.TIMEOUT);
bleStatusAbnormal("-processrequest type "
+ mCurrentRequest.type + " address "
+ mCurrentRequest.address + " [timeout]");
if (mBle != null) {
mBle.disconnect(mCurrentRequest.address);
}
new Thread(new Runnable() {
@Override
public void run() {
mCurrentRequest = null;
processNextRequest();
}
}, "th-ble").start();
break;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
Log.d(TAG, "monitoring thread exception");
}
Log.d(TAG, "monitoring thread stop");
}
};
public static IntentFilter getIntentFilter() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BLE_NOT_SUPPORTED);
intentFilter.addAction(BLE_NO_BT_ADAPTER);
intentFilter.addAction(BLE_STATUS_ABNORMAL);
intentFilter.addAction(BLE_REQUEST_FAILED);
intentFilter.addAction(BLE_DEVICE_FOUND);
intentFilter.addAction(BLE_GATT_CONNECTED);
intentFilter.addAction(BLE_GATT_DISCONNECTED);
intentFilter.addAction(BLE_SERVICE_DISCOVERED);
intentFilter.addAction(BLE_CHARACTERISTIC_READ);
intentFilter.addAction(BLE_CHARACTERISTIC_NOTIFICATION);
intentFilter.addAction(BLE_CHARACTERISTIC_WRITE);
intentFilter.addAction(BLE_CHARACTERISTIC_CHANGED);
return intentFilter;
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public BleService getService() {
return BleService.this;
}
}
@Override
public void onCreate() {
mBleSDK = getBleSDK();
if (mBleSDK == BLESDK.NOT_SUPPORTED) {
return;
}
Log.d(TAG, " " + mBleSDK);
if (mBleSDK == BLESDK.BROADCOM) {
mBle = new BroadcomBle(this);
} else if (mBleSDK == BLESDK.ANDROID) {
mBle = new AndroidBle(this);
} else if (mBleSDK == BLESDK.SAMSUNG) {
mBle = new SamsungBle(this);
}
}
protected void bleNotSupported() {
Intent intent = new Intent(BleService.BLE_NOT_SUPPORTED);
sendBroadcast(intent);
}
protected void bleNoBtAdapter() {
Intent intent = new Intent(BleService.BLE_NO_BT_ADAPTER);
sendBroadcast(intent);
}
private BLESDK getBleSDK() {
if (getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH_LE)) {
// android 4.3
return BLESDK.ANDROID;
}
ArrayList libraries = new ArrayList();
for (String i : getPackageManager().getSystemSharedLibraryNames()) {
libraries.add(i);
}
if (android.os.Build.VERSION.SDK_INT >= 17) {
// android 4.2.2
if (libraries.contains("com.samsung.android.sdk.bt")) {
return BLESDK.SAMSUNG;
} else if (libraries.contains("com.broadcom.bt")) {
return BLESDK.BROADCOM;
}
}
bleNotSupported();
return BLESDK.NOT_SUPPORTED;
}
public IBle getBle() {
return mBle;
}
/**
* Send {@link BleService#BLE_DEVICE_FOUND} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_DEVICE} device {@link BluetoothDevice}
* {@link BleService#EXTRA_RSSI} rssi int
* {@link BleService#EXTRA_SCAN_RECORD} scan record byte[]
* {@link BleService#EXTRA_SOURCE} source int, not used now
*/
protected void bleDeviceFound(BluetoothDevice device, int rssi,
byte[] scanRecord, int source) {
Log.d("blelib", "[" + new Date().toLocaleString() + "] device found "
+ device.getAddress());
Intent intent = new Intent(BleService.BLE_DEVICE_FOUND);
intent.putExtra(BleService.EXTRA_DEVICE, device);
intent.putExtra(BleService.EXTRA_RSSI, rssi);
intent.putExtra(BleService.EXTRA_SCAN_RECORD, scanRecord);
intent.putExtra(BleService.EXTRA_SOURCE, source);
sendBroadcast(intent);
}
/**
* Send {@link BleService#BLE_GATT_CONNECTED} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_DEVICE} device {@link BluetoothDevice}
*/
protected void bleGattConnected(BluetoothDevice device) {
Intent intent = new Intent(BLE_GATT_CONNECTED);
intent.putExtra(EXTRA_DEVICE, device);
intent.putExtra(EXTRA_ADDR, device.getAddress());
sendBroadcast(intent);
requestProcessed(device.getAddress(), RequestType.CONNECT_GATT, true);
}
/**
* Send {@link BleService#BLE_GATT_DISCONNECTED} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
*
* @param address
*/
protected void bleGattDisConnected(String address) {
Intent intent = new Intent(BLE_GATT_DISCONNECTED);
intent.putExtra(EXTRA_ADDR, address);
sendBroadcast(intent);
requestProcessed(address, RequestType.CONNECT_GATT, false);
}
/**
* Send {@link BleService#BLE_SERVICE_DISCOVERED} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
*
* @param address
*/
protected void bleServiceDiscovered(String address) {
Intent intent = new Intent(BLE_SERVICE_DISCOVERED);
intent.putExtra(EXTRA_ADDR, address);
sendBroadcast(intent);
requestProcessed(address, RequestType.DISCOVER_SERVICE, true);
}
protected void requestProcessed(String address, RequestType requestType,
boolean success) {
if (mCurrentRequest != null && mCurrentRequest.type == requestType) {
clearTimeoutThread();
Log.d(TAG, "-processrequest type " + requestType + " address "
+ address + " [success: " + success + "]");
if (!success) {
bleRequestFailed(mCurrentRequest.address, mCurrentRequest.type,
FailReason.RESULT_FAILED);
}
new Thread(new Runnable() {
@Override
public void run() {
mCurrentRequest = null;
processNextRequest();
}
}, "th-ble").start();
}
}
private void clearTimeoutThread() {
if (mRequestTimeout.isAlive()) {
try {
mCheckTimeout = false;
mRequestTimeout.join();
mRequestTimeout = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* Send {@link BleService#BLE_CHARACTERISTIC_READ} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now
* {@link BleService#EXTRA_VALUE} data byte[]
*
* @param address
* @param uuid
* @param status
* @param value
*/
protected void bleCharacteristicRead(String address, String uuid,
int status, byte[] value) {
Intent intent = new Intent(BLE_CHARACTERISTIC_READ);
intent.putExtra(EXTRA_ADDR, address);
intent.putExtra(EXTRA_UUID, uuid);
intent.putExtra(EXTRA_STATUS, status);
intent.putExtra(EXTRA_VALUE, value);
sendBroadcast(intent);
requestProcessed(address, RequestType.READ_CHARACTERISTIC, true);
}
protected void addBleRequest(BleRequest request) {
synchronized (mRequestQueue) {
mRequestQueue.add(request);
processNextRequest();
}
}
private synchronized void processNextRequest() {
if (mCurrentRequest != null) {
return;
}
if (mRequestQueue.isEmpty()) {
return;
}
mCurrentRequest = mRequestQueue.remove();
Log.d(TAG, "+processrequest type " + mCurrentRequest.type + " address "
+ mCurrentRequest.address + " remark " + mCurrentRequest.remark);
startTimeoutThread();
boolean ret = false;
switch (mCurrentRequest.type) {
case CONNECT_GATT:
ret = ((IBleRequestHandler) mBle).connect(mCurrentRequest.address);
break;
case DISCOVER_SERVICE:
ret = mBle.discoverServices(mCurrentRequest.address);
break;
case CHARACTERISTIC_NOTIFICATION:
case CHARACTERISTIC_INDICATION:
case CHARACTERISTIC_STOP_NOTIFICATION:
ret = ((IBleRequestHandler) mBle).characteristicNotification(
mCurrentRequest.address, mCurrentRequest.characteristic);
break;
case READ_CHARACTERISTIC:
ret = ((IBleRequestHandler) mBle).readCharacteristic(
mCurrentRequest.address, mCurrentRequest.characteristic);
break;
case WRITE_CHARACTERISTIC:
ret = ((IBleRequestHandler) mBle).writeCharacteristic(
mCurrentRequest.address, mCurrentRequest.characteristic);
break;
case READ_DESCRIPTOR:
break;
default:
break;
}
if (!ret) {
clearTimeoutThread();
Log.d(TAG, "-processrequest type " + mCurrentRequest.type
+ " address " + mCurrentRequest.address + " [fail start]");
bleRequestFailed(mCurrentRequest.address, mCurrentRequest.type,
FailReason.START_FAILED);
new Thread(new Runnable() {
@Override
public void run() {
mCurrentRequest = null;
processNextRequest();
}
}, "th-ble").start();
}
}
private void startTimeoutThread() {
mCheckTimeout = true;
mRequestTimeout = new Thread(mTimeoutRunnable);
mRequestTimeout.start();
}
protected BleRequest getCurrentRequest() {
return mCurrentRequest;
}
protected void setCurrentRequest(BleRequest mCurrentRequest) {
this.mCurrentRequest = mCurrentRequest;
}
/**
* Send {@link BleService#BLE_CHARACTERISTIC_NOTIFICATION} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now
*
* @param address
* @param uuid
* @param status
*/
protected void bleCharacteristicNotification(String address, String uuid,
boolean isEnabled, int status) {
Intent intent = new Intent(BLE_CHARACTERISTIC_NOTIFICATION);
intent.putExtra(EXTRA_ADDR, address);
intent.putExtra(EXTRA_UUID, uuid);
intent.putExtra(EXTRA_VALUE, isEnabled);
intent.putExtra(EXTRA_STATUS, status);
sendBroadcast(intent);
if (isEnabled) {
requestProcessed(address, RequestType.CHARACTERISTIC_NOTIFICATION,
true);
} else {
requestProcessed(address,
RequestType.CHARACTERISTIC_STOP_NOTIFICATION, true);
}
setNotificationAddress(address);
}
/**
* Send {@link BleService#BLE_CHARACTERISTIC_INDICATION} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now
*
* @param address
* @param uuid
* @param status
*/
protected void bleCharacteristicIndication(String address, String uuid,
int status) {
Intent intent = new Intent(BLE_CHARACTERISTIC_INDICATION);
intent.putExtra(EXTRA_ADDR, address);
intent.putExtra(EXTRA_UUID, uuid);
intent.putExtra(EXTRA_STATUS, status);
sendBroadcast(intent);
requestProcessed(address, RequestType.CHARACTERISTIC_INDICATION, true);
setNotificationAddress(address);
}
/**
* Send {@link BleService#BLE_CHARACTERISTIC_WRITE} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now
*
* @param address
* @param uuid
* @param status
*/
protected void bleCharacteristicWrite(String address, String uuid,
int status) {
Intent intent = new Intent(BLE_CHARACTERISTIC_WRITE);
intent.putExtra(EXTRA_ADDR, address);
intent.putExtra(EXTRA_UUID, uuid);
intent.putExtra(EXTRA_STATUS, status);
sendBroadcast(intent);
requestProcessed(address, RequestType.WRITE_CHARACTERISTIC, true);
}
/**
* Send {@link BleService#BLE_CHARACTERISTIC_CHANGED} broadcast.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}
* {@link BleService#EXTRA_VALUE} data byte[]
*
* @param address
* @param uuid
* @param value
*/
protected void bleCharacteristicChanged(String address, String uuid,
byte[] value) {
Intent intent = new Intent(BLE_CHARACTERISTIC_CHANGED);
intent.putExtra(EXTRA_ADDR, address);
intent.putExtra(EXTRA_UUID, uuid);
intent.putExtra(EXTRA_VALUE, value);
sendBroadcast(intent);
}
/**
* @param reason
*/
protected void bleStatusAbnormal(String reason) {
Intent intent = new Intent(BLE_STATUS_ABNORMAL);
intent.putExtra(EXTRA_VALUE, reason);
sendBroadcast(intent);
}
/**
* Sent when BLE request failed.
*
* Data in the broadcast intent:
* {@link BleService#EXTRA_ADDR} device address {@link String}
* {@link BleService#EXTRA_REQUEST} request type
* {@link BleRequest.RequestType}
* {@link BleService#EXTRA_REASON} fail reason {@link BleRequest.FailReason}
*/
protected void bleRequestFailed(String address, RequestType type,
FailReason reason) {
Intent intent = new Intent(BLE_REQUEST_FAILED);
intent.putExtra(EXTRA_ADDR, address);
intent.putExtra(EXTRA_REQUEST, type);
intent.putExtra(EXTRA_REASON, reason.ordinal());
sendBroadcast(intent);
}
protected String getNotificationAddress() {
return mNotificationAddress;
}
protected void setNotificationAddress(String mNotificationAddress) {
this.mNotificationAddress = mNotificationAddress;
}
}
================================================
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BroadcomBle.java
================================================
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.xtremeprog.sdk.ble;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import com.broadcom.bt.gatt.BluetoothGatt;
import com.broadcom.bt.gatt.BluetoothGattAdapter;
import com.broadcom.bt.gatt.BluetoothGattCallback;
import com.broadcom.bt.gatt.BluetoothGattCharacteristic;
import com.broadcom.bt.gatt.BluetoothGattDescriptor;
import com.broadcom.bt.gatt.BluetoothGattService;
import com.xtremeprog.sdk.ble.BleRequest.RequestType;
public class BroadcomBle implements IBle, IBleRequestHandler {
private BluetoothAdapter mBtAdapter;
private BleService mService;
private BluetoothGatt mBluetoothGatt;
private boolean mScanning;
private String mAddress;
private final BluetoothGattCallback mGattCallbacks = new BluetoothGattCallback() {
@Override
public void onAppRegistered(int status) {
}
@Override
public void onScanResult(BluetoothDevice device, int rssi,
byte[] scanRecord) {
mService.bleDeviceFound(device, rssi, scanRecord,
BleService.DEVICE_SOURCE_SCAN);
}
@Override
public void onConnectionStateChange(BluetoothDevice device, int status,
int newState) {
if (mBluetoothGatt == null) {
return;
}
if (newState == BluetoothProfile.STATE_CONNECTED) {
mService.bleGattConnected(device);
mBluetoothGatt.discoverServices(device);
mAddress = device.getAddress();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mService.bleGattDisConnected(device.getAddress());
mAddress = null;
}
}
@Override
public void onServicesDiscovered(BluetoothDevice device, int status) {
mService.bleServiceDiscovered(device.getAddress());
}
@Override
public void onCharacteristicRead(
BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
mService.bleCharacteristicRead(mAddress, characteristic
.getUuid().toString(), status, characteristic
.getValue());
}
}
@Override
public void onCharacteristicChanged(
BluetoothGattCharacteristic characteristic) {
String address = mService.getNotificationAddress();
mService.bleCharacteristicChanged(address, characteristic.getUuid()
.toString(), characteristic.getValue());
}
@Override
public void onDescriptorRead(BluetoothGattDescriptor descriptor,
int status) {
BleRequest request = mService.getCurrentRequest();
String address = request.address;
byte[] value = descriptor.getValue();
byte[] val_set = null;
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) {
val_set = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
} else if (request.type == RequestType.CHARACTERISTIC_INDICATION) {
val_set = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE;
} else {
val_set = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
}
if (Arrays.equals(value, val_set)) {
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), true,
status);
} else if (request.type == RequestType.CHARACTERISTIC_INDICATION) {
mService.bleCharacteristicIndication(address, descriptor
.getCharacteristic().getUuid().toString(), status);
} else {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), false,
status);
}
return;
}
if (!descriptor.setValue(val_set)) {
mService.requestProcessed(address, request.type, false);
}
mBluetoothGatt.writeDescriptor(descriptor);
};
@Override
public void onDescriptorWrite(BluetoothGattDescriptor descriptor,
int status) {
BleRequest request = mService.getCurrentRequest();
String address = request.address;
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION
|| request.type == RequestType.CHARACTERISTIC_INDICATION
|| request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) {
if (status != BluetoothGatt.GATT_SUCCESS) {
mService.requestProcessed(address, request.type, false);
return;
}
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), true,
status);
} else if (request.type == RequestType.CHARACTERISTIC_INDICATION) {
mService.bleCharacteristicIndication(address, descriptor
.getCharacteristic().getUuid().toString(), status);
} else {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), false,
status);
}
return;
}
};
};
private final BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
mBluetoothGatt = (BluetoothGatt) proxy;
mBluetoothGatt.registerApp(mGattCallbacks);
}
@Override
public void onServiceDisconnected(int profile) {
for ( BluetoothDevice d : mBluetoothGatt.getConnectedDevices() ) {
mBluetoothGatt.cancelConnection(d);
}
mBluetoothGatt = null;
}
};
public BroadcomBle(BleService service) {
mService = service;
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBtAdapter == null) {
mService.bleNoBtAdapter();
return;
}
BluetoothGattAdapter.getProfileProxy(mService, mProfileServiceListener,
BluetoothGattAdapter.GATT);
}
@Override
public void startScan() {
if (mScanning) {
return;
}
if (mBluetoothGatt == null) {
mScanning = false;
return;
}
mScanning = true;
mBluetoothGatt.startScan();
}
@Override
public void stopScan() {
if (!mScanning || mBluetoothGatt == null) {
return;
}
mScanning = false;
mBluetoothGatt.stopScan();
}
@Override
public boolean adapterEnabled() {
if (mBtAdapter != null) {
return mBtAdapter.isEnabled();
}
return false;
}
@Override
public boolean connect(String address) {
BluetoothDevice device = mBtAdapter.getRemoteDevice(address);
return mBluetoothGatt.connect(device, false);
}
@Override
public void disconnect(String address) {
BluetoothDevice device = mBtAdapter.getRemoteDevice(address);
mBluetoothGatt.cancelConnection(device);
}
@Override
public ArrayList getServices(String address) {
ArrayList list = new ArrayList();
BluetoothDevice device = mBtAdapter.getRemoteDevice(address);
List services = mBluetoothGatt
.getServices(device);
for (BluetoothGattService s : services) {
list.add(new BleGattService(s));
}
return list;
}
@Override
public boolean requestReadCharacteristic(String address,
BleGattCharacteristic characteristic) {
mService.addBleRequest(new BleRequest(RequestType.READ_CHARACTERISTIC,
address, characteristic));
return true;
}
@Override
public boolean discoverServices(String address) {
return true;
}
@Override
public boolean readCharacteristic(String address,
BleGattCharacteristic characteristic) {
if (characteristic.getGattCharacteristicB() != null) {
return mBluetoothGatt.readCharacteristic(characteristic
.getGattCharacteristicB());
}
return false;
}
@Override
public BleGattService getService(String address, UUID uuid) {
BluetoothGattService service = mBluetoothGatt.getService(
mBtAdapter.getRemoteDevice(address), uuid);
if (service == null) {
return null;
} else {
return new BleGattService(service);
}
}
@Override
public boolean requestCharacteristicNotification(String address,
BleGattCharacteristic characteristic) {
mService.addBleRequest(new BleRequest(
RequestType.CHARACTERISTIC_NOTIFICATION, address,
characteristic));
return true;
}
@Override
public boolean characteristicNotification(String address,
BleGattCharacteristic characteristic) {
BleRequest request = mService.getCurrentRequest();
BluetoothGattCharacteristic b = characteristic.getGattCharacteristicB();
boolean enable = true;
if (request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) {
enable = false;
}
if (!mBluetoothGatt.setCharacteristicNotification(b, enable)) {
return false;
}
BluetoothGattDescriptor descriptor = b
.getDescriptor(BleService.DESC_CCC);
if (descriptor == null) {
return false;
}
return mBluetoothGatt.readDescriptor(descriptor);
}
@Override
public boolean requestWriteCharacteristic(String address,
BleGattCharacteristic characteristic, String remark) {
mService.addBleRequest(new BleRequest(RequestType.WRITE_CHARACTERISTIC,
address, characteristic));
return true;
}
@Override
public boolean writeCharacteristic(String address,
BleGattCharacteristic characteristic) {
return mBluetoothGatt.writeCharacteristic(characteristic
.getGattCharacteristicB());
}
@Override
public boolean requestConnect(String address) {
if (mAddress != null) {
return false;
}
mService.addBleRequest(new BleRequest(RequestType.CONNECT_GATT, address));
return true;
}
@Override
public String getBTAdapterMacAddr() {
if (mBtAdapter != null) {
return mBtAdapter.getAddress();
}
return null;
}
@Override
public boolean requestIndication(String address,
BleGattCharacteristic characteristic) {
mService.addBleRequest(new BleRequest(
RequestType.CHARACTERISTIC_INDICATION, address, characteristic));
return true;
}
@Override
public boolean requestStopNotification(String address,
BleGattCharacteristic characteristic) {
mService.addBleRequest(new BleRequest(
RequestType.CHARACTERISTIC_STOP_NOTIFICATION, address,
characteristic));
return true;
}
}
================================================
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/IBle.java
================================================
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.xtremeprog.sdk.ble;
import java.util.ArrayList;
import java.util.UUID;
public interface IBle {
public String getBTAdapterMacAddr();
/**
* Will receive broadcast {@link BleService#BLE_DEVICE_FOUND} if device
* found.
*/
public void startScan();
/**
* Stop BLE scan.
*/
public void stopScan();
/**
* Check if bluetooth adapter is enabled.
*
* @return enabled
*/
public boolean adapterEnabled();
/**
* Disconnect BLE device. Will receive
* {@link BleService#BLE_GATT_DISCONNECTED} broadcast if device
* disconnected.
*
* @param address
* BLE device address.
*/
public void disconnect(String address);
/**
* Discover BLE services. Will receive
* {@link BleService#BLE_SERVICE_DISCOVERED} broadcast if device service
* discovered.
*
* @param address
* @return
*/
public boolean discoverServices(String address);
/**
* Get discovered services for BLE device. Call this function after
* {@link BleService#BLE_SERVICE_DISCOVERED} broadcast is received.
*
* @param address
* @return List of {@link BleGattService}
*/
public ArrayList getServices(String address);
/**
* Get discovered service by uuid. Call this function after
* {@link BleService#BLE_SERVICE_DISCOVERED} broadcast is received.
*
* @param address
* @param uuid
* @return {@link BleGattService}
*/
public BleGattService getService(String address, UUID uuid);
/**
* Request to connect a BLE device by address. Will receive
* {@link BleService#BLE_GATT_CONNECTED} broadcast if device connected.
*
* @param address
* @return if request be inserted into queue successfully.
*/
public boolean requestConnect(String address);
/**
* Request to read characteristic. Will receive
* {@link BleService#BLE_CHARACTERISTIC_READ} broadcast if characteristic
* read.
*
* @param address
* @param characteristic
* Get characteristic from {@link BleGattService}
* @return if request be inserted into queue successfully.
*/
public boolean requestReadCharacteristic(String address,
BleGattCharacteristic characteristic);
/**
* Request characteristic notification. Will receive
* {@link BleService#BLE_CHARACTERISTIC_NOTIFICATION} broadcast if
* notification set OK. When the characteristic's value changed,
* {@link BleService#BLE_CHARACTERISTIC_CHANGED} broadcast will be received
* also.
*
* @param address
* @param characteristic
* Get characteristic from {@link BleGattService}
* @return if request be inserted into queue successfully.
*/
public boolean requestCharacteristicNotification(String address,
BleGattCharacteristic characteristic);
public boolean requestStopNotification(String address,
BleGattCharacteristic characteristic);
/**
* Request characteristic indication. Will receive
* {@link BleService#BLE_CHARACTERISTIC_INDICATION} broadcast if indication
* set OK. When the characteristic's value changed,
* {@link BleService#BLE_CHARACTERISTIC_CHANGED} broadcast will be received
* also.
*
* @param address
* @param characteristic
* Get characteristic from {@link BleGattService}
* @return if request be inserted into queue successfully.
*/
public boolean requestIndication(String address,
BleGattCharacteristic characteristic);
/**
* Request write characteristic value. Will receive
* {@link BleService#BLE_CHARACTERISTIC_WRITE} broadcast if characteristic
* value be written.
*
* @param address
* @param characteristic
* Get characteristic from {@link BleGattService}
* @param remark
* For debug purpose.
* @return if request be inserted into queue successfully.
*/
public boolean requestWriteCharacteristic(String address,
BleGattCharacteristic characteristic, String remark);
}
================================================
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/IBleRequestHandler.java
================================================
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.xtremeprog.sdk.ble;
public interface IBleRequestHandler {
public boolean connect(String address);
/**
* @param address
* @param characteristic
* @return
*/
public boolean readCharacteristic(String address,
BleGattCharacteristic characteristic);
/**
* @param address
* @param characteristic
* @return
*/
public boolean characteristicNotification(String address,
BleGattCharacteristic characteristic);
/**
* @param address
* @param characteristic
* @return
*/
public boolean writeCharacteristic(String address,
BleGattCharacteristic characteristic);
}
================================================
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/SamsungBle.java
================================================
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.xtremeprog.sdk.ble;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.util.Log;
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.BluetoothGattService;
import com.xtremeprog.sdk.ble.BleRequest.RequestType;
public class SamsungBle implements IBle, IBleRequestHandler {
protected static final String TAG = "blelib";
private BluetoothAdapter mBtAdapter;
private BleService mService;
private BluetoothGatt mBluetoothGatt;
private boolean mScanning;
private final BluetoothGattCallback mGattCallbacks = new BluetoothGattCallback() {
@Override
public void onAppRegistered(int status) {
}
@Override
public void onScanResult(BluetoothDevice device, int rssi,
byte[] scanRecord) {
mService.bleDeviceFound(device, rssi, scanRecord,
BleService.DEVICE_SOURCE_SCAN);
}
@Override
public void onConnectionStateChange(BluetoothDevice device, int status,
int newState) {
if (mBluetoothGatt == null) {
return;
}
if (status != BluetoothGatt.GATT_SUCCESS) {
disconnect(device.getAddress());
mService.bleGattDisConnected(device.getAddress());
return;
}
if (newState == BluetoothProfile.STATE_CONNECTED) {
mService.bleGattConnected(device);
mService.addBleRequest(new BleRequest(
RequestType.DISCOVER_SERVICE, device.getAddress()));
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mService.bleGattDisConnected(device.getAddress());
disconnect(device.getAddress());
}
}
@Override
public void onServicesDiscovered(BluetoothDevice device, int status) {
String address = device.getAddress();
if (status != BluetoothGatt.GATT_SUCCESS) {
disconnect(address);
mService.bleGattDisConnected(address);
mService.requestProcessed(address,
RequestType.DISCOVER_SERVICE, false);
return;
}
mService.bleServiceDiscovered(device.getAddress());
}
@Override
public void onCharacteristicRead(
BluetoothGattCharacteristic characteristic, int status) {
BleRequest request = mService.getCurrentRequest();
String address = request.address;
if (status != BluetoothGatt.GATT_SUCCESS) {
mService.requestProcessed(address,
RequestType.READ_CHARACTERISTIC, false);
return;
}
mService.bleCharacteristicRead(address, characteristic.getUuid()
.toString(), status, characteristic.getValue());
}
@Override
public void onCharacteristicChanged(
BluetoothGattCharacteristic characteristic) {
Log.d(TAG, "onCharacteristicChanged");
String address = mService.getNotificationAddress();
mService.bleCharacteristicChanged(address, characteristic.getUuid()
.toString(), characteristic.getValue());
}
@Override
public void onCharacteristicWrite(
BluetoothGattCharacteristic characteristic, int status) {
BleRequest request = mService.getCurrentRequest();
String address = request.address;
if (status != BluetoothGatt.GATT_SUCCESS) {
mService.requestProcessed(address,
RequestType.WRITE_CHARACTERISTIC, false);
return;
}
mService.bleCharacteristicWrite(address, characteristic.getUuid()
.toString(), status);
};
@Override
public void onDescriptorRead(BluetoothGattDescriptor descriptor,
int status) {
BleRequest request = mService.getCurrentRequest();
String address = request.address;
byte[] value = descriptor.getValue();
byte[] val_set = null;
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) {
val_set = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
} else if (request.type == RequestType.CHARACTERISTIC_INDICATION) {
val_set = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE;
} else {
val_set = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
}
if (Arrays.equals(value, val_set)) {
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), true,
status);
} else if (request.type == RequestType.CHARACTERISTIC_INDICATION) {
mService.bleCharacteristicIndication(address, descriptor
.getCharacteristic().getUuid().toString(), status);
} else {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), false,
status);
}
return;
}
if (!descriptor.setValue(val_set)) {
mService.requestProcessed(address, request.type, false);
}
mBluetoothGatt.writeDescriptor(descriptor);
};
@Override
public void onDescriptorWrite(BluetoothGattDescriptor descriptor,
int status) {
BleRequest request = mService.getCurrentRequest();
String address = request.address;
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION
|| request.type == RequestType.CHARACTERISTIC_INDICATION
|| request.type == RequestType.CHARACTERISTIC_STOP_NOTIFICATION) {
if (status != BluetoothGatt.GATT_SUCCESS) {
mService.requestProcessed(address, request.type, false);
return;
}
if (request.type == RequestType.CHARACTERISTIC_NOTIFICATION) {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), true,
status);
} else if (request.type == RequestType.CHARACTERISTIC_INDICATION) {
mService.bleCharacteristicIndication(address, descriptor
.getCharacteristic().getUuid().toString(), status);
} else {
mService.bleCharacteristicNotification(address, descriptor
.getCharacteristic().getUuid().toString(), false,
status);
}
return;
}
};
};
private final BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
mBluetoothGatt = (BluetoothGatt) proxy;
mBluetoothGatt.registerApp(mGattCallbacks);
}
@Override
public void onServiceDisconnected(int profile) {
mBluetoothGatt = null;
}
};
public SamsungBle(BleService service) {
mService = service;
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBtAdapter == null) {
mService.bleNoBtAdapter();
return;
}
BluetoothGattAdapter.getProfileProxy(mService, mProfileServiceListener,
BluetoothGattAdapter.GATT);
}
@Override
public void startScan() {
if (mScanning) {
return;
}
if (mBluetoothGatt == null) {
mScanning = false;
return;
}
mScanning = true;
mBluetoothGatt.startScan();
}
@Override
public void stopScan() {
if (!mScanning || mBluetoothGatt == null) {
return;
}
mScanning = false;
mBluetoothGatt.stopScan();
}
@Override
public boolean adapterEnabled() {
if (mBtAdapter != null) {
return mBtAdapter.isEnabled();
}
return false;
}
@Override
public boolean connect(String address) {
BluetoothDevice device = mBtAdapter.getRemoteDevice(address);
return mBluetoothGatt.connect(device, false);
}
@Override
public void disconnect(String address) {
BluetoothDevice device = mBtAdapter.getRemoteDevice(address);
mBluetoothGatt.cancelConnection(device);
}
@Override
public ArrayList getServices(String address) {
ArrayList list = new ArrayList();
BluetoothDevice device = mBtAdapter.getRemoteDevice(address);
List services = mBluetoothGatt
.getServices(device);
for (BluetoothGattService s : services) {
list.add(new BleGattService(s));
}
return list;
}
@Override
public boolean requestReadCharacteristic(String address,
BleGattCharacteristic characteristic) {
mService.addBleRequest(new BleRequest(RequestType.READ_CHARACTERISTIC,
address, characteristic));
return true;
}
@Override
public boolean discoverServices(String address) {
return mBluetoothGatt.discoverServices(mBtAdapter
.getRemoteDevice(address));
}
@Override
public boolean readCharacteristic(String address,
BleGattCharacteristic characteristic) {
return mBluetoothGatt.readCharacteristic(characteristic
.getGattCharacteristicS());
}
@Override
public BleGattService getService(String address, UUID uuid) {
BluetoothGattService service = mBluetoothGatt.getService(
mBtAdapter.getRemoteDevice(address), uuid);
if (service == null) {
return null;
} else {
return new BleGattService(service);
}
}
@Override
public boolean requestCharacteristicNotification(String address,
BleGattCharacteristic characteristic) {
mService.addBleRequest(new BleRequest(
RequestType.CHARACTERISTIC_NOTIFICATION, address,
characteristic));
return true;
}
@Override
public boolean characteristicNotification(String address,
BleGattCharacteristic characteristic) {
BluetoothGattCharacteristic c = characteristic.getGattCharacteristicS();
if (!mBluetoothGatt.setCharacteristicNotification(c, true)) {
return false;
}
BluetoothGattDescriptor descriptor = c
.getDescriptor(BleService.DESC_CCC);
if (descriptor == null) {
return false;
}
return mBluetoothGatt.readDescriptor(descriptor);
}
@Override
public boolean requestWriteCharacteristic(String address,
BleGattCharacteristic characteristic, String remark) {
mService.addBleRequest(new BleRequest(RequestType.WRITE_CHARACTERISTIC,
address, characteristic));
return true;
}
@Override
public boolean writeCharacteristic(String address,
BleGattCharacteristic characteristic) {
return mBluetoothGatt.writeCharacteristic(characteristic
.getGattCharacteristicS());
}
@Override
public boolean requestConnect(String address) {
mService.addBleRequest(new BleRequest(RequestType.CONNECT_GATT, address));
return true;
}
@Override
public String getBTAdapterMacAddr() {
if (mBtAdapter != null) {
return mBtAdapter.getAddress();
}
return null;
}
@Override
public boolean requestIndication(String address,
BleGattCharacteristic characteristic) {
mService.addBleRequest(new BleRequest(
RequestType.CHARACTERISTIC_INDICATION, address, characteristic));
return true;
}
@Override
public boolean requestStopNotification(String address,
BleGattCharacteristic characteristic) {
mService.addBleRequest(new BleRequest(
RequestType.CHARACTERISTIC_STOP_NOTIFICATION, address,
characteristic));
return true;
}
}
================================================
FILE: BluetoothLeGatt/.classpath
================================================
================================================
FILE: BluetoothLeGatt/.project
================================================
DeviceScanActivitycom.android.ide.eclipse.adt.ResourceManagerBuildercom.android.ide.eclipse.adt.PreCompilerBuilderorg.eclipse.jdt.core.javabuildercom.android.ide.eclipse.adt.ApkBuildercom.android.ide.eclipse.adt.AndroidNatureorg.eclipse.jdt.core.javanature
================================================
FILE: BluetoothLeGatt/AndroidManifest.xml
================================================
================================================
FILE: BluetoothLeGatt/project.properties
================================================
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-17
android.library.reference.1=../BleLibrary
================================================
FILE: BluetoothLeGatt/res/layout/actionbar_indeterminate_progress.xml
================================================
================================================
FILE: BluetoothLeGatt/res/layout/activity_characteristic.xml
================================================
================================================
FILE: BluetoothLeGatt/res/layout/gatt_services_characteristics.xml
================================================
================================================
FILE: BluetoothLeGatt/res/layout/listitem_device.xml
================================================
================================================
FILE: BluetoothLeGatt/res/menu/characteristic.xml
================================================
================================================
FILE: BluetoothLeGatt/res/menu/gatt_services.xml
================================================
================================================
FILE: BluetoothLeGatt/res/menu/main.xml
================================================
================================================
FILE: BluetoothLeGatt/res/values/dimens.xml
================================================
16dp16dp
================================================
FILE: BluetoothLeGatt/res/values/strings.xml
================================================
BLE SampleBLE is not supportedData:Device address:State:No dataConnectedDisconnectedBLE Device ScanBluetooth not supported.Unknown deviceUnknown characteristicUnknown serviceConnectDisconnectScanStopCharacteristicActivityHello world!Settings
================================================
FILE: BluetoothLeGatt/res/values-w820dp/dimens.xml
================================================
64dp
================================================
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/BleApplication.java
================================================
package com.example.bluetooth.le;
import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import com.xtremeprog.sdk.ble.BleService;
import com.xtremeprog.sdk.ble.IBle;
public class BleApplication extends Application {
private BleService mService;
private IBle mBle;
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder rawBinder) {
mService = ((BleService.LocalBinder) rawBinder).getService();
mBle = mService.getBle();
if (mBle != null && !mBle.adapterEnabled()) {
// TODO: enalbe adapter
}
}
@Override
public void onServiceDisconnected(ComponentName classname) {
mService = null;
}
};
@Override
public void onCreate() {
super.onCreate();
Intent bindIntent = new Intent(this, BleService.class);
bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
public IBle getIBle() {
return mBle;
}
}
================================================
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/CharacteristicActivity.java
================================================
package com.example.bluetooth.le;
import java.util.UUID;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.xtremeprog.sdk.ble.BleGattCharacteristic;
import com.xtremeprog.sdk.ble.BleService;
import com.xtremeprog.sdk.ble.IBle;
public class CharacteristicActivity extends Activity {
private String mDeviceAddress;
private IBle mBle;
private BleGattCharacteristic mCharacteristic;
private View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_read) {
mBle.requestReadCharacteristic(mDeviceAddress, mCharacteristic);
} else if (v.getId() == R.id.btn_notify) {
if (mNotifyStarted) {
mBle.requestStopNotification(mDeviceAddress,
mCharacteristic);
} else {
mBle.requestCharacteristicNotification(mDeviceAddress,
mCharacteristic);
}
} else if (v.getId() == R.id.btn_indicate) {
mBle.requestIndication(mDeviceAddress, mCharacteristic);
} else if (v.getId() == R.id.btn_write) {
String val = et_hex.getText().toString();
try {
byte[] data = Hex.decodeHex(val.toCharArray());
mCharacteristic.setValue(data);
mBle.requestWriteCharacteristic(mDeviceAddress,
mCharacteristic, "");
} catch (DecoderException e) {
e.printStackTrace();
}
}
}
};
private final BroadcastReceiver mBleReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (!mDeviceAddress.equals(extras.getString(BleService.EXTRA_ADDR))) {
return;
}
String uuid = extras.getString(BleService.EXTRA_UUID);
if (uuid != null
&& !mCharacteristic.getUuid().toString().equals(uuid)) {
return;
}
String action = intent.getAction();
if (BleService.BLE_GATT_DISCONNECTED.equals(action)) {
Toast.makeText(CharacteristicActivity.this,
"Device disconnected...", Toast.LENGTH_SHORT).show();
finish();
} else if (BleService.BLE_CHARACTERISTIC_READ.equals(action)
|| BleService.BLE_CHARACTERISTIC_CHANGED.equals(action)) {
byte[] val = extras.getByteArray(BleService.EXTRA_VALUE);
tv_ascii.setText(new String(val));
tv_hex.setText("0x" + new String(Hex.encodeHex(val)));
} else if (BleService.BLE_CHARACTERISTIC_NOTIFICATION
.equals(action)) {
Toast.makeText(CharacteristicActivity.this,
"Notification state changed!", Toast.LENGTH_SHORT)
.show();
mNotifyStarted = extras.getBoolean(BleService.EXTRA_VALUE);
if (mNotifyStarted) {
btn_notify.setText("Stop Notify");
} else {
btn_notify.setText("Start Notify");
}
} else if (BleService.BLE_CHARACTERISTIC_INDICATION.equals(action)) {
Toast.makeText(CharacteristicActivity.this,
"Indication state changed!", Toast.LENGTH_SHORT).show();
} else if (BleService.BLE_CHARACTERISTIC_WRITE.equals(action)) {
Toast.makeText(CharacteristicActivity.this, "Write success!",
Toast.LENGTH_SHORT).show();
}
}
};
private TextView tv_ascii;
private TextView tv_hex;
private EditText et_hex;
private boolean mNotifyStarted;
private Button btn_notify;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_characteristic);
mDeviceAddress = getIntent().getStringExtra("address");
String service = getIntent().getStringExtra("service");
String characteristic = getIntent().getStringExtra("characteristic");
BleApplication app = (BleApplication) getApplication();
mBle = app.getIBle();
mCharacteristic = mBle.getService(mDeviceAddress,
UUID.fromString(service)).getCharacteristic(
UUID.fromString(characteristic));
mNotifyStarted = false;
TextView tv_name = (TextView) findViewById(R.id.tv_name);
TextView tv_uuid = (TextView) findViewById(R.id.tv_uuid);
tv_ascii = (TextView) findViewById(R.id.tv_ascii);
tv_hex = (TextView) findViewById(R.id.tv_hex);
tv_name.setText(Utils.BLE_CHARACTERISTICS.containsKey(characteristic) ? Utils.BLE_CHARACTERISTICS
.get(characteristic) : "unknown characteristic");
tv_uuid.setText(mCharacteristic.getUuid().toString());
View btn_read = findViewById(R.id.btn_read);
btn_notify = (Button) findViewById(R.id.btn_notify);
View btn_indicate = findViewById(R.id.btn_indicate);
View ll_write = findViewById(R.id.ll_write);
View btn_write = findViewById(R.id.btn_write);
et_hex = (EditText) findViewById(R.id.et_hex);
btn_read.setOnClickListener(onClickListener);
btn_notify.setOnClickListener(onClickListener);
btn_indicate.setOnClickListener(onClickListener);
btn_write.setOnClickListener(onClickListener);
final int charaProp = mCharacteristic.getProperties();
if ((charaProp & BleGattCharacteristic.PROPERTY_READ) > 0) {
btn_read.setVisibility(View.VISIBLE);
}
if ((charaProp & BleGattCharacteristic.PROPERTY_NOTIFY) > 0) {
btn_notify.setVisibility(View.VISIBLE);
}
if ((charaProp & BleGattCharacteristic.PROPERTY_INDICATE) > 0) {
btn_indicate.setVisibility(View.VISIBLE);
}
if ((charaProp & BleGattCharacteristic.PROPERTY_WRITE) > 0) {
ll_write.setVisibility(View.VISIBLE);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.characteristic, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(mBleReceiver, BleService.getIntentFilter());
}
@Override
public void onPanelClosed(int featureId, Menu menu) {
super.onPanelClosed(featureId, menu);
unregisterReceiver(mBleReceiver);
}
}
================================================
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/DeviceControlActivity.java
================================================
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed 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.
*/
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.example.bluetooth.le;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;
import com.xtremeprog.sdk.ble.BleGattCharacteristic;
import com.xtremeprog.sdk.ble.BleGattService;
import com.xtremeprog.sdk.ble.BleService;
import com.xtremeprog.sdk.ble.IBle;
//import android.bluetooth.BluetoothGattCharacteristic;
//import android.bluetooth.BluetoothGattService;
/**
* For a given BLE device, this Activity provides the user interface to connect,
* display data, and display GATT services and characteristics supported by the
* device. The Activity communicates with {@code BluetoothLeService}, which in
* turn interacts with the Bluetooth LE API.
*/
public class DeviceControlActivity extends Activity {
private final static String TAG = DeviceControlActivity.class
.getSimpleName();
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
private TextView mConnectionState;
private String mDeviceName;
private String mDeviceAddress;
private ExpandableListView mGattServicesList;
private ArrayList> mGattCharacteristics = new ArrayList>();
private boolean mConnected = false;
private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
protected IBle mBle;
// Handles various events fired by the Service.
// ACTION_GATT_CONNECTED: connected to a GATT server.
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
// ACTION_DATA_AVAILABLE: received data from the device. This can be a
// result of read
// or notification operations.
private final BroadcastReceiver mBleReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (!mDeviceAddress.equals(extras.getString(BleService.EXTRA_ADDR))) {
return;
}
String action = intent.getAction();
if (BleService.BLE_GATT_CONNECTED.equals(action)) {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
} else if (BleService.BLE_GATT_DISCONNECTED.equals(action)) {
onDeviceDisconnected();
} else if (BleService.BLE_SERVICE_DISCOVERED.equals(action)) {
displayGattServices(mBle.getServices(mDeviceAddress));
}
}
};
// If a given GATT characteristic is selected, check for supported features.
// This sample
// demonstrates 'Read' and 'Notify' features. See
// http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for
// the complete
// list of supported characteristic features.
private final ExpandableListView.OnChildClickListener servicesListClickListner = new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Log.d(TAG, "onChildClick " + groupPosition + " " + childPosition);
if (mGattCharacteristics != null) {
final BleGattCharacteristic characteristic = mGattCharacteristics
.get(groupPosition).get(childPosition);
Intent intent = new Intent(DeviceControlActivity.this,
CharacteristicActivity.class);
intent.putExtra("address", mDeviceAddress);
Log.d(TAG, "service size " + mBle.getServices(mDeviceAddress).size());
intent.putExtra("service", mBle.getServices(mDeviceAddress)
.get(groupPosition).getUuid().toString());
intent.putExtra("characteristic", characteristic.getUuid()
.toString().toUpperCase());
startActivity(intent);
return true;
}
return false;
}
};
private void clearUI() {
mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gatt_services_characteristics);
final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
// Sets up UI references.
((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);
mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
mGattServicesList.setOnChildClickListener(servicesListClickListner);
mConnectionState = (TextView) findViewById(R.id.connection_state);
getActionBar().setTitle(mDeviceName);
getActionBar().setDisplayHomeAsUpEnabled(true);
BleApplication app = (BleApplication) getApplication();
mBle = app.getIBle();
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(mBleReceiver, BleService.getIntentFilter());
ArrayList services = mBle.getServices(mDeviceAddress);
if (services == null || services.size() == 0) {
onDeviceDisconnected();
}
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mBleReceiver);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mBle != null) {
mBle.disconnect(mDeviceAddress);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.gatt_services, menu);
if (mConnected) {
menu.findItem(R.id.menu_connect).setVisible(true);
menu.findItem(R.id.menu_disconnect).setVisible(true);
} else {
menu.findItem(R.id.menu_connect).setVisible(true);
menu.findItem(R.id.menu_disconnect).setVisible(true);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_connect:
mBle.requestConnect(mDeviceAddress);
return true;
case R.id.menu_disconnect:
mBle.disconnect(mDeviceAddress);
onDeviceDisconnected();
return true;
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateConnectionState(final int resourceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mConnectionState.setText(resourceId);
}
});
}
// Demonstrates how to iterate through the supported GATT
// Services/Characteristics.
// In this sample, we populate the data structure that is bound to the
// ExpandableListView
// on the UI.
private void displayGattServices(List gattServices) {
if (gattServices == null)
return;
String uuid = null;
String unknownServiceString = getResources().getString(
R.string.unknown_service);
String unknownCharaString = getResources().getString(
R.string.unknown_characteristic);
ArrayList> gattServiceData = new ArrayList>();
ArrayList>> gattCharacteristicData = new ArrayList>>();
mGattCharacteristics = new ArrayList>();
// Loops through available GATT Services.
for (BleGattService gattService : gattServices) {
HashMap currentServiceData = new HashMap();
uuid = gattService.getUuid().toString().toUpperCase();
currentServiceData.put(LIST_NAME, Utils.BLE_SERVICES
.containsKey(uuid) ? Utils.BLE_SERVICES.get(uuid)
: unknownServiceString);
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
ArrayList> gattCharacteristicGroupData = new ArrayList>();
List gattCharacteristics = gattService
.getCharacteristics();
ArrayList charas = new ArrayList();
// Loops through available Characteristics.
for (BleGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap currentCharaData = new HashMap();
uuid = gattCharacteristic.getUuid().toString().toUpperCase();
currentCharaData
.put(LIST_NAME,
Utils.BLE_CHARACTERISTICS.containsKey(uuid) ? Utils.BLE_CHARACTERISTICS
.get(uuid) : unknownCharaString);
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
}
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
}
SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
this, gattServiceData,
android.R.layout.simple_expandable_list_item_2, new String[] {
LIST_NAME, LIST_UUID }, new int[] { android.R.id.text1,
android.R.id.text2 }, gattCharacteristicData,
android.R.layout.simple_expandable_list_item_2, new String[] {
LIST_NAME, LIST_UUID }, new int[] { android.R.id.text1,
android.R.id.text2 });
mGattServicesList.setAdapter(gattServiceAdapter);
}
private void onDeviceDisconnected() {
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
}
}
================================================
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/DeviceScanActivity.java
================================================
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed 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.
*/
/**
* This XPG software is supplied to you by Xtreme Programming Group, Inc.
* ("XPG") in consideration of your agreement to the following terms, and your
* use, installation, modification or redistribution of this XPG software
* constitutes acceptance of these terms.� If you do not agree with these terms,
* please do not use, install, modify or redistribute this XPG software.
*
* In consideration of your agreement to abide by the following terms, and
* subject to these terms, XPG grants you a non-exclusive license, under XPG's
* copyrights in this original XPG software (the "XPG Software"), to use and
* redistribute the XPG Software, in source and/or binary forms; provided that
* if you redistribute the XPG Software, with or without modifications, you must
* retain this notice and the following text and disclaimers in all such
* redistributions of the XPG Software. Neither the name, trademarks, service
* marks or logos of XPG Inc. may be used to endorse or promote products derived
* from the XPG Software without specific prior written permission from XPG.�
* Except as expressly stated in this notice, no other rights or licenses,
* express or implied, are granted by XPG herein, including but not limited to
* any patent rights that may be infringed by your derivative works or by other
* works in which the XPG Software may be incorporated.
*
* The XPG Software is provided by XPG on an "AS IS" basis.� XPG MAKES NO
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, REGARDING THE XPG SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
* COMBINATION WITH YOUR PRODUCTS.
*
* IN NO EVENT SHALL XPG BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
* AND/OR DISTRIBUTION OF THE XPG SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
* THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
* OTHERWISE, EVEN IF XPG HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ABOUT XPG: Established since June 2005, Xtreme Programming Group, Inc. (XPG)
* is a digital solutions company based in the United States and China. XPG
* integrates cutting-edge hardware designs, mobile applications, and cloud
* computing technologies to bring innovative products to the marketplace. XPG's
* partners and customers include global leading corporations in semiconductor,
* home appliances, health/wellness electronics, toys and games, and automotive
* industries. Visit www.xtremeprog.com for more information.
*
* Copyright (C) 2013 Xtreme Programming Group, Inc. All Rights Reserved.
*/
package com.example.bluetooth.le;
import java.util.ArrayList;
import android.app.Activity;
import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.xtremeprog.sdk.ble.BleService;
import com.xtremeprog.sdk.ble.IBle;
/**
* Activity for scanning and displaying available Bluetooth LE devices.
*/
public class DeviceScanActivity extends ListActivity {
private LeDeviceListAdapter mLeDeviceListAdapter;
private boolean mScanning;
private Handler mHandler;
private IBle mBle;
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
private final BroadcastReceiver mBleReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BleService.BLE_NOT_SUPPORTED.equals(action)) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(DeviceScanActivity.this,
"Ble not support", Toast.LENGTH_SHORT).show();
finish();
}
});
} else if (BleService.BLE_DEVICE_FOUND.equals(action)) {
// device found
Bundle extras = intent.getExtras();
final BluetoothDevice device = extras
.getParcelable(BleService.EXTRA_DEVICE);
runOnUiThread(new Runnable() {
@Override
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
} else if (BleService.BLE_NO_BT_ADAPTER.equals(action)) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(DeviceScanActivity.this,
"No bluetooth adapter", Toast.LENGTH_SHORT)
.show();
finish();
}
});
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setTitle(R.string.title_devices);
mHandler = new Handler();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
if (!mScanning) {
menu.findItem(R.id.menu_stop).setVisible(false);
menu.findItem(R.id.menu_scan).setVisible(true);
menu.findItem(R.id.menu_refresh).setActionView(null);
} else {
menu.findItem(R.id.menu_stop).setVisible(true);
menu.findItem(R.id.menu_scan).setVisible(false);
menu.findItem(R.id.menu_refresh).setActionView(
R.layout.actionbar_indeterminate_progress);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_scan:
mLeDeviceListAdapter.clear();
scanLeDevice(true);
break;
case R.id.menu_stop:
scanLeDevice(false);
break;
}
return true;
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(mBleReceiver, BleService.getIntentFilter());
// Ensures Bluetooth is enabled on the device. If Bluetooth is not
// currently enabled,
// fire an intent to display a dialog asking the user to grant
// permission to enable it.
if (mBle != null && !mBle.adapterEnabled()) {
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
// Initializes list view adapter.
mLeDeviceListAdapter = new LeDeviceListAdapter();
setListAdapter(mLeDeviceListAdapter);
scanLeDevice(true);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT
&& resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mBleReceiver);
scanLeDevice(false);
mLeDeviceListAdapter.clear();
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
if (device == null)
return;
final Intent intent = new Intent(this, DeviceControlActivity.class);
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME,
device.getName());
intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS,
device.getAddress());
if (mBle != null) {
mBle.stopScan();
}
startActivity(intent);
}
private void scanLeDevice(final boolean enable) {
BleApplication app = (BleApplication) getApplication();
mBle = app.getIBle();
if (mBle == null) {
return;
}
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
if (mBle != null) {
mBle.stopScan();
}
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
if (mBle != null) {
mBle.startScan();
}
} else {
mScanning = false;
if (mBle != null) {
mBle.stopScan();
}
}
invalidateOptionsMenu();
}
// Adapter for holding devices found through scanning.
private class LeDeviceListAdapter extends BaseAdapter {
private ArrayList mLeDevices;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList();
mInflator = DeviceScanActivity.this.getLayoutInflater();
}
public void addDevice(BluetoothDevice device) {
if (!mLeDevices.contains(device)) {
mLeDevices.add(device);
}
}
public BluetoothDevice getDevice(int position) {
return mLeDevices.get(position);
}
public void clear() {
mLeDevices.clear();
}
@Override
public int getCount() {
return mLeDevices.size();
}
@Override
public Object getItem(int i) {
return mLeDevices.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
// General ListView optimization code.
if (view == null) {
view = mInflator.inflate(R.layout.listitem_device, null);
viewHolder = new ViewHolder();
viewHolder.deviceAddress = (TextView) view
.findViewById(R.id.device_address);
viewHolder.deviceName = (TextView) view
.findViewById(R.id.device_name);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
}
BluetoothDevice device = mLeDevices.get(i);
final String deviceName = device.getName();
if (deviceName != null && deviceName.length() > 0)
viewHolder.deviceName.setText(deviceName);
else
viewHolder.deviceName.setText(R.string.unknown_device);
viewHolder.deviceAddress.setText(device.getAddress());
return view;
}
}
static class ViewHolder {
TextView deviceName;
TextView deviceAddress;
}
}
================================================
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/Utils.java
================================================
package com.example.bluetooth.le;
import java.util.HashMap;
import java.util.Map;
public class Utils {
public static Map BLE_SERVICES = new HashMap();
public static Map BLE_CHARACTERISTICS = new HashMap();
static {
BLE_SERVICES.put("00001811-0000-1000-8000-00805F9B34FB", "Alert Notification Service");
BLE_SERVICES.put("0000180F-0000-1000-8000-00805F9B34FB", "Battery Service");
BLE_SERVICES.put("00001810-0000-1000-8000-00805F9B34FB", "Blood Pressure");
BLE_SERVICES.put("00001805-0000-1000-8000-00805F9B34FB", "Current Time Service");
BLE_SERVICES.put("00001818-0000-1000-8000-00805F9B34FB", "Cycling Power");
BLE_SERVICES.put("00001816-0000-1000-8000-00805F9B34FB", "Cycling Speed and Cadence");
BLE_SERVICES.put("0000180A-0000-1000-8000-00805F9B34FB", "Device Information");
BLE_SERVICES.put("00001800-0000-1000-8000-00805F9B34FB", "Generic Access");
BLE_SERVICES.put("00001801-0000-1000-8000-00805F9B34FB", "Generic Attribute");
BLE_SERVICES.put("00001808-0000-1000-8000-00805F9B34FB", "Glucose");
BLE_SERVICES.put("00001809-0000-1000-8000-00805F9B34FB", "Health Thermometer");
BLE_SERVICES.put("0000180D-0000-1000-8000-00805F9B34FB", "Heart Rate");
BLE_SERVICES.put("00001812-0000-1000-8000-00805F9B34FB", "Human Interface Device");
BLE_SERVICES.put("00001802-0000-1000-8000-00805F9B34FB", "Immediate Alert");
BLE_SERVICES.put("00001803-0000-1000-8000-00805F9B34FB", "Link Loss");
BLE_SERVICES.put("00001819-0000-1000-8000-00805F9B34FB", "Location and Navigation");
BLE_SERVICES.put("00001807-0000-1000-8000-00805F9B34FB", "Next DST Change Service");
BLE_SERVICES.put("0000180E-0000-1000-8000-00805F9B34FB", "Phone Alert Status Service");
BLE_SERVICES.put("00001806-0000-1000-8000-00805F9B34FB", "Reference Time Update Service");
BLE_SERVICES.put("00001814-0000-1000-8000-00805F9B34FB", "Running Speed and Cadence");
BLE_SERVICES.put("00001813-0000-1000-8000-00805F9B34FB", "Scan Parameters");
BLE_SERVICES.put("00001804-0000-1000-8000-00805F9B34FB", "Tx Power");
BLE_CHARACTERISTICS.put("00002A43-0000-1000-8000-00805F9B34FB", "Alert Category ID");
BLE_CHARACTERISTICS.put("00002A42-0000-1000-8000-00805F9B34FB", "Alert Category ID Bit Mask");
BLE_CHARACTERISTICS.put("00002A06-0000-1000-8000-00805F9B34FB", "Alert Level");
BLE_CHARACTERISTICS.put("00002A44-0000-1000-8000-00805F9B34FB", "Alert Notification Control Point");
BLE_CHARACTERISTICS.put("00002A3F-0000-1000-8000-00805F9B34FB", "Alert Status");
BLE_CHARACTERISTICS.put("00002A01-0000-1000-8000-00805F9B34FB", "Appearance");
BLE_CHARACTERISTICS.put("00002A19-0000-1000-8000-00805F9B34FB", "Battery Level");
BLE_CHARACTERISTICS.put("00002A49-0000-1000-8000-00805F9B34FB", "Blood Pressure Feature");
BLE_CHARACTERISTICS.put("00002A35-0000-1000-8000-00805F9B34FB", "Blood Pressure Measurement");
BLE_CHARACTERISTICS.put("00002A38-0000-1000-8000-00805F9B34FB", "Body Sensor Location");
BLE_CHARACTERISTICS.put("00002A22-0000-1000-8000-00805F9B34FB", "Boot Keyboard Input Report");
BLE_CHARACTERISTICS.put("00002A32-0000-1000-8000-00805F9B34FB", "Boot Keyboard Output Report");
BLE_CHARACTERISTICS.put("00002A33-0000-1000-8000-00805F9B34FB", "Boot Mouse Input Report");
BLE_CHARACTERISTICS.put("00002A5C-0000-1000-8000-00805F9B34FB", "CSC Feature");
BLE_CHARACTERISTICS.put("00002A5B-0000-1000-8000-00805F9B34FB", "CSC Measurement");
BLE_CHARACTERISTICS.put("00002A2B-0000-1000-8000-00805F9B34FB", "Current Time");
BLE_CHARACTERISTICS.put("00002A66-0000-1000-8000-00805F9B34FB", "Cycling Power Control Point");
BLE_CHARACTERISTICS.put("00002A65-0000-1000-8000-00805F9B34FB", "Cycling Power Feature");
BLE_CHARACTERISTICS.put("00002A63-0000-1000-8000-00805F9B34FB", "Cycling Power Measurement");
BLE_CHARACTERISTICS.put("00002A64-0000-1000-8000-00805F9B34FB", "Cycling Power Vector");
BLE_CHARACTERISTICS.put("00002A08-0000-1000-8000-00805F9B34FB", "Date Time");
BLE_CHARACTERISTICS.put("00002A0A-0000-1000-8000-00805F9B34FB", "Day Date Time");
BLE_CHARACTERISTICS.put("00002A09-0000-1000-8000-00805F9B34FB", "Day of Week");
BLE_CHARACTERISTICS.put("00002A00-0000-1000-8000-00805F9B34FB", "Device Name");
BLE_CHARACTERISTICS.put("00002A0D-0000-1000-8000-00805F9B34FB", "DST Offset");
BLE_CHARACTERISTICS.put("00002A0C-0000-1000-8000-00805F9B34FB", "Exact Time 256");
BLE_CHARACTERISTICS.put("00002A26-0000-1000-8000-00805F9B34FB", "Firmware Revision String");
BLE_CHARACTERISTICS.put("00002A51-0000-1000-8000-00805F9B34FB", "Glucose Feature");
BLE_CHARACTERISTICS.put("00002A18-0000-1000-8000-00805F9B34FB", "Glucose Measurement");
BLE_CHARACTERISTICS.put("00002A34-0000-1000-8000-00805F9B34FB", "Glucose Measurement Context");
BLE_CHARACTERISTICS.put("00002A27-0000-1000-8000-00805F9B34FB", "Hardware Revision String");
BLE_CHARACTERISTICS.put("00002A39-0000-1000-8000-00805F9B34FB", "Heart Rate Control Point");
BLE_CHARACTERISTICS.put("00002A37-0000-1000-8000-00805F9B34FB", "Heart Rate Measurement");
BLE_CHARACTERISTICS.put("00002A4C-0000-1000-8000-00805F9B34FB", "HID Control Point");
BLE_CHARACTERISTICS.put("00002A4A-0000-1000-8000-00805F9B34FB", "HID Information");
BLE_CHARACTERISTICS.put("00002A2A-0000-1000-8000-00805F9B34FB", "IEEE 11073-20601 Regulatory Certification Data List");
BLE_CHARACTERISTICS.put("00002A36-0000-1000-8000-00805F9B34FB", "Intermediate Cuff Pressure");
BLE_CHARACTERISTICS.put("00002A1E-0000-1000-8000-00805F9B34FB", "Intermediate Temperature");
BLE_CHARACTERISTICS.put("00002A6B-0000-1000-8000-00805F9B34FB", "LN Control Point");
BLE_CHARACTERISTICS.put("00002A6A-0000-1000-8000-00805F9B34FB", "LN Feature");
BLE_CHARACTERISTICS.put("00002A0F-0000-1000-8000-00805F9B34FB", "Local Time Information");
BLE_CHARACTERISTICS.put("00002A67-0000-1000-8000-00805F9B34FB", "Location and Speed");
BLE_CHARACTERISTICS.put("00002A29-0000-1000-8000-00805F9B34FB", "Manufacturer Name String");
BLE_CHARACTERISTICS.put("00002A21-0000-1000-8000-00805F9B34FB", "Measurement Interval");
BLE_CHARACTERISTICS.put("00002A24-0000-1000-8000-00805F9B34FB", "Model Number String");
BLE_CHARACTERISTICS.put("00002A68-0000-1000-8000-00805F9B34FB", "Navigation");
BLE_CHARACTERISTICS.put("00002A46-0000-1000-8000-00805F9B34FB", "New Alert");
BLE_CHARACTERISTICS.put("00002A04-0000-1000-8000-00805F9B34FB", "Peripheral Preferred Connection Parameters");
BLE_CHARACTERISTICS.put("00002A02-0000-1000-8000-00805F9B34FB", "Peripheral Privacy Flag");
BLE_CHARACTERISTICS.put("00002A50-0000-1000-8000-00805F9B34FB", "PnP ID");
BLE_CHARACTERISTICS.put("00002A69-0000-1000-8000-00805F9B34FB", "Position Quality");
BLE_CHARACTERISTICS.put("00002A4E-0000-1000-8000-00805F9B34FB", "Protocol Mode");
BLE_CHARACTERISTICS.put("00002A03-0000-1000-8000-00805F9B34FB", "Reconnection Address");
BLE_CHARACTERISTICS.put("00002A52-0000-1000-8000-00805F9B34FB", "Record Access Control Point");
BLE_CHARACTERISTICS.put("00002A14-0000-1000-8000-00805F9B34FB", "Reference Time Information");
BLE_CHARACTERISTICS.put("00002A4D-0000-1000-8000-00805F9B34FB", "Report");
BLE_CHARACTERISTICS.put("00002A4B-0000-1000-8000-00805F9B34FB", "Report Map");
BLE_CHARACTERISTICS.put("00002A40-0000-1000-8000-00805F9B34FB", "Ringer Control Point");
BLE_CHARACTERISTICS.put("00002A41-0000-1000-8000-00805F9B34FB", "Ringer Setting");
BLE_CHARACTERISTICS.put("00002A54-0000-1000-8000-00805F9B34FB", "RSC Feature");
BLE_CHARACTERISTICS.put("00002A53-0000-1000-8000-00805F9B34FB", "RSC Measurement");
BLE_CHARACTERISTICS.put("00002A55-0000-1000-8000-00805F9B34FB", "SC Control Point");
BLE_CHARACTERISTICS.put("00002A4F-0000-1000-8000-00805F9B34FB", "Scan Interval Window");
BLE_CHARACTERISTICS.put("00002A31-0000-1000-8000-00805F9B34FB", "Scan Refresh");
BLE_CHARACTERISTICS.put("00002A5D-0000-1000-8000-00805F9B34FB", "Sensor Location");
BLE_CHARACTERISTICS.put("00002A25-0000-1000-8000-00805F9B34FB", "Serial Number String");
BLE_CHARACTERISTICS.put("00002A05-0000-1000-8000-00805F9B34FB", "Service Changed");
BLE_CHARACTERISTICS.put("00002A28-0000-1000-8000-00805F9B34FB", "Software Revision String");
BLE_CHARACTERISTICS.put("00002A47-0000-1000-8000-00805F9B34FB", "Supported New Alert Category");
BLE_CHARACTERISTICS.put("00002A48-0000-1000-8000-00805F9B34FB", "Supported Unread Alert Category");
BLE_CHARACTERISTICS.put("00002A23-0000-1000-8000-00805F9B34FB", "System ID");
BLE_CHARACTERISTICS.put("00002A1C-0000-1000-8000-00805F9B34FB", "Temperature Measurement");
BLE_CHARACTERISTICS.put("00002A1D-0000-1000-8000-00805F9B34FB", "Temperature Type");
BLE_CHARACTERISTICS.put("00002A12-0000-1000-8000-00805F9B34FB", "Time Accuracy");
BLE_CHARACTERISTICS.put("00002A13-0000-1000-8000-00805F9B34FB", "Time Source");
BLE_CHARACTERISTICS.put("00002A16-0000-1000-8000-00805F9B34FB", "Time Update Control Point");
BLE_CHARACTERISTICS.put("00002A17-0000-1000-8000-00805F9B34FB", "Time Update State");
BLE_CHARACTERISTICS.put("00002A11-0000-1000-8000-00805F9B34FB", "Time with DST");
BLE_CHARACTERISTICS.put("00002A0E-0000-1000-8000-00805F9B34FB", "Time Zone");
BLE_CHARACTERISTICS.put("00002A07-0000-1000-8000-00805F9B34FB", "Tx Power Level");
BLE_CHARACTERISTICS.put("00002A45-0000-1000-8000-00805F9B34FB", "Unread Alert Status");
}
private static Utils INSTANCE;
private Utils() {}
public static Utils getInstance() {
if (INSTANCE == null) {
INSTANCE = new Utils();
}
return INSTANCE;
}
}
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed 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.
================================================
FILE: README.md
================================================
GizwitsBLE
==========
GizwitsBLE solves the compatibility and reliability issues that have troubled developers. First, many BLE-ready Android phones (e.g. Samsung S2 and Note2) have not been upgraded to Android 4.3. Therefore adding Android app-level BLE support requires developers to code against a number of vendor specific BLE SDK's. Second, the Android 4.3 native BLE support has a number of pitfalls that seriously affect user experience. Since android users rarely upgrade their Operating Systems, Android 4.2 and 4.3 will continue to dominate the Android smartphone market for the next few years.
GizwitsBLE Android SDK was build to be a quick and reliable solution for developers to add robust BLE support for Android 4.2 and Android 4.3+ smartphones with a simple common interface. On Android 4.2 phones, GizwitsBLE automatically detects and adapts to the corresponding vendor specific SDK (e.g. those provided by Samsung and Broadcom), so that developers don't have to learn and code against the specifies of each implementation.
On Android 4.3 phones, BLE related calls tends to crash the app and even the Operating System for no apparent reasons. Through trial and error, the Gizwits team has found that BLE calls must be made serially to avoid system crashes, and therefore all requests (connection, discovery service, read or write characteristics) are queued and executed sequentially. This has made BLE communications much more stable.
GizwitsBLE has a simple interface that's easy to learn and is open sourced. It is also been heavily tested and is commercially ready. It powers dozens of BLE products. We encourage all developers frustrated by the fragmented and inconsistent BLE support on try it out.
# Main Features
* Support Android 4.2 (Broadcom, Sumsung SDK) and Android 4.3+
* Built in Service, just start the service and receive BLE events by broadcast
* Built in BLE request queue
# Components
* BleLibrary: this is the library project you can reuse in your project.
* BluetoothLeGatt: this is the demo app project that uses BleLibrary.
# Compile & Run
## Eclipse
These two projects are eclipse projects. If you use eclipse, you can import these projects directly and run BluetoothLeGatt.
## Android Studio
If you use android studio, you should import these project.
When it goes to Libraries step, it will show libs and libs1, just choose libs and ignore libs1.
When it goes to select project SDK step, ensure you choose Android API > 17.
Then you can run BluetoothLeGatt in android studio.