jjzjj

java - 未从 BLE 设备接收数据

coder 2023-12-26 原文

我又来了。
所以,长话短说:在我的应用程序中,我试图在 Android 示例 (that) 的帮助下从我的 BLE 设备(tickr 心率监视器:that)接收数据。
但是...我没有从我的设备接收数据!我能够获得特征和描述符,但是......仅此而已。我只是……没捕获重点。 这是我的代码:

private BluetoothLeService mBluetoothLeService;
private ArrayList<BluetoothGattCharacteristic> mGattCharacteristics =
        new ArrayList<BluetoothGattCharacteristic>();
private BluetoothGattCharacteristic mNotifyCharacteristic;
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
private static final int CONNECTED_ID = 1;
private String mDeviceName;
private String mDeviceAddress;
private boolean mConnected = false;
BluetoothGatt btGatt;
BluetoothGattCharacteristic btGattCharacteristic;
 private List<BluetoothGattCharacteristic> gattCharacteristics = new ArrayList<BluetoothGattCharacteristic>();
    @InjectView(R.id.hrate) public TextView hRate;
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
            Log.i(TAG, "gatt connected");
            mConnected = true;
        } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
            mConnected = false;
            Log.i(TAG, "gatt disconnected");
            hRate.setText("0");
        } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            Log.i(TAG, "service discovered");
            returnServices(mBluetoothLeService.getSupportedGattServices());
        } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
            Log.i(TAG, "data available");
            displayHR(intent.getExtras().getString(BluetoothLeService.EXTRA_DATA));
        }
    }
};

private final ServiceConnection mServiceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder service) {
        mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
        if (!mBluetoothLeService.initialize()) {
            Log.e(TAG, "Unable to initialize Bluetooth");
            onDestroy();
        }
        // Automatically connects to the device upon successful start-up initialization.
        mBluetoothLeService.connect(mDeviceAddress);
        Log.i("", "i'm connected");
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        mBluetoothLeService = null;
    }
};

@OnClick({R.id.button_start, R.id.button_pause, R.id.button_stop})
public void OnSession(View view) {

    switch (view.getId()) {

        case R.id.button_start:
            if(first) {
                first=false;
                onBLE();
            }
            else {
                startRun();
                if (mBluetoothLeService != null) {
                    getActivity().registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
                    final boolean result = mBluetoothLeService.connect(mDeviceAddress);
                    Log.d(TAG, "Connect request result=" + result);
                }
            }
            break;
}
public Dialog onBLE(){
    android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(getActivity());
    builder.setMessage("Vuoi utilizzare un device?")
            .setCancelable(false)
            .setPositiveButton("Sì", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    Intent intent = new Intent(getActivity(), BluetoothActivity.class);
                    startActivityForResult(new Intent(intent), CONNECTED_ID);
                    dialog.cancel();
                }
            })
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    hRate.setText("N.D.");
                    startRun();
                    dialog.cancel();
                }
            });
    android.app.AlertDialog ble = builder.create();
    ble.show();
    return null;
}

public void startRun(){
    timeAtStart = SystemClock.uptimeMillis();
    customHandler.postDelayed(updated, 0);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CONNECTED_ID){
        if (resultCode == Activity.RESULT_OK) {
            mDeviceName = data.getExtras().getString(EXTRAS_DEVICE_NAME);
            mDeviceAddress = data.getExtras().getString(EXTRAS_DEVICE_ADDRESS);
            Log.i("", mDeviceAddress+" "+mDeviceName);
            connect();
            startRun();
        }

    }
}
public void connect(){
    Intent gattServiceIntent = new Intent(getActivity(), BluetoothLeService.class);
    getActivity().bindService(gattServiceIntent, mServiceConnection, getActivity().BIND_AUTO_CREATE);
}
public void displayHR(String arg){
    if(arg != null){
        hRate.setText(arg);
    }
}
private void returnServices(List<BluetoothGattService> gattServices) {
    if (gattServices == null) return;

    for (BluetoothGattService service : gattServices) {
        gattCharacteristics=service.getCharacteristics();
        for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
            if (characteristic.getUuid().toString().compareTo(SampleGattAttributes.HEART_RATE_MEASUREMENT) == 0)
                btGattCharacteristic = characteristic;

        }
    }
    if ((btGattCharacteristic.getProperties() | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
        if (mNotifyCharacteristic != null) {
            mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
            mNotifyCharacteristic = null;
        }
        mBluetoothLeService.readCharacteristic(btGattCharacteristic);
    }

    if ((btGattCharacteristic.getProperties() | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
        mNotifyCharacteristic = btGattCharacteristic;
        mBluetoothLeService.setCharacteristicNotification(btGattCharacteristic, true);

    }
}

private static IntentFilter makeGattUpdateIntentFilter() {
    final IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
    intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
    return intentFilter;
}

这是我的日志:

09-25 11:38:05.975  25709-25709/apheniti.prova D/BluetoothAdapter﹕ startLeScan(): null
09-25 11:38:06.092  25709-25709/apheniti.prova D/dalvikvm﹕ GC_FOR_ALLOC freed 235K, 3% free 9444K/9716K, paused 18ms, total 18ms
09-25 11:38:06.147  25709-25722/apheniti.prova D/BluetoothAdapter﹕ onClientRegistered() - status=0 clientIf=4
09-25 11:38:07.194  25709-25722/apheniti.prova D/BluetoothAdapter﹕ onScanResult() - Device=DA:E1:DD:95:BB:D4 RSSI=-61
09-25 11:38:07.842  25709-25709/apheniti.prova D/BluetoothAdapter﹕ stopLeScan()
09-25 11:38:07.921  25709-25709/apheniti.prova I/﹕ DA:E1:DD:95:BB:D4 TICKR
09-25 11:38:08.006  25709-25709/apheniti.prova D/BluetoothGatt﹕ connect() - device: DA:E1:DD:95:BB:D4, auto: false
09-25 11:38:08.006  25709-25709/apheniti.prova D/BluetoothGatt﹕ registerApp()
09-25 11:38:08.006  25709-25709/apheniti.prova D/BluetoothGatt﹕ registerApp() - UUID=e8dfe101-58d1-4c04-bc3b-f1983e19b468
09-25 11:38:08.014  25709-25723/apheniti.prova D/BluetoothGatt﹕ onClientRegistered() - status=0 clientIf=4
09-25 11:38:08.014  25709-25709/apheniti.prova D/BluetoothLeService﹕ Trying to create a new connection.
09-25 11:38:08.014  25709-25709/apheniti.prova I/﹕ i'm connected
09-25 11:38:08.483  25709-25723/apheniti.prova D/BluetoothGatt﹕ onClientConnectionState() - status=0 clientIf=4 device=DA:E1:DD:95:BB:D4
09-25 11:38:08.491  25709-25723/apheniti.prova I/BluetoothLeService﹕ Connected to GATT server.
09-25 11:38:08.491  25709-25723/apheniti.prova D/BluetoothGatt﹕ discoverServices() - device: DA:E1:DD:95:BB:D4
09-25 11:38:08.491  25709-25723/apheniti.prova I/BluetoothLeService﹕ Attempting to start service discovery:true
09-25 11:38:08.491  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=00001800-0000-1000-8000-00805f9b34fb
09-25 11:38:08.499  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=00001801-0000-1000-8000-00805f9b34fb
09-25 11:38:08.499  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=0000180d-0000-1000-8000-00805f9b34fb
09-25 11:38:08.499  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=0000180f-0000-1000-8000-00805f9b34fb
09-25 11:38:08.506  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=0000180a-0000-1000-8000-00805f9b34fb
09-25 11:38:08.506  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=a026ee01-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.506  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetService() - Device=DA:E1:DD:95:BB:D4 UUID=a026ee03-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.506  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a00-0000-1000-8000-00805f9b34fb
09-25 11:38:08.514  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a01-0000-1000-8000-00805f9b34fb
09-25 11:38:08.514  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a04-0000-1000-8000-00805f9b34fb
09-25 11:38:08.530  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a05-0000-1000-8000-00805f9b34fb
09-25 11:38:08.530  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a37-0000-1000-8000-00805f9b34fb
09-25 11:38:08.538  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a38-0000-1000-8000-00805f9b34fb
09-25 11:38:08.546  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a19-0000-1000-8000-00805f9b34fb
09-25 11:38:08.546  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a29-0000-1000-8000-00805f9b34fb
09-25 11:38:08.546  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a27-0000-1000-8000-00805f9b34fb
09-25 11:38:08.553  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=00002a26-0000-1000-8000-00805f9b34fb
09-25 11:38:08.561  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=a026e002-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.561  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=a026e004-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.561  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetCharacteristic() - Device=DA:E1:DD:95:BB:D4 UUID=a026e00a-0a7d-4ab3-97fa-f1500f9feb8b
09-25 11:38:08.569  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.569  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.577  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.585  25709-25722/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.585  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.600  25709-25723/apheniti.prova D/BluetoothGatt﹕ onGetDescriptor() - Device=DA:E1:DD:95:BB:D4 UUID=00002902-0000-1000-8000-00805f9b34fb
09-25 11:38:08.600  25709-25722/apheniti.prova D/BluetoothGatt﹕ onSearchComplete() = Device=DA:E1:DD:95:BB:D4 Status=0
09-25 11:38:09.624  25709-25709/apheniti.prova D/dalvikvm﹕ GC_FOR_ALLOC freed 441K, 5% free 9514K/9992K, paused 26ms, total 27ms
09-25 11:38:11.944  25709-25709/apheniti.prova D/dalvikvm﹕ GC_FOR_ALLOC freed 485K, 6% free 9542K/10064K, paused 18ms, total 18ms
09-25 11:38:14.772  25709-25709/apheniti.prova D/dalvikvm﹕ GC_FOR_ALLOC freed 490K, 6% free 9566K/10092K, paused 18ms, total 19ms
09-25 11:38:15.991  25709-25709/apheniti.prova D/BluetoothAdapter﹕ stopLeScan()

最佳答案

您有一个 mBluetoothLeService.readCharacteristic(btGattCharacteristic) 调用但没有 onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status) 回调来接收值。它是 BluetoothGattCallback 的一部分.

