ble/BlessedConnect.java
2020-02-04 17:36:39 -05:00

277 lines
9.8 KiB
Java

package st.wow.git.ble;
import java.lang.String;
import java.util.List;
import java.util.UUID;
import android.app.Activity;
import android.app.Fragment;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.ScanResult;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.Manifest;
import android.util.Log;
import com.welie.blessed.BluetoothCentral;
import com.welie.blessed.BluetoothCentralCallback;
import com.welie.blessed.BluetoothPeripheral;
import com.welie.blessed.BluetoothPeripheralCallback;
public class BlessedConnect extends Fragment {
BluetoothCentral central;
boolean wantScan = false;
final int PERMISSION_REQUEST = 1;
final int REQUEST_ENABLE_BT = 2;
public BlessedConnect() {
Log.d("gio", "BlessedConnect()");
}
@Override public void onAttach(Context ctx) {
super.onAttach(ctx);
Log.d("gio", "BlessedConnect: onAttach()");
ctx.registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
if (ctx.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST);
}
central = new BluetoothCentral(ctx, centralCallback, null);
System.loadLibrary("gio");
installComplete(this);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("gio", "Received broadcast");
if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
updateState(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1));
}
}
};
public boolean enabled() {
Context ctx = getContext();
//The Blessed library does not expose this functionality, so
//we need to get our own BluetoothAdapter and check its status.
BluetoothAdapter adapter = ((BluetoothManager)ctx.getSystemService(ctx.BLUETOOTH_SERVICE)).getAdapter();
return (adapter != null && adapter.isEnabled());
}
@Override
public void onDestroy() {
Log.d("gio","onDestroy()");
stopScan();
getContext().unregisterReceiver(receiver);
super.onDestroy();
}
public void scan() {
if (enabled()) {
central.scanForPeripherals();
} else {
wantScan = true;
}
}
public void stopScan() {
central.stopScan();
}
private final BluetoothCentralCallback centralCallback = new BluetoothCentralCallback() {
@Override
public void onDiscoveredPeripheral(BluetoothPeripheral peripheral, ScanResult scanResult) {
Log.d("gio", "BlessedConnect: onDiscoveredPeripheral(): " + peripheral.getName());
onScan(peripheral.getName(), peripheral.getAddress(), scanResult.getRssi(), peripheral);
}
@Override
public void onConnectedPeripheral(BluetoothPeripheral peripheral) {
if (peripheral.getState() == peripheral.STATE_CONNECTED) {
Log.d("gio", "BlessedConnect: Connected to " + peripheral.getName());
Log.d("gio", "BlessedConnect: Address = " + peripheral.getAddress());
onConnect(peripheral, peripheral.getAddress());
} else {
onDisconnect(peripheral, peripheral.getAddress());
}
}
@Override
public void onConnectionFailed(BluetoothPeripheral peripheral, int status) {
Log.d("gio", "BlessedConnect: onConnectionFailed()");
onDisconnect(peripheral, peripheral.getAddress());
}
@Override
public void onDisconnectedPeripheral(BluetoothPeripheral peripheral, int status) {
Log.d("gio", "BlessedConnect: Disconnected");
onDisconnect(peripheral, peripheral.getAddress());
}
@Override
public void onScanFailed(int errorCode) {
Log.d("gio", "BlessedConnect: Scan failed");
}
};
private final BluetoothPeripheralCallback peripheralCallback = new BluetoothPeripheralCallback() {
public void onBondingFailed(BluetoothPeripheral peripheral) {
Log.d("gio", "BlessedConnect: onBondingFailed()");
}
public void onBondingStarted(BluetoothPeripheral peripheral) {
Log.d("gio", "BlessedConnect: onBondingStarted()");
}
public void onBondingSucceeded(BluetoothPeripheral peripheral) {
Log.d("gio", "BlessedConnect: onBondingSucceeded()");
}
public void onBondLost(BluetoothPeripheral peripheral) {
Log.d("gio", "BlessedConnect: onBondLost()");
}
public void onCharacteristicUpdate(BluetoothPeripheral peripheral, byte[] value, BluetoothGattCharacteristic characteristic, int status) {
Log.d("gio", "BlessedConnect: onCharacteristicUpdate()");
characteristicChanged(peripheral.getAddress(), characteristic.getUuid().toString(), characteristic, value, value.length);
}
public void onCharacteristicWrite(BluetoothPeripheral peripheral, byte[] value, android.bluetooth.BluetoothGattCharacteristic characteristic, int status) {
Log.d("gio", "onCharacteristicWrite(): " + characteristic.getUuid().toString());
}
public void onDescriptorRead(BluetoothPeripheral peripheral, byte[] value, android.bluetooth.BluetoothGattDescriptor descriptor, int status) {
Log.d("gio", "onDescriptorRead()");
}
public void onDescriptorWrite(BluetoothPeripheral peripheral, byte[] value, android.bluetooth.BluetoothGattDescriptor descriptor, int status) {
Log.d("gio", "onDescriptorWrite(): " + descriptor.getUuid().toString());
}
public void onMtuChanged(BluetoothPeripheral peripheral, int mtu, int status) {
Log.d("gio", "onMtuChanged()");
}
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
Log.d("gio", "onReadRemoteRssi");
}
public void onNotificationStateUpdate(BluetoothPeripheral peripheral, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
if(peripheral.isNotifying(characteristic)) {
Log.i("gio", String.format("BlessedConnect: Notify set to 'on' for %s", characteristic.getUuid()));
} else {
Log.i("gio", String.format("BlessedConnect: Notify set to 'off' for %s", characteristic.getUuid()));
}
} else {
Log.d("gio", "BlessedConnect: onNotificationStateUpdate(): failed");
}
}
public void onServicesDiscovered(BluetoothPeripheral peripheral) {
Log.d("gio", "BlessedConnect: onServicesDiscovered()");
}
};
public void connect(BluetoothPeripheral peripheral) {
if (peripheral == null) {
return;
}
Log.d("gio","BlessedConnect: connect");
central.connectPeripheral(peripheral, peripheralCallback);
}
public void disconnect(BluetoothPeripheral peripheral) {
if (peripheral == null) {
return;
}
Log.d("gio","BlessedConnect: disconnect");
peripheral.cancelConnection();
onDisconnect(peripheral, peripheral.getAddress());
}
public void discoverServices(BluetoothPeripheral peripheral) {
if (peripheral == null) {
return;
}
List<BluetoothGattService> services = peripheral.getServices();
for (BluetoothGattService serv : services) {
onDiscoverService(peripheral.getAddress(), serv.getUuid().toString(), serv);
}
}
public void discoverCharacteristics(BluetoothPeripheral peripheral, BluetoothGattService serv) {
if (peripheral == null || serv == null) {
return;
}
List<BluetoothGattCharacteristic> chrs = serv.getCharacteristics();
for (BluetoothGattCharacteristic chr : chrs) {
onDiscoverCharacteristic(peripheral.getAddress(), serv.getUuid().toString(), serv, chr.getUuid().toString(), chr);
}
}
public void readCharacteristic(BluetoothPeripheral peripheral, BluetoothGattCharacteristic chr) {
if (peripheral == null || chr == null) {
return;
}
peripheral.readCharacteristic(chr);
}
public boolean setCharacteristicNotification(BluetoothPeripheral peripheral, BluetoothGattCharacteristic chr) {
if (peripheral == null || chr == null) {
return false;
}
return peripheral.setNotify(chr, true);
}
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("gio", "BlessedConnect: onActivityResult()");
if (requestCode == REQUEST_ENABLE_BT) {
Log.d("gio", "BlessedConnect: onActivityResult() REQUEST_ENABLE_BT");
switch (resultCode) {
case Activity.RESULT_OK: {
Log.d("gio", "BlessedConnect: onActivityResult() -- OK");
if (wantScan) {
scan();
}
break;
}
case Activity.RESULT_CANCELED: {
Log.d("gio", "BlessedConnect: onActivityResult() -- Cancelled");
break;
}
}
}
}
@Override
public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) {
Log.d("gio", "BlessedConnect: onRequestPermissionsResult");
if (requestCode == PERMISSION_REQUEST) {
boolean granted = true;
for (int x : grantResults) {
if (x == PackageManager.PERMISSION_DENIED) {
granted = false;
break;
}
}
if (!granted) {
Log.d("gio", "BlessedConnect: permissions not granted");
return;
}
Log.d("gio", "BlessedConnect: permissions granted");
if (wantScan) {
scan();
}
}
}
static private native void installComplete(BlessedConnect p);
static private native void updateState(int s);
static private native void onScan(String name, String id, int rssi, BluetoothPeripheral peripheral);
static private native void onConnect(BluetoothPeripheral peripheral, String id);
static private native void onDisconnect(BluetoothPeripheral peripheral, String id);
static private native void onDiscoverService(String id, String uuid, BluetoothGattService serv);
static private native void onDiscoverCharacteristic(String id, String suuid, BluetoothGattService serv, String cuuid, BluetoothGattCharacteristic chr);
static private native void characteristicChanged(String id, String cuuid, BluetoothGattCharacteristic chr, byte[] value, int length);
}