首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在android中获取BLE通知?

如何在android中获取BLE通知?
EN

Stack Overflow用户
提问于 2014-11-05 21:39:32
回答 1查看 1.5K关注 0票数 1

我在试着得到定制设备的通知。我知道该设备正在工作,因为在iOS中,使用Lightblue应用程序时,我确实会收到通知。我试过使用nexus 5和三星s4 (都是kitkats)。似乎什么都起不到作用。我的"onCharacteristicChanged“没有被呼叫。

MainActivity.java

代码语言:javascript
复制
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 = "0123456789ABCDEF".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

代码语言:javascript
复制
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有:

代码语言:javascript
复制
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

日志如下所示:

代码语言:javascript
复制
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

任何帮助都将不胜感激!

EN

回答 1

Stack Overflow用户

发布于 2014-11-13 16:54:21

我观察到一些通知或者没有处理某些电话/外围/环境组合,或者在同一连接会话中工作之后停止工作,没有明显的原因。所有调用都会返回成功,但通知不会通过。不管你是否解决了眼前的问题,你都应该考虑为你的特征值做一个阅读轮询,作为一个后备解决方案。

您的onServicesDiscovered()方法中的各种调用也应该通过对您正在调用的各个gatt方法的返回值的条件检查来关闭。

总之,有些事你可以试试:

  • 尝试通过您的手机设置重置蓝牙堆栈,甚至重新启动整个手机。
  • 测试其他设备。iOS有一些应用程序可以让您的iPhone充当外围设备。尝试连接到这样一个"sim设备“,看看通知在这种情况下是否有效。
  • 试试不同的安卓手机。我观察到,Nexus 4在通知方面的问题最多,如果是这样的话。

最后,我将像技术支持一样询问计算机是否已插入:确保外围设备上的特征值确实在变化。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26767634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档