我对该过程的理解是,首先您以某种方式找到 BluetoothDevice - 可能是通过 BLE 扫描。你识别它,例如通过其名称(使用 device.getName())或广告数据并使用 device.connectGatt(context, false/true, gattCallback) 连接到它。

然后在回调中,您会在 onConnectionStateChange(BluetoothGatt gatt, int status, int newState) 中收到连接状态。如果状态为 BluetoothProfile.STATE_CONNECTED,您可以使用 gatt.discoverServices() 发现服务。这将触发 onServicesDiscovered(BluetoothGatt gatt, int status),您将在其中通过 gatt.getServices() 获取可用服务并通过其 UUID 识别正确的服务并获取其通过 service.getCharacteristics() 识别特征,并再次通过其 UUID 识别正确的特征。

然后您将使用 gatt.readCharacteristic( service.getCharacteristic(CHARACTERISTIC_UUID)) 读取特征。然后,这会触发 onCharacteristicRead(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic, int status) 回调。在这里,您将使用 characteristic.getUuid() 检查您收到的特征(因为事物是异步的),并使用 characteristic.getStringValue(0) 或 Float 值读取其字符串值使用 getFloatValue(0) 等,具体取决于数据类型。

由于异步操作链,它可能会造成混淆。然而,在 here 中为服务器和客户端提供了很好的示例代码。更具体地说,客户端代码是 in this file .它们与 this excellent video about BLE on Android 有关由 NewCircle 提供,它也对代码做了一些解释。

您提到的 Android 示例可能有点令人困惑,因为它还涉及 Activity/Service 交互,而不仅仅是关于蓝牙 LE。最好看看 NewCircle 视频和示例项目……

关于java - 未从 BLE 设备接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32779643/

有关java - 未从 BLE 设备接收数据的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  3. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  4. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  5. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  6. ruby-on-rails - 如何使用 Rack 接收 JSON 对象 - 2

    我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":

  7. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  8. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  9. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  10. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

随机推荐