我正在创建一个与专有蓝牙LE设备的Android SDK连接的ANE。 SDK已经在纯Android项目上进行了测试,并且工作正常。我正在使用FREContext.dispatchStatusEventAsync返回有关检测到的每个信标的信息。但是,在AIR应用程序运行时观察从LogCat返回的日志时,我发现每次找到信标时都会抛出IllegalArgumentException。有趣的是,我可以在其他任何地方使用dispatchStatusEventAsync,它似乎工作正常。
以下是ANE的所有相关代码。 (我通过执行查找/替换来掩盖SDK的名称,但代码编译,所以如果对类或函数的命名有些疯狂,请不要认为它是一个可能的问题。)
" DUMMY"语句只是表明它们是用于调试的。
BecsterExtension.java
public class BecsterExtension implements FREExtension
{
public static final String TAG = "BecsterExtension";
@Override
public FREContext createContext(String arg0)
{
return new BecsterContext();
}
@Override
public void dispose()
{
// TODO Auto-generated method stub
}
@Override
public void initialize()
{
// TODO Auto-generated method stub
}
}
BecContext.java
public class BecContext extends FREContext {
@Override
public void dispose()
{
// TODO Auto-generated method stub
}
@Override
public Map<String, FREFunction> getFunctions()
{
Map<String, FREFunction> functionMap = new HashMap<String, FREFunction>();
functionMap.put("startScanning", new StartScanFunction());
return functionMap;
}
}
StartScanFunction.java
private final static String TAG = StartScanFunction.class.getSimpleName();
byte[] advPacket;
public BecsterBeacon becBecMgr;
@Override
public FREObject call(FREContext context, FREObject[] args)
{
//****-----BECSTER SDK START-----****//
Log.i(TAG, "**Initializing Becster SDK**");
//this call works
context.dispatchStatusEventAsync("BECSTER_DUMMY", "Becster SDK has started initalizing");
if (!context.getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE))
{
Log.e(TAG, "Bluetooth LE not supported or disabled");
return null;
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) context.getActivity().getSystemService(Context.BLUETOOTH_SERVICE);
Log.i(TAG, "Starting Becster Beacon Manager");
becBecMgr = new BecsterBeacon(bluetoothManager, new BecNotifyHandler(context));
Log.i(TAG, "**Becster SDK Initialized**");
//this call works
context.dispatchStatusEventAsync("BECSTER_DUMMY", "Becster SDK has finished initalizing");
BecBecMgr.startLEScan();
return null;
}
BecNotifyHandler.java(这实现了BecEvent的功能becsterEventNotify,它是从内部调用的
public static final String TAG = "BecNotifyHandler";
private FREContext context;
public BecNotifyHandler(FREContext context)
{
context.dispatchStatusEventAsync("BECSTER_DUMMY", "BecNotifyHandler has been initialized");
this.context = context;
}
@Override
public void becsterEventNotify(BecPkt event)
{
try
{
Log.i(TAG, "Notifying of Becster event. Context: " + context);
//this call ALWAYS throws the IllegalArgumentException
context.dispatchStatusEventAsync("BECSTER_NOTIFY", "Becster notify");
Log.i(TAG, "Notified");
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
}
logcat的:
07-17 10:50:33.949: I/BecNotifyHandler(17467): Notifying of Becster event. Context: com.company.sdk.BecsterContext@41e2df30
07-17 10:50:33.949: W/System.err(17467): java.lang.IllegalArgumentException
07-17 10:50:33.949: W/System.err(17467): at com.adobe.fre.FREContext.dispatchStatusEventAsync(Native Method)
07-17 10:50:33.949: W/System.err(17467): at com.company.sdk.BecNotifyHandler.becsterEventNotify(BecNotifyHandler.java:27)
07-17 10:50:33.949: W/System.err(17467): at com.becster.becsterSDK.BecsterBeacon$1$1.run(BecsterBeacon.java:280)
07-17 10:50:33.949: W/System.err(17467): at android.os.Handler.handleCallback(Handler.java:733)
07-17 10:50:33.949: W/System.err(17467): at android.os.Handler.dispatchMessage(Handler.java:95)
07-17 10:50:33.949: W/System.err(17467): at android.os.Looper.loop(Looper.java:136)
07-17 10:50:33.949: W/System.err(17467): at android.app.ActivityThread.main(ActivityThread.java:5141)
07-17 10:50:33.949: W/System.err(17467): at java.lang.reflect.Method.invokeNative(Native Method)
07-17 10:50:33.957: W/System.err(17467): at java.lang.reflect.Method.invoke(Method.java:515)
07-17 10:50:33.957: W/System.err(17467): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
07-17 10:50:33.957: W/System.err(17467): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
07-17 10:50:33.957: W/System.err(17467): at dalvik.system.NativeStart.main(Native Method)
非常感谢任何见解!
答案 0 :(得分:1)
context.dispatchStatusEventAsync继续产生一些非常奇怪的结果。当我调用becsterEventNotify一次时,我会收到正确的消息。两次背靠背调用becsterEventNotify没有发送任何消息。因此,我仍然不确定导致问题的原因。我怀疑线程可能存在问题,因为我一度使用Thread.sleep(1000)来查看在消息之间放一些时间是否有帮助,但这并没有导致任何消息被发送。
如果有人好奇,我确实想出了一个解决方法。我创建了一个静态的字符串Vector来保存来自信标的数据(id,电池寿命和rssi),而不是使用dispatchStatusEventAsync。
public static Vector<String> packets = new Vector<String>();
然后将此gem添加为函数:
public class GetNextPacketFunction implements FREFunction
{
private static final String TAG = GetNextPacketFunction.class.getSimpleName();
@Override
public FREObject call(FREContext context, FREObject[] args)
{
Vector<String> packets = BecsterExtension.packets;
if (packets != null && packets.size() > 0)
{
String nextPacket = packets.remove(packets.size() - 1);
Log.i(TAG, "Found packet: " + nextPacket);
try
{
return FREObject.newObject(nextPacket);
}
catch (FREWrongThreadException e)
{
Log.e(TAG, "WRONG THREAD!");
e.printStackTrace();
}
}
return null;
}
}
然后我实现了这样的通知程序,以便在数据包进入时保存:
@Override
public void becsterEventNotify(BecPkt event)
{
String newPacket = btIDStr + ";" + event.getBattVal() + ";" + event.getRssiVal();
BecsterExtension.packets.add(newPacket);
Log.i(TAG, "Number of packets in queue: " + BecsterExtension.packets.size());
}
然后在AS端,我使用Timer每秒轮询一次新的数据包(尚未确定这是否是最佳间隔):
var packetTimer:Timer = new Timer(1000);
packetTimer.addEventListener(TimerEvent.TIMER, function (e:TimerEvent):void
{
var newPacket:String = getNextPacket();
if (newPacket != null)
{
var data:Array = newPacket.split(";");
var becEvent:BecEvent = new BecEvent(BecEvent.NOTIFY);
becEvent.id = data[0];
becEvent.battLife = data[1];
becEvent.rssi = data[2];
dispatchEvent(becEvent);
}
});
packetTimer.start();
这种方法目前运作良好,我更喜欢它,因为我可以管理AS端的排队。
全部谢谢!