Skip to content

Karewan/KnBle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

99 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KnBle

API License: MIT

A simple BLE Android client

Installation

allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}
android {
	compileOptions {
		sourceCompatibility JavaVersion.VERSION_21
		targetCompatibility JavaVersion.VERSION_21
	}
}

dependencies {
	implementation 'com.github.Karewan:KnBle:3.0.5'
}

Do not forget to add internet permissions in manifest

<!-- For all Android versions -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!--
	Android 6+: Needed for BLE scan
	Optionnal permission on Android 12+, use only if you need to derive location from scan results
	neverForLocation is optional, please also set the never location in the scanner settings default => true
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" android:usesPermissionFlags="neverForLocation"/>
<!-- Android 10+: For background BLE scan (Optional) -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" android:minSdkVersion="31"/>
<!-- Android 12+: BLE scan (neverForLocation is optional, please also set the never location in the scanner settings default => true) -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:minSdkVersion="31" android:usesPermissionFlags="neverForLocation"/>
<!-- Android 12+: BLE connect to already paired device -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

Then initialize, return false if device is not BLE compatible

boolean success = KnBle.gi().init(getApplicationContext());

At any time you can check if the initialization is correct, return false if the device is not BLE compatible

boolean isInit = KnBle.gi().isInit();

Scanning operations

Start scan

KnBle.gi().startScan(new BleScanCallback() {
	@Override
	public void onScanStarted() {

	}

	@Override
	public void onScanFailed(int error) {
		// BleScanCallback.BT_DISABLED
		// BleScanCallback.LOCATION_DISABLED
		// BleScanCallback.SCANNER_UNAVAILABLE
		// BleScanCallback.UNKNOWN_ERROR
		// BleScanCallback.SCAN_FEATURE_UNSUPPORTED
	}

	@Override
	public void onScanResult(@NonNull BleDevice bleDevice) {

	}

	@Override
	public void onDeviceUpdated(@NonNull BleDevice bleDevice) {

	}

	@Override
	public void onScanFinished(@NonNull List<BleDevice> scanResult) {

	}
});

Stop scan

KnBle.gi().stopScan();

Set scan settings (before start scan)

// Check ScanSettings class to see all settings
ScanSettings settings = new ScanSettings.Builder().build();

KnBle.gi().setScanSettings(settings);

Set scan filters (before start scan)

// Check ScanFilters class to see all filters
ScanFilters filters = new ScanFilters.Builder().build();

KnBle.gi().setScanFilter(filters);

Check if currently scanning

boolean isScanning = KnBle.gi().isScanning();

Get last scan error

int error = KnBle.gi().getLastError();

Get current scan settings

ScanSettings settings = KnBle.gi().getScanSettings();

Get current scan filters

ScanFilters filters = KnBle.gi().getScanFilters();

Get all scanned devices

@NonNull
List<BleDevice> devices = KnBle.gi().getScannedDevices();

Clear scanned devices

KnBle.gi().clearScannedDevices();

Stop and reset scan completely (boolean resetSettings, boolean resetFilters)

KnBle.gi().resetScan(true, true);

Device operations

Get device from MAC address

@Nullable
BleDevice device = KnBle.gi().getBleDeviceFromMac("FF:FF:FF:FF:FF:FF");

Get list of connected devices

@NonNull
List<BleDevice> devices = KnBle.gi().getConnectedDevices();

Check if device is connected

boolean connected = KnBle.gi().isConnected(device);

Get device connection state

int state = KnBle.gi().getDeviceConnState(device);

// BleGattCallback.DISCONNECTED
// BleGattCallback.CONNECTING
// BleGattCallback.CONNECTED

Connect to a device

KnBle.gi().connect(device, new BleGattCallback() {
	@Override
	public void onConnecting() {

	}

	@Override
	public void onConnectSuccess(@NonNull List<BluetoothGattService> services) {

	}

	@Override
	public void onDisconnected(boolean connectFailed) {

	}
});

Get a gatt service of a device

KnBle.gi().getService(device, "service uuid",  new BleGetService() {
	@Override
	public void onSuccess(@NonNull BluetoothGattService service) {

	}

	@Override
	public void onFailed() {

	}
});

// OR

KnBle.gi().getService(device, serviceUUID,  new BleGetService() {
	@Override
	public void onSuccess(@NonNull BluetoothGattService service) {

	}

	@Override
	public void onFailed() {

	}
});

Get a gatt characteristic of a device

