맞춤 장치에 대한 알림을 받고 싶습니다. Lightblue 앱을 사용하는 iOS에서 알림을받을 수 있기 때문에 기기가 작동하고 있음을 안다. 나는 넥서스 5와 samsung s4 (둘 다 kitkats)로 시도했다. 아무것도 작동하는 것 같습니다. 내 "onCharacteristicChanged"가 호출되지 않습니다.안드로이드에서 BLE 알림을받는 방법?
MainActivity.java
package com.foo.ble;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
public class MainActivity extends Activity implements BluetoothAdapter.LeScanCallback {
private BluetoothAdapter adapter;
final private static char[] hexArray = "ABCDEF".toCharArray();
private Callback callback;
/**
* Converts 0xfe to "FE"
* @return hex representation of the adScanned
*/
public static String getPayload(final byte[] adScanned) {
if (adScanned == null) return "N/A";
final char[] hexChars = new char[adScanned.length * 2];
for (int j = 0; j < adScanned.length; j++) {
final int v = adScanned[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
adapter = manager.getAdapter();
callback = new Callback();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
adapter.stopLeScan(MainActivity.this);
}
}, 3*10000);
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.startLeScan(MainActivity.this);
}
});
}
@Override
public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
if (device.getAddress().equals("CE:AD:09:F2:BB:DC")) {
Log.d("foo", "onLeScan payload:" + getPayload(scanRecord));
adapter.stopLeScan(this);
runOnUiThread(new Runnable() {
@Override
public void run() {
device.connectGatt(MainActivity.this, true, callback);
}
});
}
}
@Override
protected void onDestroy() {
callback.close();
}
}
Callback.java
package com.foo.ble;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothProfile;
import android.util.Log;
import java.util.UUID;
public class Callback extends BluetoothGattCallback {
final static UUID SERVICE = UUID.fromString("something1");
final static UUID ADV_CHAR = UUID.fromString("something2");
final static UUID ADV_DESCRIPTOR = UUID.fromString("something3");
BluetoothGatt gatt;
public void close() {
if (gatt == null) return;
Log.d("foo", "close with gatt");
gatt.disconnect();
gatt.close();
gatt = null;
}
@Override
public void onConnectionStateChange(final BluetoothGatt gatt, final int status,
final int newState) {
Log.d("foo", "onConnectionStateChange");
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.d("foo", "status connected");
this.gatt = gatt;
gatt.discoverServices();
}
}
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, final int status) {
Log.d("foo", "onServicesDiscovered");
if (status == BluetoothGatt.GATT_SUCCESS) {
final BluetoothGattCharacteristic characteristic =
gatt.getService(SERVICE).getCharacteristic(ADV_CHAR);
final BluetoothGattDescriptor descriptor =
characteristic.getDescriptor(ADV_DESCRIPTOR);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.setCharacteristicNotification(characteristic, true);
gatt.writeDescriptor(descriptor);
}
}
@Override
public void onCharacteristicRead(final BluetoothGatt gatt,
final BluetoothGattCharacteristic characteristic,
final int status) {
Log.d("foo", "onCharacteristicRead status:" + status + " payload: " +
MainActivity.getPayload(characteristic.getValue()));
}
@Override
public void onCharacteristicWrite(final BluetoothGatt gatt,
final BluetoothGattCharacteristic characteristic,
final int status) {
Log.d("foo", "onCharacteristicWrite");
}
@Override
public void onCharacteristicChanged(final BluetoothGatt gatt,
final BluetoothGattCharacteristic characteristic) {
Log.d("foo", "onCharacteristicChanged payload:" +
MainActivity.getPayload(characteristic.getValue()));
}
@Override
public void onDescriptorWrite(final BluetoothGatt gatt,
final BluetoothGattDescriptor descriptor,
final int status) {
Log.d("foo", "onDescriptorWrite status: " + status);
final BluetoothGattCharacteristic characteristic =
gatt.getService(SERVICE).getCharacteristic(ADV_CHAR);
if (characteristic.getValue() != null) {
Log.d("foo", "value: " + MainActivity.getPayload(characteristic.getValue()));
} else {
gatt.readCharacteristic(characteristic);
}
}
}
내 AndroidManifest.xml에가 있습니다
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
을 로그는 다음과 같습니다
11-05 12:17:13.314 3683-3683/com.foo.ble D/BluetoothAdapter﹕ startLeScan(): null
11-05 12:17:13.364 3683-3695/com.foo.ble D/BluetoothAdapter﹕ onClientRegistered() - status=0 clientIf=5
11-05 12:17:13.394 3683-3683/com.foo.ble I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:320>: EGL 1.4 QUALCOMM Build: I0404c4692afb8623f95c43aeb6d5e13ed4b30ddbDate: 11/06/13
11-05 12:17:13.414 3683-3683/com.foo.ble D/OpenGLRenderer﹕ Enabling debug mode 0
11-05 12:17:13.454 3683-3683/com.foo.ble D/dalvikvm﹕ GC_FOR_ALLOC freed 238K, 2% free 16971K/17240K, paused 14ms, total 14ms
11-05 12:17:15.174 3683-3694/com.foo.ble D/foo﹕ onLeScan payload:02010517FF0000000000000005000000000000000000395401001207086C6976656C7911072E9AB04DB9790F857A4CF0634C7AB94A000000000000000000
11-05 12:17:15.174 3683-3694/com.foo.ble D/BluetoothAdapter﹕ stopLeScan()
11-05 12:17:15.184 3683-3683/com.foo.ble D/BluetoothGatt﹕ connect() - device: CE:AD:09:F2:BB:DC, auto: true
11-05 12:17:15.184 3683-3683/com.foo.ble D/BluetoothGatt﹕ registerApp()
11-05 12:17:15.184 3683-3683/com.foo.ble D/BluetoothGatt﹕ registerApp() - UUID=605cbd6f-6080-4fd8-97ff-1f97b406258e
11-05 12:17:15.194 3683-3695/com.foo.ble D/BluetoothGatt﹕ onClientRegistered() - status=0 clientIf=5
11-05 12:17:43.344 3683-3683/com.foo.ble D/BluetoothAdapter﹕ stopLeScan()
11-05 12:23:59.194 3683-3694/com.foo.ble D/BluetoothGatt﹕ onClientConnectionState() - status=0 clientIf=5 device=CE:AD:09:F2:BB:DC
11-05 12:23:59.194 3683-3694/com.foo.ble D/foo﹕ onConnectionStateChange
11-05 12:23:59.204 3683-3694/com.foo.ble D/foo﹕ status connected
11-05 12:23:59.204 3683-3694/com.foo.ble D/BluetoothGatt﹕ discoverServices() - device: CE:AD:09:F2:BB:DC
11-05 12:24:00.754 3683-3695/com.foo.ble D/BluetoothGatt﹕ onGetService() - Device=CE:AD:09:F2:BB:DC UUID=randomService1
11-05 12:24:00.764 3683-3694/com.foo.ble D/BluetoothGatt﹕ onGetService() - Device=CE:AD:09:F2:BB:DC UUID=randomService2
11-05 12:24:00.784 3683-3695/com.foo.ble D/BluetoothGatt﹕ onGetService() - Device=CE:AD:09:F2:BB:DC UUID=something1
11-05 12:24:00.794 3683-3694/com.foo.ble D/BluetoothGatt﹕ onGetCharacteristic() - Device=CE:AD:09:F2:BB:DC UUID=randomUUID1
11-05 12:24:00.804 3683-3695/com.foo.ble D/BluetoothGatt﹕ onGetCharacteristic() - Device=CE:AD:09:F2:BB:DC UUID=randomUUID2
11-05 12:24:00.804 3683-3694/com.foo.ble D/BluetoothGatt﹕ onGetCharacteristic() - Device=CE:AD:09:F2:BB:DC UUID=randomUUID3
11-05 12:24:00.814 3683-3695/com.foo.ble D/BluetoothGatt﹕ onGetCharacteristic() - Device=CE:AD:09:F2:BB:DC UUID=randomUUID4
11-05 12:24:00.814 3683-3694/com.foo.ble D/BluetoothGatt﹕ onGetCharacteristic() - Device=CE:AD:09:F2:BB:DC UUID=randomUUID5
11-05 12:24:00.814 3683-3695/com.foo.ble D/BluetoothGatt﹕ onGetCharacteristic() - Device=CE:AD:09:F2:BB:DC UUID=randomUUID6
11-05 12:24:00.814 3683-3694/com.foo.ble D/BluetoothGatt﹕ onGetCharacteristic() - Device=CE:AD:09:F2:BB:DC UUID=randomUUID7
11-05 12:24:00.814 3683-3695/com.foo.ble D/BluetoothGatt﹕ onGetCharacteristic() - Device=CE:AD:09:F2:BB:DC UUID=something2
11-05 12:24:00.824 3683-3694/com.foo.ble D/BluetoothGatt﹕ onGetDescriptor() - Device=CE:AD:09:F2:BB:DC UUID=something3
11-05 12:24:00.824 3683-3695/com.foo.ble D/BluetoothGatt﹕ onSearchComplete() = Device=CE:AD:09:F2:BB:DC Status=0
11-05 12:24:00.824 3683-3695/com.foo.ble D/foo﹕ onServicesDiscovered
11-05 12:24:00.824 3683-3695/com.foo.ble D/BluetoothGatt﹕ setCharacteristicNotification() - uuid: something2 enable: true
11-05 12:24:00.834 3683-3695/com.foo.ble D/BluetoothGatt﹕ writeDescriptor() - uuid: something3
11-05 12:24:00.894 3683-3694/com.foo.ble D/BluetoothGatt﹕ onDescriptorWrite() - Device=CE:AD:09:F2:BB:DC UUID=something3
11-05 12:24:00.894 3683-3694/com.foo.ble D/foo﹕ onDescriptorWrite status: 0
11-05 12:24:00.894 3683-3694/com.foo.ble D/BluetoothGatt﹕ readCharacteristic() - uuid: something2
11-05 12:24:00.994 3683-3695/com.foo.ble D/BluetoothGatt﹕ onCharacteristicRead() - Device=CE:AD:09:F2:BB:DC UUID=something2 Status=0
11-05 12:24:00.994 3683-3695/com.foo.ble D/foo﹕ onCharacteristicRead status:0 payload: 0000000000050000000000000000005154010012
도움이 될 것입니다!
정확히 작동하지 않는 항목은 무엇입니까? 로그에 성공 상태가 표시됩니다. –
알림이 표시되지 않습니다. "onCharacteristicChanged"가 없습니다. – eipipuz
OnCharacteristicChanged 메서드의 다른 위치에 중단 점을 설정하면 디버깅하는 동안 실제로 원격 장치에서 알림을 받고 있습니다. –