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
================================================
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
================================================
FILE: BleLibrary/.project
================================================
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>BleLibrary</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
================================================
FILE: BleLibrary/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xtremeprog.sdk.ble"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
</application>
</manifest>
================================================
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 <fields>;
public protected <methods>;
}
# 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 <methods>;
}
================================================
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
================================================
<resources>
<string name="app_name">BleLibrary</string>
</resources>
================================================
FILE: BleLibrary/res/values/styles.xml
================================================
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
</resources>
================================================
FILE: BleLibrary/res/values-v11/styles.xml
================================================
<resources>
<!--
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
<!-- API 11 theme customizations can go here. -->
</style>
</resources>
================================================
FILE: BleLibrary/res/values-v14/styles.xml
================================================
<resources>
<!--
Base application theme for API 14+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
</style>
</resources>
================================================
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<String, BluetoothGatt> 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<String, BluetoothGatt>();
}
@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<BleGattService> getServices(String address) {
BluetoothGatt gatt = mBluetoothGatts.get(address);
if (gatt == null) {
return null;
}
ArrayList<BleGattService> list = new ArrayList<BleGattService>();
List<BluetoothGattService> 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<BleGattCharacteristic> getCharacteristics() {
ArrayList<BleGattCharacteristic> list = new ArrayList<BleGattCharacteristic>();
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<BleRequest> mRequestQueue = new LinkedList<BleRequest>();
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<String> libraries = new ArrayList<String>();
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. <br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_DEVICE} device {@link BluetoothDevice} <br>
* {@link BleService#EXTRA_RSSI} rssi int<br>
* {@link BleService#EXTRA_SCAN_RECORD} scan record byte[] <br>
* {@link BleService#EXTRA_SOURCE} source int, not used now <br>
*/
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. <br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_DEVICE} device {@link BluetoothDevice} <br>
*/
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. <br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_ADDR} device address {@link String} <br>
*
* @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. <br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_ADDR} device address {@link String} <br>
*
* @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. <br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_ADDR} device address {@link String} <br>
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}<br>
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now <br>
* {@link BleService#EXTRA_VALUE} data byte[] <br>
*
* @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. <br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_ADDR} device address {@link String} <br>
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}<br>
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now <br>
*
* @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. <br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_ADDR} device address {@link String} <br>
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}<br>
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now <br>
*
* @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. <br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_ADDR} device address {@link String} <br>
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}<br>
* {@link BleService#EXTRA_STATUS} read status {@link Integer} Not used now <br>
*
* @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. <br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_ADDR} device address {@link String} <br>
* {@link BleService#EXTRA_UUID} characteristic uuid {@link String}<br>
* {@link BleService#EXTRA_VALUE} data byte[] <br>
*
* @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.<br>
* <br>
* Data in the broadcast intent: <br>
* {@link BleService#EXTRA_ADDR} device address {@link String} <br>
* {@link BleService#EXTRA_REQUEST} request type
* {@link BleRequest.RequestType} <br>
* {@link BleService#EXTRA_REASON} fail reason {@link BleRequest.FailReason} <br>
*/
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<BleGattService> getServices(String address) {
ArrayList<BleGattService> list = new ArrayList<BleGattService>();
BluetoothDevice device = mBtAdapter.getRemoteDevice(address);
List<BluetoothGattService> 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<BleGattService> 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<BleGattService> getServices(String address) {
ArrayList<BleGattService> list = new ArrayList<BleGattService>();
BluetoothDevice device = mBtAdapter.getRemoteDevice(address);
List<BluetoothGattService> 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
================================================
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
================================================
FILE: BluetoothLeGatt/.project
================================================
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>DeviceScanActivity</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
================================================
FILE: BluetoothLeGatt/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluetooth.le"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="17" />
<!--
Declare this required feature if you want to make the app available to BLE-capable
devices only. If you want to make your app available to devices that don't support BLE,
you should omit this in the manifest. Instead, determine BLE capability by using
PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE)
-->
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name="com.example.bluetooth.le.BleApplication"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light" >
<activity
android:name="com.example.bluetooth.le.DeviceScanActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.bluetooth.le.DeviceControlActivity" >
</activity>
<service
android:name="com.xtremeprog.sdk.ble.BleService"
android:enabled="true" />
<activity
android:name="com.example.bluetooth.le.CharacteristicActivity"
android:label="@string/title_activity_characteristic" >
</activity>
</application>
</manifest>
================================================
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
================================================
<!--
Copyright 2013 Google Inc.
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.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="56dp"
android:minWidth="56dp">
<ProgressBar android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center"/>
</FrameLayout>
================================================
FILE: BluetoothLeGatt/res/layout/activity_characteristic.xml
================================================
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp"
tools:context="com.example.bluetooth.le.CharacteristicActivity" >
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp" />
<TextView
android:id="@+id/tv_uuid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ASCII: "
android:textSize="18sp" />
<TextView
android:id="@+id/tv_ascii"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="HEX: "
android:textSize="18sp" />
<TextView
android:id="@+id/tv_hex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btn_read"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Read"
android:visibility="gone" />
<Button
android:id="@+id/btn_notify"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Notify"
android:visibility="gone" />
<Button
android:id="@+id/btn_indicate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Indicate"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_write"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" >
<Button
android:id="@+id/btn_write"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Write" />
<EditText
android:id="@+id/et_hex"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="0x0A30BC" />
</LinearLayout>
</LinearLayout>
================================================
FILE: BluetoothLeGatt/res/layout/gatt_services_characteristics.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_device_address"
android:textSize="18sp" />
<Space
android:layout_width="5dp"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/device_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_state"
android:textSize="18sp" />
<Space
android:layout_width="5dp"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/connection_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/disconnected"
android:textSize="18sp" />
</LinearLayout>
<ExpandableListView
android:id="@+id/gatt_services_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
================================================
FILE: BluetoothLeGatt/res/layout/listitem_device.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/device_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24dp"/>
<TextView android:id="@+id/device_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12dp"/>
</LinearLayout>
================================================
FILE: BluetoothLeGatt/res/menu/characteristic.xml
================================================
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.bluetooth.le.CharacteristicActivity" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>
================================================
FILE: BluetoothLeGatt/res/menu/gatt_services.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_refresh"
android:checkable="false"
android:orderInCategory="1"
android:showAsAction="ifRoom"/>
<item android:id="@+id/menu_connect"
android:title="@string/menu_connect"
android:orderInCategory="100"
android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_disconnect"
android:title="@string/menu_disconnect"
android:orderInCategory="101"
android:showAsAction="ifRoom|withText"/>
</menu>
================================================
FILE: BluetoothLeGatt/res/menu/main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_refresh"
android:checkable="false"
android:orderInCategory="1"
android:showAsAction="ifRoom"/>
<item android:id="@+id/menu_scan"
android:title="@string/menu_scan"
android:orderInCategory="100"
android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_stop"
android:title="@string/menu_stop"
android:orderInCategory="101"
android:showAsAction="ifRoom|withText"/>
</menu>
================================================
FILE: BluetoothLeGatt/res/values/dimens.xml
================================================
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
================================================
FILE: BluetoothLeGatt/res/values/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<resources>
<string name="app_name">BLE Sample</string>
<string name="ble_not_supported">BLE is not supported</string>
<string name="label_data">Data:</string>
<string name="label_device_address">Device address:</string>
<string name="label_state">State:</string>
<string name="no_data">No data</string>
<string name="connected">Connected</string>
<string name="disconnected">Disconnected</string>
<string name="title_devices">BLE Device Scan</string>
<string name="error_bluetooth_not_supported">Bluetooth not supported.</string>
<string name="unknown_device">Unknown device</string>
<string name="unknown_characteristic">Unknown characteristic</string>
<string name="unknown_service">Unknown service</string>
<!-- Menu items -->
<string name="menu_connect">Connect</string>
<string name="menu_disconnect">Disconnect</string>
<string name="menu_scan">Scan</string>
<string name="menu_stop">Stop</string>
<string name="title_activity_characteristic">CharacteristicActivity</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
</resources>
================================================
FILE: BluetoothLeGatt/res/values-w820dp/dimens.xml
================================================
<resources>
<!--
Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
-->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
================================================
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<ArrayList<BleGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BleGattCharacteristic>>();
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<BleGattService> 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<BleGattService> 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<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();
mGattCharacteristics = new ArrayList<ArrayList<BleGattCharacteristic>>();
// Loops through available GATT Services.
for (BleGattService gattService : gattServices) {
HashMap<String, String> currentServiceData = new HashMap<String, String>();
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<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();
List<BleGattCharacteristic> gattCharacteristics = gattService
.getCharacteristics();
ArrayList<BleGattCharacteristic> charas = new ArrayList<BleGattCharacteristic>();
// Loops through available Characteristics.
for (BleGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap<String, String> currentCharaData = new HashMap<String, String>();
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<BluetoothDevice> mLeDevices;
private LayoutInflater mInflator;
public LeDeviceListAdapter() {
super();
mLeDevices = new ArrayList<BluetoothDevice>();
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<String, String> BLE_SERVICES = new HashMap<String, String>();
public static Map<String, String> BLE_CHARACTERISTICS = new HashMap<String, String>();
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.
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
SYMBOL INDEX (231 symbols across 14 files)
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/AndroidBle.java
class AndroidBle (line 73) | @SuppressLint("NewApi")
method onLeScan (line 84) | @Override
method onConnectionStateChange (line 93) | @Override
method onServicesDiscovered (line 115) | @Override
method onCharacteristicRead (line 127) | @Override
method onCharacteristicChanged (line 143) | @Override
method onCharacteristicWrite (line 153) | public void onCharacteristicWrite(BluetoothGatt gatt,
method onDescriptorWrite (line 166) | public void onDescriptorWrite(BluetoothGatt gatt,
method AndroidBle (line 196) | public AndroidBle(BleService service) {
method startScan (line 215) | @Override
method stopScan (line 220) | @Override
method adapterEnabled (line 225) | @Override
method connect (line 233) | @Override
method disconnect (line 248) | @Override
method getServices (line 259) | @Override
method requestReadCharacteristic (line 276) | @Override
method readCharacteristic (line 289) | public boolean readCharacteristic(String address,
method discoverServices (line 299) | @Override
method getService (line 313) | @Override
method requestCharacteristicNotification (line 328) | @Override
method characteristicNotification (line 342) | @Override
method requestWriteCharacteristic (line 381) | @Override
method writeCharacteristic (line 394) | @Override
method requestConnect (line 407) | @Override
method getBTAdapterMacAddr (line 418) | @Override
method requestIndication (line 426) | @Override
method requestStopNotification (line 440) | @Override
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleGattCharacteristic.java
class BleGattCharacteristic (line 55) | @SuppressLint("NewApi")
method BleGattCharacteristic (line 115) | public BleGattCharacteristic(android.bluetooth.BluetoothGattCharacteri...
method BleGattCharacteristic (line 121) | public BleGattCharacteristic(
method BleGattCharacteristic (line 127) | public BleGattCharacteristic(
method initInfo (line 133) | private void initInfo() {
method getUuid (line 137) | public UUID getUuid() {
method getGattCharacteristicA (line 149) | protected android.bluetooth.BluetoothGattCharacteristic getGattCharact...
method getProperties (line 153) | public int getProperties() {
method getGattCharacteristicB (line 165) | protected com.broadcom.bt.gatt.BluetoothGattCharacteristic getGattChar...
method setGattCharacteristicB (line 169) | protected void setGattCharacteristicB(
method getName (line 174) | public String getName() {
method setName (line 178) | public void setName(String name) {
method setValue (line 182) | public boolean setValue(byte[] val) {
method getValue (line 194) | public byte[] getValue() {
method setValue (line 206) | public boolean setValue(int value, int formatType, int offset) {
method setValue (line 218) | public boolean setValue(int mantissa, int exponent, int formatType,
method setValue (line 234) | public boolean setValue(String value) {
method getStringValue (line 238) | public String getStringValue(int offset) {
method getFloatValue (line 250) | public Float getFloatValue(int formatType, int offset) {
method getIntValue (line 262) | public Integer getIntValue(int formatType, int offset) {
method byte2uint24 (line 289) | private Integer byte2uint24(int offset, byte[] value) {
method getGattCharacteristicS (line 297) | protected com.samsung.android.sdk.bt.gatt.BluetoothGattCharacteristic ...
method setGattCharacteristicS (line 301) | protected void setGattCharacteristicS(
method setGattCharacteristicA (line 306) | protected void setGattCharacteristicA(
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleGattService.java
class BleGattService (line 61) | @SuppressLint("NewApi")
method BleGattService (line 70) | public BleGattService(com.samsung.android.sdk.bt.gatt.BluetoothGattSer...
method BleGattService (line 76) | public BleGattService(com.broadcom.bt.gatt.BluetoothGattService s) {
method BleGattService (line 82) | public BleGattService(android.bluetooth.BluetoothGattService s) {
method initInfo (line 88) | private void initInfo() {
method getUuid (line 92) | public UUID getUuid() {
method getCharacteristics (line 104) | public List<BleGattCharacteristic> getCharacteristics() {
method getCharacteristic (line 126) | public BleGattCharacteristic getCharacteristic(UUID uuid) {
method setInfo (line 150) | public void setInfo(JSONObject info) {
method getName (line 162) | public String getName() {
method setName (line 166) | public void setName(String mName) {
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleRequest.java
class BleRequest (line 49) | public class BleRequest {
type RequestType (line 50) | public enum RequestType {
type FailReason (line 54) | public enum FailReason {
method BleRequest (line 63) | public BleRequest(RequestType type, String address) {
method BleRequest (line 68) | public BleRequest(RequestType type, String address,
method BleRequest (line 75) | public BleRequest(RequestType type, String address,
method equals (line 83) | @Override
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BleService.java
class BleService (line 67) | public class BleService extends Service {
type BLESDK (line 136) | public enum BLESDK {
method run (line 154) | @Override
method getIntentFilter (line 194) | public static IntentFilter getIntentFilter() {
method onBind (line 211) | @Override
class LocalBinder (line 216) | public class LocalBinder extends Binder {
method getService (line 217) | public BleService getService() {
method onCreate (line 222) | @Override
method bleNotSupported (line 239) | protected void bleNotSupported() {
method bleNoBtAdapter (line 244) | protected void bleNoBtAdapter() {
method getBleSDK (line 249) | private BLESDK getBleSDK() {
method getBle (line 274) | public IBle getBle() {
method bleDeviceFound (line 287) | protected void bleDeviceFound(BluetoothDevice device, int rssi,
method bleGattConnected (line 305) | protected void bleGattConnected(BluetoothDevice device) {
method bleGattDisConnected (line 321) | protected void bleGattDisConnected(String address) {
method bleServiceDiscovered (line 336) | protected void bleServiceDiscovered(String address) {
method requestProcessed (line 343) | protected void requestProcessed(String address, RequestType requestType,
method clearTimeoutThread (line 363) | private void clearTimeoutThread() {
method bleCharacteristicRead (line 389) | protected void bleCharacteristicRead(String address, String uuid,
method addBleRequest (line 400) | protected void addBleRequest(BleRequest request) {
method processNextRequest (line 407) | private synchronized void processNextRequest() {
method startTimeoutThread (line 463) | private void startTimeoutThread() {
method getCurrentRequest (line 469) | protected BleRequest getCurrentRequest() {
method setCurrentRequest (line 473) | protected void setCurrentRequest(BleRequest mCurrentRequest) {
method bleCharacteristicNotification (line 489) | protected void bleCharacteristicNotification(String address, String uuid,
method bleCharacteristicIndication (line 519) | protected void bleCharacteristicIndication(String address, String uuid,
method bleCharacteristicWrite (line 542) | protected void bleCharacteristicWrite(String address, String uuid,
method bleCharacteristicChanged (line 564) | protected void bleCharacteristicChanged(String address, String uuid,
method bleStatusAbnormal (line 576) | protected void bleStatusAbnormal(String reason) {
method bleRequestFailed (line 591) | protected void bleRequestFailed(String address, RequestType type,
method getNotificationAddress (line 600) | protected String getNotificationAddress() {
method setNotificationAddress (line 604) | protected void setNotificationAddress(String mNotificationAddress) {
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/BroadcomBle.java
class BroadcomBle (line 66) | public class BroadcomBle implements IBle, IBleRequestHandler {
method onAppRegistered (line 74) | @Override
method onScanResult (line 78) | @Override
method onConnectionStateChange (line 85) | @Override
method onServicesDiscovered (line 102) | @Override
method onCharacteristicRead (line 107) | @Override
method onCharacteristicChanged (line 117) | @Override
method onDescriptorRead (line 125) | @Override
method onDescriptorWrite (line 163) | @Override
method onServiceConnected (line 194) | @Override
method onServiceDisconnected (line 200) | @Override
method BroadcomBle (line 209) | public BroadcomBle(BleService service) {
method startScan (line 220) | @Override
method stopScan (line 235) | @Override
method adapterEnabled (line 245) | @Override
method connect (line 253) | @Override
method disconnect (line 259) | @Override
method getServices (line 265) | @Override
method requestReadCharacteristic (line 277) | @Override
method discoverServices (line 285) | @Override
method readCharacteristic (line 290) | @Override
method getService (line 300) | @Override
method requestCharacteristicNotification (line 311) | @Override
method characteristicNotification (line 320) | @Override
method requestWriteCharacteristic (line 343) | @Override
method writeCharacteristic (line 351) | @Override
method requestConnect (line 358) | @Override
method getBTAdapterMacAddr (line 367) | @Override
method requestIndication (line 375) | @Override
method requestStopNotification (line 383) | @Override
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/IBle.java
type IBle (line 52) | public interface IBle {
method getBTAdapterMacAddr (line 54) | public String getBTAdapterMacAddr();
method startScan (line 60) | public void startScan();
method stopScan (line 65) | public void stopScan();
method adapterEnabled (line 72) | public boolean adapterEnabled();
method disconnect (line 82) | public void disconnect(String address);
method discoverServices (line 92) | public boolean discoverServices(String address);
method getServices (line 101) | public ArrayList<BleGattService> getServices(String address);
method getService (line 111) | public BleGattService getService(String address, UUID uuid);
method requestConnect (line 120) | public boolean requestConnect(String address);
method requestReadCharacteristic (line 132) | public boolean requestReadCharacteristic(String address,
method requestCharacteristicNotification (line 147) | public boolean requestCharacteristicNotification(String address,
method requestStopNotification (line 150) | public boolean requestStopNotification(String address,
method requestIndication (line 165) | public boolean requestIndication(String address,
method requestWriteCharacteristic (line 180) | public boolean requestWriteCharacteristic(String address,
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/IBleRequestHandler.java
type IBleRequestHandler (line 49) | public interface IBleRequestHandler {
method connect (line 51) | public boolean connect(String address);
method readCharacteristic (line 58) | public boolean readCharacteristic(String address,
method characteristicNotification (line 66) | public boolean characteristicNotification(String address,
method writeCharacteristic (line 74) | public boolean writeCharacteristic(String address,
FILE: BleLibrary/src/com/xtremeprog/sdk/ble/SamsungBle.java
class SamsungBle (line 67) | public class SamsungBle implements IBle, IBleRequestHandler {
method onAppRegistered (line 77) | @Override
method onScanResult (line 81) | @Override
method onConnectionStateChange (line 88) | @Override
method onServicesDiscovered (line 111) | @Override
method onCharacteristicRead (line 124) | @Override
method onCharacteristicChanged (line 138) | @Override
method onCharacteristicWrite (line 147) | @Override
method onDescriptorRead (line 161) | @Override
method onDescriptorWrite (line 199) | @Override
method onServiceConnected (line 231) | @Override
method onServiceDisconnected (line 237) | @Override
method SamsungBle (line 243) | public SamsungBle(BleService service) {
method startScan (line 254) | @Override
method stopScan (line 269) | @Override
method adapterEnabled (line 279) | @Override
method connect (line 287) | @Override
method disconnect (line 293) | @Override
method getServices (line 299) | @Override
method requestReadCharacteristic (line 311) | @Override
method discoverServices (line 319) | @Override
method readCharacteristic (line 325) | @Override
method getService (line 332) | @Override
method requestCharacteristicNotification (line 343) | @Override
method characteristicNotification (line 352) | @Override
method requestWriteCharacteristic (line 370) | @Override
method writeCharacteristic (line 378) | @Override
method requestConnect (line 385) | @Override
method getBTAdapterMacAddr (line 391) | @Override
method requestIndication (line 399) | @Override
method requestStopNotification (line 407) | @Override
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/BleApplication.java
class BleApplication (line 13) | public class BleApplication extends Application {
method onServiceConnected (line 19) | @Override
method onServiceDisconnected (line 29) | @Override
method onCreate (line 35) | @Override
method getIBle (line 43) | public IBle getIBle() {
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/CharacteristicActivity.java
class CharacteristicActivity (line 26) | public class CharacteristicActivity extends Activity {
method onClick (line 34) | @Override
method onReceive (line 63) | @Override
method onCreate (line 112) | @Override
method onCreateOptionsMenu (line 162) | @Override
method onOptionsItemSelected (line 170) | @Override
method onResume (line 182) | @Override
method onPanelClosed (line 188) | @Override
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/DeviceControlActivity.java
class DeviceControlActivity (line 94) | public class DeviceControlActivity extends Activity {
method onReceive (line 121) | @Override
method onChildClick (line 148) | @Override
method clearUI (line 170) | private void clearUI() {
method onCreate (line 174) | @Override
method onResume (line 195) | @Override
method onPause (line 205) | @Override
method onDestroy (line 211) | @Override
method onCreateOptionsMenu (line 219) | @Override
method onOptionsItemSelected (line 232) | @Override
method updateConnectionState (line 249) | private void updateConnectionState(final int resourceId) {
method displayGattServices (line 263) | private void displayGattServices(List<BleGattService> gattServices) {
method onDeviceDisconnected (line 318) | private void onDeviceDisconnected() {
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/DeviceScanActivity.java
class DeviceScanActivity (line 91) | public class DeviceScanActivity extends ListActivity {
method onReceive (line 103) | @Override
method onCreate (line 141) | @Override
method onCreateOptionsMenu (line 148) | @Override
method onOptionsItemSelected (line 164) | @Override
method onResume (line 178) | @Override
method onActivityResult (line 199) | @Override
method onPause (line 210) | @Override
method onListItemClick (line 218) | @Override
method scanLeDevice (line 234) | private void scanLeDevice(final boolean enable) {
class LeDeviceListAdapter (line 267) | private class LeDeviceListAdapter extends BaseAdapter {
method LeDeviceListAdapter (line 271) | public LeDeviceListAdapter() {
method addDevice (line 277) | public void addDevice(BluetoothDevice device) {
method getDevice (line 283) | public BluetoothDevice getDevice(int position) {
method clear (line 287) | public void clear() {
method getCount (line 291) | @Override
method getItem (line 296) | @Override
method getItemId (line 301) | @Override
method getView (line 306) | @Override
class ViewHolder (line 334) | static class ViewHolder {
FILE: BluetoothLeGatt/src/com/example/bluetooth/le/Utils.java
class Utils (line 6) | public class Utils {
method Utils (line 119) | private Utils() {}
method getInstance (line 121) | public static Utils getInstance() {
Condensed preview — 47 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (186K chars).
[
{
"path": ".gitignore",
"chars": 271,
"preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbi"
},
{
"path": "BleLibrary/.classpath",
"chars": 466,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"src\" path=\"src\"/>\n\t<classpathentry kind=\"src\" "
},
{
"path": "BleLibrary/.project",
"chars": 813,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>BleLibrary</name>\n\t<comment></comment>\n\t<projects>\n\t<"
},
{
"path": "BleLibrary/AndroidManifest.xml",
"chars": 470,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.xtremeprog.sdk.ble\"\n android:ve"
},
{
"path": "BleLibrary/proguard-project.txt",
"chars": 781,
"preview": "# To enable ProGuard in your project, edit project.properties\n# to define the proguard.config property as described in t"
},
{
"path": "BleLibrary/proguard.pro",
"chars": 1142,
"preview": "-injars bin/blelibrary.jar\n-outjars bin/blelibrary-0.1.jar\n\n-libraryjars /Users/teamx/bin/adt-bundle-mac-x86_64-20130917"
},
{
"path": "BleLibrary/project.properties",
"chars": 584,
"preview": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# T"
},
{
"path": "BleLibrary/res/values/strings.xml",
"chars": 75,
"preview": "<resources>\n\n <string name=\"app_name\">BleLibrary</string>\n\n</resources>\n"
},
{
"path": "BleLibrary/res/values/styles.xml",
"chars": 680,
"preview": "<resources>\n\n <!--\n Base application theme, dependent on API level. This theme is replaced\n by AppBaseT"
},
{
"path": "BleLibrary/res/values-v11/styles.xml",
"chars": 324,
"preview": "<resources>\n\n <!--\n Base application theme for API 11+. This theme completely replaces\n AppBaseTheme fr"
},
{
"path": "BleLibrary/res/values-v14/styles.xml",
"chars": 381,
"preview": "<resources>\n\n <!--\n Base application theme for API 14+. This theme completely replaces\n AppBaseTheme fr"
},
{
"path": "BleLibrary/src/com/xtremeprog/sdk/ble/AndroidBle.java",
"chars": 15065,
"preview": "/**\n * This XPG software is supplied to you by Xtreme Programming Group, Inc.\n * (\"XPG\") in consideration of your agreem"
},
{
"path": "BleLibrary/src/com/xtremeprog/sdk/ble/BleGattCharacteristic.java",
"chars": 10202,
"preview": "/**\n * This XPG software is supplied to you by Xtreme Programming Group, Inc.\n * (\"XPG\") in consideration of your agreem"
},
{
"path": "BleLibrary/src/com/xtremeprog/sdk/ble/BleGattService.java",
"chars": 6078,
"preview": "/**\n * This XPG software is supplied to you by Xtreme Programming Group, Inc.\n * (\"XPG\") in consideration of your agreem"
},
{
"path": "BleLibrary/src/com/xtremeprog/sdk/ble/BleRequest.java",
"chars": 4100,
"preview": "/**\n * This XPG software is supplied to you by Xtreme Programming Group, Inc.\n * (\"XPG\") in consideration of your agreem"
},
{
"path": "BleLibrary/src/com/xtremeprog/sdk/ble/BleService.java",
"chars": 20621,
"preview": "/**\n * This XPG software is supplied to you by Xtreme Programming Group, Inc.\n * (\"XPG\") in consideration of your agreem"
},
{
"path": "BleLibrary/src/com/xtremeprog/sdk/ble/BroadcomBle.java",
"chars": 12797,
"preview": "/**\n * This XPG software is supplied to you by Xtreme Programming Group, Inc.\n * (\"XPG\") in consideration of your agreem"
},
{
"path": "BleLibrary/src/com/xtremeprog/sdk/ble/IBle.java",
"chars": 6743,
"preview": "/**\n * This XPG software is supplied to you by Xtreme Programming Group, Inc.\n * (\"XPG\") in consideration of your agreem"
},
{
"path": "BleLibrary/src/com/xtremeprog/sdk/ble/IBleRequestHandler.java",
"chars": 3488,
"preview": "/**\n * This XPG software is supplied to you by Xtreme Programming Group, Inc.\n * (\"XPG\") in consideration of your agreem"
},
{
"path": "BleLibrary/src/com/xtremeprog/sdk/ble/SamsungBle.java",
"chars": 13691,
"preview": "/**\n * This XPG software is supplied to you by Xtreme Programming Group, Inc.\n * (\"XPG\") in consideration of your agreem"
},
{
"path": "BluetoothLeGatt/.classpath",
"chars": 466,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classpath>\n\t<classpathentry kind=\"con\" path=\"com.android.ide.eclipse.adt.ANDROID"
},
{
"path": "BluetoothLeGatt/.project",
"chars": 821,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>DeviceScanActivity</name>\n\t<comment></comment>\n\t<proj"
},
{
"path": "BluetoothLeGatt/AndroidManifest.xml",
"chars": 2553,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nCopyright (C) 2013 The Android Open Source Project\n\nLicensed under the Apach"
},
{
"path": "BluetoothLeGatt/project.properties",
"chars": 605,
"preview": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# T"
},
{
"path": "BluetoothLeGatt/res/layout/actionbar_indeterminate_progress.xml",
"chars": 942,
"preview": "<!--\n Copyright 2013 Google Inc.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use t"
},
{
"path": "BluetoothLeGatt/res/layout/activity_characteristic.xml",
"chars": 3170,
"preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/too"
},
{
"path": "BluetoothLeGatt/res/layout/gatt_services_characteristics.xml",
"chars": 2570,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright (C) 2013 The Android Open Source Project\n\n Licensed under"
},
{
"path": "BluetoothLeGatt/res/layout/listitem_device.xml",
"chars": 1266,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2013 The Android Open Source Project\n\n Licensed under the "
},
{
"path": "BluetoothLeGatt/res/menu/characteristic.xml",
"chars": 373,
"preview": "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/tools\"\n "
},
{
"path": "BluetoothLeGatt/res/menu/gatt_services.xml",
"chars": 1265,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2013 The Android Open Source Project\n\n Licensed under the "
},
{
"path": "BluetoothLeGatt/res/menu/main.xml",
"chars": 1247,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2013 The Android Open Source Project\n\n Licensed under the "
},
{
"path": "BluetoothLeGatt/res/values/dimens.xml",
"chars": 213,
"preview": "<resources>\n\n <!-- Default screen margins, per the Android Design guidelines. -->\n <dimen name=\"activity_horizonta"
},
{
"path": "BluetoothLeGatt/res/values/strings.xml",
"chars": 1855,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright (C) 2013 The Android Open Source Project\n\n Licensed under"
},
{
"path": "BluetoothLeGatt/res/values-w820dp/dimens.xml",
"chars": 373,
"preview": "<resources>\n\n <!--\n Example customization of dimensions originally defined in res/values/dimens.xml\n "
},
{
"path": "BluetoothLeGatt/src/com/example/bluetooth/le/BleApplication.java",
"chars": 1118,
"preview": "package com.example.bluetooth.le;\n\nimport android.app.Application;\nimport android.content.ComponentName;\nimport android."
},
{
"path": "BluetoothLeGatt/src/com/example/bluetooth/le/CharacteristicActivity.java",
"chars": 6523,
"preview": "package com.example.bluetooth.le;\n\nimport java.util.UUID;\n\nimport org.apache.commons.codec.DecoderException;\nimport org."
},
{
"path": "BluetoothLeGatt/src/com/example/bluetooth/le/DeviceControlActivity.java",
"chars": 12908,
"preview": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "BluetoothLeGatt/src/com/example/bluetooth/le/DeviceScanActivity.java",
"chars": 10818,
"preview": "/*\n * Copyright (C) 2013 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lice"
},
{
"path": "BluetoothLeGatt/src/com/example/bluetooth/le/Utils.java",
"chars": 9518,
"preview": "package com.example.bluetooth.le;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Utils {\n\tpublic static "
},
{
"path": "LICENSE",
"chars": 11323,
"preview": "Apache License\n Version 2.0, January 2004\n http://www.apache.org/licens"
},
{
"path": "README.md",
"chars": 2535,
"preview": "GizwitsBLE\n==========\n\nGizwitsBLE solves the compatibility and reliability issues that have troubled developers. First, "
}
]
// ... and 6 more files (download for full content)
About this extraction
This page contains the full source code of the xpg/GizwitsBLE GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 47 files (167.2 KB), approximately 42.6k tokens, and a symbol index with 231 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.