KnBle.gi().getCharacteristic(device, "service uuid", "characteristic uuid",  new BleGetCharacteristic() {
	@Override
	public void onSuccess(@NonNull BluetoothGattCharacteristic characteristic) {

	}

	@Override
	public void onFailed() {

	}
});

// OR

KnBle.gi().getCharacteristic(device, serviceUUID, characteristicUUID,  new BleGetCharacteristic() {
	@Override
	public void onSuccess(@NonNull BluetoothGattCharacteristic characteristic) {

	}

	@Override
	public void onFailed() {

	}
});

Get a gatt descriptor of a device

KnBle.gi().getDescriptor(device, "service uuid", "characteristic uuid", "descriptor uuid", new BleGetDescriptor() {
	@Override
	public void onSuccess(@NonNull BluetoothGattDescriptor descriptor) {

	}

	@Override
	public void onFailed() {

	}
});

// OR

KnBle.gi().getDescriptor(device, serviceUUID, characteristicUUID, descriptorUUID, new BleGetDescriptor() {
	@Override
	public void onSuccess(@NonNull BluetoothGattDescriptor descriptor) {

	}

	@Override
	public void onFailed() {

	}
});

Read gatt characteristic data

KnBle.gi().read(device, "service uuid", "characteristic uuid", new BleReadCallback() {
	@Override
	public void onReadSuccess(@NonNull byte[] data) {

	}

	@Override
	public void onReadFailed() {

	}
});

// OR

KnBle.gi().read(device, serviceUUID, characteristicUUID, new BleReadCallback() {
	@Override
	public void onReadSuccess(@NonNull byte[] data) {

	}

	@Override
	public void onReadFailed() {

	}
});

// OR

KnBle.gi().read(device, service, characteristic, new BleReadCallback() {
	@Override
	public void onReadSuccess(@NonNull byte[] data) {

	}

	@Override
	public void onReadFailed() {

	}
});

Write data in gatt characteristic

KnBle.gi().write(device, "service uuid", "characteristic uuid", data, noResponse, new BleWriteCallback() {
	@Override
	public void onWriteFailed() {

	}

	@Override
	public void onWriteSuccess() {

	}
});

// OR

KnBle.gi().write(device, serviceUUID, characteristicUUID, data, noResponse, new BleWriteCallback() {
	@Override
	public void onWriteFailed() {

	}

	@Override
	public void onWriteSuccess() {

	}
});

// OR

KnBle.gi().write(device, service, characteristic, data, noResponse, new BleWriteCallback() {
	@Override
	public void onWriteFailed() {

	}

	@Override
	public void onWriteSuccess() {

	}
});

Splitted write data in gatt characteristic

KnBle.gi().splittedWrite(device, "service uuid", "characteristic uuid", data, splitSize, noResponse, intervalBetweenTwoPackage, new BleSplittedWriteCallback() {
	@Override
	public void onWriteFailed() {

	}

	@Override
	public void onWriteProgress(int current, int total) {

	}

	@Override
	public void onWriteSuccess() {

	}
});

// OR

KnBle.gi().splittedWrite(device, serviceUUID, characteristicUUID, data, splitSize, noResponse, intervalBetweenTwoPackage, new BleSplittedWriteCallback() {
	@Override
	public void onWriteFailed() {

	}

	@Override
	public void onWriteProgress(int current, int total) {

	}

	@Override
	public void onWriteSuccess() {

	}
});

// OR

KnBle.gi().splittedWrite(device, service, characteristic, data, splitSize, noResponse, intervalBetweenTwoPackage, new BleSplittedWriteCallback() {
	@Override
	public void onWriteFailed() {

	}

	@Override
	public void onWriteProgress(int current, int total) {

	}

	@Override
	public void onWriteSuccess() {

	}
});

Enable characteristic notification

KnBle.gi().enableNotify(device, "service uuid", "characteristic uuid", new BleNotifyCallback() {
	@Override
	public void onNotifyEnabled() {

	}

	@Override
	public void onNotifyDisabled() {

	}

	@Override
	public void onNotify(@NonNull byte[] data) {

	}
});

// OR

KnBle.gi().enableNotify(device, serviceUUID, characteristicUUID, new BleNotifyCallback() {
	@Override
	public void onNotifyEnabled() {

	}

	@Override
	public void onNotifyDisabled() {

	}

	@Override
	public void onNotify(@NonNull byte[] data) {

	}
});

// OR

