A simple BLE Android client
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}
dependencies {
implementation 'com.github.Karewan:KnBle:2.4.7'
}
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 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- Android 10+: For background BLE scan (Optional) -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<!-- Android 12+: BLE scan -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- Android 12+: BLE connect to already paired device -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
Then initialize
boolean success = KnBle.gi().init(getApplicationContext());
Verify is init correctly, return false if device is not BLE compatible
boolean isInit = KnBle.gi().isInit();
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 HashMap<String, BleDevice> scanResult) {
}
});
KnBle.gi().stopScan();
// Check ScanSettings class to see all settings
ScanSettings settings = new ScanSettings.Builder().build();
KnBle.gi().setScanSettings(settings);
// Check ScanFilters class to see all filters
ScanFilters filters = new ScanFilters.Builder().build();
KnBle.gi().setScanFilter(filters);
boolean isScanning = KnBle.gi().isScanning();
int error = KnBle.gi().getLastError();
ScanSettings settings = KnBle.gi().getScanSettings();
ScanFilters filters = KnBle.gi().getScanFilters();
HashMap<String, BleDevice> devices = KnBle.gi().getScannedDevices();
KnBle.gi().clearScannedDevices();
KnBle.gi().resetScan(true, true);
BleDevice device = KnBle.gi().getBleDeviceFromMac("FF:FF:FF:FF:FF:FF");
List<BleDevice> devices = KnBle.gi().getConnectedDevices();
boolean connected = KnBle.gi().isConnected(device);
KnBle.gi().connect(device, new BleGattCallback() {
@Override
public void onConnecting() {
}
@Override
public void onConnectFailed() {
}
@Override
public void onConnectSuccess(List<BluetoothGattService> services) {
}
@Override
public void onDisconnected() {
}
});
KnBle.gi().hasService(device, "service uuid", new BleCheckCallback() {
@Override
public void onResponse(boolean res) {
}
});
KnBle.gi().hasCharacteristic(device, "service uuid", "characteristic uuid", new BleCheckCallback() {
@Override
public void onResponse(boolean res) {
}
});
KnBle.gi().write(device, "service uuid", "characteristic uuid", data, new BleWriteCallback() {
@Override
public void onWriteFailed() {
}
@Override
public void onWriteProgress(int current, int total) {
}
@Override
public void onWriteSuccess() {
}
});
// OR
// true=split data
// 20=split into packet of
// true=if true send when android set last packet sent as success else send immediately
// 25=interval between two packet
KnBle.gi().write(device, "service uuid", "characteristic uuid", data, true, 20, true, 25, new BleWriteCallback() {
@Override
public void onWriteFailed() {
}
@Override
public void onWriteProgress(int current, int total) {
}
@Override
public void onWriteSuccess() {
}
});
KnBle.gi().read(device, "service uuid", "characteristic uuid", new BleReadCallback() {
@Override
public void onReadSuccess(byte[] data) {
}
@Override
public void onReadFailed() {
}
});
KnBle.gi().enableNotify(device, "service uuid", "characteristic uuid", new BleNotifyCallback() {
@Override
public void onNotifyEnabled() {
}
@Override
public void onNotifyDisabled() {
}
@Override
public void onNotify(byte[] data) {
}
});
KnBle.gi().disableNotify(device);
KnBle.gi().requestConnectionPriority(device, connectionPriority);
KnBle.gi().requestMtu(device, mtu);
int mtu = KnBle.gi().getMtu(device);
KnBle.gi().setPreferredPhy(device, txPhy, rxPhy, phyOptions);
KnBle.gi().setGattCallback(device, newCallback);
KnBle.gi().disconnect(device);
KnBle.gi().disconnectAll();
int state = KnBle.gi().getDeviceConnState(device);
// BleGattCallback.DISCONNECTED
// BleGattCallback.CONNECTING
// BleGattCallback.CONNECTED
@Nullable
BluetoothGatt gatt = KnBle.gi().getBluetoothGatt(device);
int status = KnBle.gi().getLastGattStatusOfDevice(device);
KnBle.gi().destroyAllDevices();
boolean enabled = KnBle.gi().isBluetoothEnabled();
// Enable
KnBle.gi().enableBluetooth(true);
// Disable
KnBle.gi().enableBluetooth(false);
BluetoothAdapter adapter = KnBle.gi().getBluetoothAdapter();
BluetoothManager btManager = KnBle.gi().getBluetoothManager();
Context ctx = KnBle.gi().getContext();
KnBle.DEBUG = false;
The MIT License (MIT)
Copyright (c) 2019-2023 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.