我正在尝试创建一个按顺序执行蓝牙任务的类,除了启动该过程之外,无需用户干预。在这个类中,外部事件从那里调用被覆盖的方法“executeCentral”,它调用setup()来启用和请求权限。如果它们成功完成,则调用initialize()方法并在调用在EDT中执行的Bluetooth initialize()之前等待一秒钟。如果它无异常运行,则调用startScanning(),它也会在EDT中调用蓝牙startScan()之前等待1秒。扫描开始后,等待10秒后再在EDT中调用蓝牙stopScan()。
我重新创建了一个干净的设置项目,并在Codename One Settings中使用了“下载程序”。它成功编译并运行,但报告“蓝牙未初始化”的例外情况
对我做错了什么的任何想法?我的印象是所有电话都必须在美国东部时间完成。
单一形式BTDemo将每个任务编译并执行为单独的用户启动事件。
public class UITaskBluetoothEx extends com.crumptech.library.mobile.ui.tasks.UITaskBluetooth {
protected Bluetooth bt = new Bluetooth();
protected Map devices = new HashMap();
public UITaskBluetoothEx() {
super();
}
@Override
public String getReplacement() {
return "UITaskBluetoothEx";
}
protected void showDebug(String message) {
Display.getInstance().callSerially(new Runnable() {
@Override
public void run() {
UIApplication.showDebug("UITaskBluetoothEx " + message);
completed(result(false));
}
});
}
@Override
protected void executeCentral() {
bt = new Bluetooth();
try {
setup();
initialize();
} catch (Exception e) {
showDebug(e.getMessage());
}
}
protected void setup() throws IOException {
if (!bt.isEnabled()) {
bt.enable();
}
if (!bt.hasPermission()) {
bt.requestPermission();
}
}
protected void initialize() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Display.getInstance().callSerially(new Runnable() {
@Override
public void run() {
try {
if (!bt.isInitialized()) {
bt.initialize(true, false, "ShopMyLocalStores");
}
startScanning();
} catch (Exception e) {
showDebug(e.getMessage());
}
}
});
}
}, 1000);
}
protected void startScanning() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Display.getInstance().callSerially(new Runnable() {
@Override
public void run() {
try {
if (!bt.isScanning()) {
bt.startScan(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
try {
JSONObject res = (JSONObject) evt.getSource();
if (res.getString("status").equals("scanResult")) {
if (!devices.containsKey(res.getString("address"))) {
devices.put(res.getString("address"), res);
}
}
} catch (JSONException e) {
}
}
}, null, true, Bluetooth.SCAN_MODE_LOW_POWER, Bluetooth.MATCH_MODE_STICKY, Bluetooth.MATCH_NUM_MAX_ADVERTISEMENT, Bluetooth.CALLBACK_TYPE_ALL_MATCHES);
stopScanning();
}
} catch (Exception e) {
showDebug(e.getMessage());
}
}
});
}
}, 1000);
}
protected void stopScanning() {
try {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Display.getInstance().callSerially(new Runnable() {
@Override
public void run() {
try {
if (bt.isScanning()) {
bt.stopScan();
}
} catch (Exception e) {
showDebug(e.getMessage());
}
showResults();
}
});
}
}, 10000);
} catch (Exception e) {
}
}
protected void showResults() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Display.getInstance().callSerially(new Runnable() {
@Override
public void run() {
String text = "";
Iterator it = devices.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
text += (pair.getKey() + " = " + pair.getValue() + "\r\n");
}
UIApplication.showDebug(text);
completed(result(true));
}
});
}
}, 1000);
}
}
答案 0 :(得分:1)
看起来iOS上目前不支持某些方法。如果在iOS上调用它们,它们将抛出IOExceptions。这是我们移植的Cordova插件中的限制。这些方法确实会返回" Unsupported Operation"插件内部。我不确定这些是否只是插件的遗漏,或者它们是否无法得到支持。 iOS上当前不支持的方法列表包括:
我在蓝牙类的javadocs中标记了这些以帮助识别它们。我们可能不得不在这里做些什么来清理它......也许一个例外不是最好的事情。
在任何情况下,您的测试应用程序都会失败,因为您在同一个try / catch块中调用了isEnabled()和initialize()。 isEnabled会抛出异常,因此它永远不会初始化(),并且您的测试也不会运行。
我已将您的代码调整到我自己的测试用例中,并进行了修改,看起来运行正常。