KnBle.gi().enableNotify(device, service, characteristic, new BleNotifyCallback() {
	@Override
	public void onNotifyEnabled() {

	}

	@Override
	public void onNotifyDisabled() {

	}

	@Override
	public void onNotify(@NonNull byte[] data) {

	}
});

Disable characteristic notification

KnBle.gi().disableNotify(device, "service uuid", "characteristic uuid");

// OR

KnBle.gi().disableNotify(device, serviceUUID, characteristicUUID);

// OR

KnBle.gi().disableNotify(device, service, characteristic);

Read gatt descriptor data

KnBle.gi().readDesc(device, "service uuid", "characteristic uuid", "descriptor uuid", new BleReadCallback() {
	@Override
	public void onReadSuccess(@NonNull byte[] data) {

	}

	@Override
	public void onReadFailed() {

	}
});

// OR

KnBle.gi().readDesc(device, serviceUUID, characteristicUUID, descriptorUUID, new BleReadCallback() {
	@Override
	public void onReadSuccess(@NonNull byte[] data) {

	}

	@Override
	public void onReadFailed() {

	}
});

// OR

KnBle.gi().readDesc(device, service, characteristic, descriptor new BleReadCallback() {
	@Override
	public void onReadSuccess(@NonNull byte[] data) {

	}

	@Override
	public void onReadFailed() {

	}
});

Write data in gatt descriptor

KnBle.gi().writeDesc(device, "service uuid", "characteristic uuid", "descriptor uuid", data, new BleWriteCallback() {
	@Override
	public void onWriteFailed() {

	}

	@Override
	public void onWriteSuccess() {

	}
});

// OR

KnBle.gi().writeDesc(device, serviceUUID, characteristicUUID, descriptorUUID, data, new BleWriteCallback() {
	@Override
	public void onWriteFailed() {

	}

	@Override
	public void onWriteSuccess() {

	}
});

// OR

KnBle.gi().writeDesc(device, service, characteristic, descriptor, data, new BleWriteCallback() {
	@Override
	public void onWriteFailed() {

	}

	@Override
	public void onWriteSuccess() {

	}
});

Request connection priority (BluetoothGatt.CONNECTION_PRIORITY_xxx)

KnBle.gi().requestConnectionPriority(device, connectionPriority);

Get current MTU

int mtu = KnBle.gi().getMtu(device);

Request MTU change

KnBle.gi().requestMtu(device, mtu);

// OR

KnBle.gi().requestMtu(device, mtu, new BleMtuChangedCallback() {
	@Override
	public void onMtuChanged(int mtu) {

	}
});

Read PHY (Android 13+)

KnBle.gi().readPhy(device, new BlePhyValueCallback() {
	@Override
	public void onPhyValue(int txPhy, int rxPhy) {

	}
});

Set prefered PHY (Android 8+)

KnBle.gi().setPreferredPhy(device, txPhy, rxPhy, phyOptions);

// OR

KnBle.gi().setPreferredPhy(device, txPhy, rxPhy, phyOptions, new BlePhyValueCallback() {
	@Override
	public void onPhyValue(int txPhy, int rxPhy) {

	}
});

Change BleGattCallback of a device

KnBle.gi().setGattCallback(device, newCallback);

Disconnect a device

KnBle.gi().disconnect(device);

Disconnect all devices

KnBle.gi().disconnectAll();

Get the BluetoothGatt of a device

@Nullable
BluetoothGatt gatt = KnBle.gi().getBluetoothGatt(device);

Destroy (and disconnect) a device instance

KnBle.gi().destroyDevice(device);

Destroy (and disconnect) all devices instances

KnBle.gi().destroyAllDevices();

Others operations

Check if bluetooth adapter is enabled

boolean enabled = KnBle.gi().isBluetoothEnabled();

Enable/Disable bluetooth adapter (Deprecated in Android 13+)

// Enable
KnBle.gi().enableBluetooth(true);
// Disable
KnBle.gi().enableBluetooth(false);

Get the bluetooth adapter

@Nullable
BluetoothAdapter adapter = KnBle.gi().getBluetoothAdapter();

Get the bluetooth manager service

@Nullable
BluetoothManager btManager = KnBle.gi().getBluetoothManager();

Get KnBle context

@Nullable
Context ctx = KnBle.gi().getContext();

Toggle DEBUG

KnBle.DEBUG = false;

License

The MIT License (MIT)

Copyright (c) 2019-2025 Florent VIALATTE

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Contributors 2

  •  
  •  

Languages