小编Veg*_*und的帖子

在Android上为蓝牙低功耗创建后台服务

背景:

理想情况下,我希望我的Android设备能够一直扫描蓝牙低功耗设备,以便在出现具有特定属性的新设备时启动应用程序.

因此,BLE中的广播分组将例如枚举由广播设备提供的一组服务.然后,应用程序可以注册某些服务的兴趣,并在具有此服务的设备进入范围时自动启动.

根据我的理解,这不是Android BLE API的工作原理吗?那我怎么能得到类似的东西呢?

最简单的例子:

我有一个BLE传感器可以记录环境温度.每当我的Android手机足够接近时,我想连接并下载所有数据,并将其发送到某些云存储解决方案.这个应用程序不需要任何GUI(至少在配置完成后不需要).但是如何在没有耗尽电池的情况下在后台运行,但是一旦它在范围内,我仍然可以很快地连接设备?

问题:

我是否需要设置计时器并偶尔唤醒应用程序,然后手动开始扫描?我应该选择什么样的间隔.我可以在不对电池产生不利影响的情况下让扫描仪运行多长时间?

可能的方法:

这是我到目前为止所提出的.

  • 用于设置要扫描的间隔和设备的配置活动
  • 配置活动将设置类似于Scheduler示例的WakefulBroadcastReceiver
  • 当接收器获得onReceive事件时,我启动了一个BLE扫描服务(我已经写过)作为一个唤醒服务.
  • 扫描服务开始扫描(使用已注册的回调).
  • 该服务可能会获得可以采取行动的报告
  • 超时后,服务将停止扫描仪并结束唤醒服务.

这有效,但我不确定这是最好的方法.我也不知道我可以有多小间隔,仍然可以避免破坏电池寿命.我想要的是每两分钟开始扫描一次,扫描10-20秒.但我担心唤醒设备的频率会相当高吗?

android bluetooth-lowenergy

47
推荐指数
1
解决办法
3万
查看次数

Android上的蓝牙低功耗专用与公共地址

蓝牙低功耗设备由其地址唯一标识(在Android API中,他们将其称为MAC地址,并将其表示为冒号分隔的十六进制值,例如11:aa:22:bb:33:cc).

但要唯一识别BLE地址,您需要知道它是公共地址还是私人地址.本质上,识别地址需要49位,而不是48位.

随机地址可以是静态随机地址,不可解析私有地址或可解析私有地址,这些类型在两个最高有效字节(分别为11,00和10)中由位模式分隔.

但是我没有看到只要通过查看地址中的48位就可以将公共地址和随机地址分开的任何地方.

那么这在Android API中如何运作?当他们不知道您指定的地址是公开的还是随机的时,他们如何知道要连接的设备?

有问题的API例如是getRemoteDevice函数.它说:

Valid Bluetooth hardware addresses must be upper case, in a format such as
"00:11:22:33:AA:BB". The helper checkBluetoothAddress(String) is available
to validate a Bluetooth address.

A BluetoothDevice will always be returned for a valid hardware address,
even if this adapter has never seen that device.
Run Code Online (Sandbox Code Playgroud)

所以你给函数48位数据,没有办法告诉它地址是公共的还是私有的.这意味着设备未被唯一标识.

android bluetooth-lowenergy android-bluetooth

24
推荐指数
1
解决办法
2万
查看次数

SQL服务器中的XQuery执行SUM超过零值

我正在尝试提取存储在一些格式不合理的xml列中的货币总和(没有为XML列定义的架构,我猜这是问题的一部分).每当遇到一个0为其值的节点时,我都会收到转换错误.

例:

select xml.value('sum(/List/value)', 'numeric') sum
from (select cast('<List><value>1</value><value>2</value></List>' as xml) xml) a
Run Code Online (Sandbox Code Playgroud)

给出总和3时:

select xml.value('sum(/List/value)', 'numeric') sum
from (select cast('<List><value>0</value><value>0</value></List>' as xml) xml) a
Run Code Online (Sandbox Code Playgroud)

引发错误:"将数据类型nvarchar转换为数字时出错."

在总结一个零值节点列表时,我知道如何让我的查询返回0?

xml t-sql sql-server xquery

11
推荐指数
2
解决办法
3630
查看次数

File.Open用于在Windows中执行文件时拒绝读取访问

我在Windows中执行文件的文件权限有问题,似乎是在关注论坛提示后解决的[1],但我无法理解为什么.也许你们可以提供帮助.

我正在通过执行它来检查文件的标题(读取控制台输出)然后打开相同的文件以便随后使用FileStream进行读取:

public void fileMD5(string filename) {
  if (!File.Exists(filename)) return NT.Fail("File does not exist: " + filename);

  BinaryReader stream = new BinaryReader(File.Open(filename,
      FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
  int bufferSize = 4096;
  byte[] buffer = new byte[bufferSize];
  int readBytes;
  while ((readBytes = stream.Read(buffer, 0, bufferSize)) > 0) {
    md5Hasher.TransformBlock(buffer, 0, readBytes, buffer, 0);
  }
  stream.Close();
}

fileMD5('sample.exe');
Run Code Online (Sandbox Code Playgroud)

每隔一段时间我就会得到"文件被另一个进程使用".从维基百科我知道Windows将锁定执行拒绝写访问的文件[2],但我只是在阅读.当我尝试打开它时,该过程应该已经停止.

从论坛帖子看,似乎添加一个FileShare.ReadWrite会有所帮助,它似乎确实如此:

FileStream stream = File.Open('sample.exe', 
    FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Run Code Online (Sandbox Code Playgroud)

但我不明白为什么.这里有没有竞争条件我看不到?

使用FileShare.ReadWrite而不是默认值(我猜是FileShare.Read),File.Open调用似乎要快得多.

[1] http://www.xtremevbtalk.com/archive/index.php/t-192118.html

[2] http://en.wikipedia.org/wiki/File_locking#In_Microsoft_Windows

c# windows file-locking

4
推荐指数
1
解决办法
1万
查看次数