我又来了。
所以,长话短说:在我的应用程序中,我试图在 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/
我主要使用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
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在处理旧代码的一部分。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_
我正在尝试使用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
我有一个非常简单的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":
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
我正在尝试使用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_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD