android - BLE 广告在 Android 中的变化
问题描述
我对 android 和 BLE 很陌生。目前,我正在尝试宣传一个在 android 低谷 BLE 中周期性变化的数据包。我使用了https://source.android.com/devices/bluetooth/ble_advertising中提供的以下代码。
BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
AdvertisingSetParameters parameters = (new AdvertisingSetParameters.Builder())
.setLegacyMode(true) // True by default, but set here as a reminder.
.setConnectable(false)
.setInterval(AdvertisingSetParameters.INTERVAL_HIGH)
.setTxPowerLevel(AdvertisingSetParameters.TX_POWER_HIGH)
.build();
AdvertiseData data = (new AdvertiseData.Builder()).setIncludeDeviceName(true).build();
final AdvertisingSet[] currentAdvertisingSet = new AdvertisingSet[1];
//final AdvertisingSet[] currentAdvertisingSet = {null};
AdvertisingSetCallback callback = new AdvertisingSetCallback() {
@Override
public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
Log.i(LOG_TAG, "onAdvertisingSetStarted(): txPower:" + txPower + " , status: "
+ status);
currentAdvertisingSet[0] = advertisingSet;
}
@Override
public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {
Log.i(LOG_TAG, "onAdvertisingDataSet() :status:" + status);
}
@Override
public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {
Log.i(LOG_TAG, "onScanResponseDataSet(): status:" + status);
}
@Override
public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
Log.i(LOG_TAG, "onAdvertisingSetStopped():");
}
};
//start advertising
advertiser.startAdvertisingSet(parameters, data, null, null, null, callback);
//change the advertising packet
currentAdvertisingSet[0].setAdvertisingData(new AdvertiseData.Builder().setIncludeDeviceName(true).setIncludeTxPowerLevel(true).build());
但是当我尝试分配一个新的广告数据作为我得到的最后一行时
Attempt to invoke virtual method 'void android.bluetooth.le.AdvertisingSet.setAdvertisingData(android.bluetooth.le.AdvertiseData)' on a null object reference
错误和应用程序以setLegacyMode true 和 false 关闭。但是我已经在public void onAdvertisingSetStarted函数中分配了adsSet 。我应该在这里做什么?
解决方案
currentAdvertisingSet[0]
显示的代码导致 NullPointerException 的原因是因为它在您为该数组元素分配值之前 尝试访问。
当代码初始化它时final AdvertisingSet[] currentAdvertisingSet = new AdvertisingSet[1];
,数组的内容被初始化,每个元素都设置为 null。在执行之前,代码不会初始化currentAdvertisingSet[0]
为非空值AdvertisingSetCallback
。这是异步的,将在调用advertiser.startAdvertisingSet(...)
.
currentAdvertisingSet[0].setAdvertisingData(...)
问题是当下一行在几微秒后执行时,这个回调还没有发生。当它执行时,currentAdvertisingSet[0]
元素还没有被初始化——它仍然是空的。这就是代码崩溃的原因。
要解决此问题,您必须等到currentAdvertisingSet[0]
它被初始化后再使用。你当然可以添加一个检查if (currentAdvertisingSet[0] != null)
来防止崩溃,但是在显示的代码中这永远不会是真的,所以代码永远不会执行。
最终,您需要移动更改广告集的代码,以便稍后执行。您可以将此代码放在回调中,但这对您的用例可能没有意义——开始广告然后立即将其更改为其他内容可能没有意义。
推荐阅读
- flutter - 相同的代码在不同的机器上生成不同的黄金图像
- swift - 如何检测 AVQueuePlayer 播放完毕?
- c++ - 有符号整数类型的大小可以不同于 C/C++ 中对应的无符号类型的大小吗?
- c# - 在 .net SDK MYOB 中进行调用时是否需要 ICompanyFileCredentials
- laravel - 在 mpdf 中生成 pdf 时,如何修复 Laravel 中的 Class doi 不存在错误?
- python - 我可以跨多个文件创建一个相互引用的 sqlalchemy 类吗
- javascript - 将多个json文件导入一个js数组
- r - 如何在 r 中按时间聚合/求和值
- c# - 领域驱动设计:订单和订单线类
- javascript - 在 HighCharts 上设置图标(图像)时遇到问题