package st.wow.git.ble; import java.lang.String; import java.lang.Runnable; import java.util.List; import java.util.UUID; import android.app.Activity; import android.app.Fragment; import android.app.FragmentTransaction; 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.os.Handler; import android.util.Log; import android.view.View; 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()"); } public void register(View view) { Log.d("gio", "BlessedConnect: register()"); Context ctx = view.getContext(); Handler handler = new Handler(ctx.getMainLooper()); BlessedConnect inst = this; handler.post(new Runnable() { public void run() { Activity act = (Activity)ctx; FragmentTransaction ft = act.getFragmentManager().beginTransaction(); ft.add(inst, "BlessedConnect"); ft.commitNow(); } }); } @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 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 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); }