DJI onProductChange 和 onProductConnect 的区别
Difference between DJI onProductChange and onProductConnect
上下文
我正在 DJK SDK 之上构建一个 Flutter 插件。为此,我必须在本机端实现与飞机的通信,我正在使用 Java 来实现。我也只为 Android.
这样做
API的方法之一是boolean connectToAircraft()
,必须return连接飞行器成功
Expected/current行为
在我调用 connectToAircraft()
之后 - 它调用了 DJISDKManager.getInstance().startConnectionToProduct()
方法,我希望能够立即使用与飞机相关的任何东西,但这并没有发生。我得等几秒钟才能从飞机上取回数据
一些代码
public class UavApi implements IUavApi, DJISDKManager.SDKManagerCallback {
...
private final CountDownLatch onConnectToUavFinishedSignal = new CountDownLatch(1);
...
public boolean connectToUav() throws InterruptedException {
Logger.v("connectToUav()");
DJISDKManager.getInstance().startConnectionToProduct();
synchronized (onConnectToUavFinishedSignal) {
onConnectToUavFinishedSignal.await();
}
return DJISDKManager.getInstance().getProduct() instanceof Aircraft;
}
...
@Override
public void onProductConnect(@Nullable final BaseProduct baseProduct) {
Logger.v(MessageFormat.format("onProductConnect(product: {0})", baseProduct));
if (baseProduct != null) {
handleProductConnected(baseProduct);
}
}
@Override
public void onProductChanged(@Nullable final BaseProduct baseProduct) {
Logger.v(MessageFormat.format("onProductChanged(product: {0})", baseProduct));
if (baseProduct != null) {
handleProductConnected(baseProduct);
}
}
...
private void handleProductConnected(@NonNull final BaseProduct baseProduct) {
Logger.d(MessageFormat.format("Is null? {0}", baseProduct == null ? "Yes" : "No"));
Logger.d(MessageFormat.format("Type: {0}", baseProduct.getClass().getSimpleName()));
onConnectToUavFinishedSignal.countDown();
}
...
}
问题
上面的代码是我尝试做的,但它不起作用,我猜这是因为我误解了 onProductChange()
和 onProductConnect()
方法的使用。
DJISDKManager.getInstance().getProduct()
总是 returning null。
OBS:总是在 onConnectToUavFinishedSignal.await()
调用结束后立即 returning null。几秒钟后,我得到了飞机的有效实例。
我还注意到,有时调用 onProductChange()
时会使用日志输出的某些值作为 Unknwoun 和 None。这些是什么?我如何测试它们?喜欢if (baseProduct == ???) doSomething()
环境
- Android 9
- MSDK 4.13.1
- 精灵 4 Pro
差异
根据SDK DocsonProductChanged
主要用于检测连接状态从只连接遥控器变为全连接飞行器与SDK运行设备。
请记住,当飞机断开连接时,将使用飞机实例调用此方法,但此实例将与 属性 isConnected
一起作为 false
。如果将飞机对象打印到控制台,您会注意到如果 isConnected
是 true
,它将打印飞机名称,否则将打印“None”。
只要onProductConnect
,总是会在DJISDKManager.getInstance().registerApp()
成功后或手动连接飞行器DJISDKManager.getInstance().startConnectionToProduct()
成功后调用。在我的测试中,即使应用程序注册成功,该方法也会 return false
,因此您可能需要检查 SDKManagerCallback::onRegister
是否导致 DJISDKError.REGISTRATION_SUCCESS
.
解决方案
您需要监听组件变化事件。不幸的是,仅仅因为产品已连接,并不意味着飞行控制器、摄像头等各个组件都已连接。您将需要实施 onComponentChange
并添加侦听器以检测组件何时连接。这些并不总是以相同的顺序连接,可能会在连接产品之前或之后开始连接。
@Override
public void onComponentChange(
BaseProduct.ComponentKey componentKey,
BaseComponent oldBaseComponent,
BaseComponent newBaseComponent
) {
newBaseComponent.setComponentListener(isConnected -> {
// check if component connected and access data
if (isConnected) {
if(componentKey == ComponentKey.FLIGHT_CONTROLLER) {
// DJISDKManager.getInstance().getProduct() should no longer be null
DJISDKManager.getInstance().getProduct().getModel();
}
}
})
}
上下文
我正在 DJK SDK 之上构建一个 Flutter 插件。为此,我必须在本机端实现与飞机的通信,我正在使用 Java 来实现。我也只为 Android.
这样做API的方法之一是boolean connectToAircraft()
,必须return连接飞行器成功
Expected/current行为
在我调用 connectToAircraft()
之后 - 它调用了 DJISDKManager.getInstance().startConnectionToProduct()
方法,我希望能够立即使用与飞机相关的任何东西,但这并没有发生。我得等几秒钟才能从飞机上取回数据
一些代码
public class UavApi implements IUavApi, DJISDKManager.SDKManagerCallback {
...
private final CountDownLatch onConnectToUavFinishedSignal = new CountDownLatch(1);
...
public boolean connectToUav() throws InterruptedException {
Logger.v("connectToUav()");
DJISDKManager.getInstance().startConnectionToProduct();
synchronized (onConnectToUavFinishedSignal) {
onConnectToUavFinishedSignal.await();
}
return DJISDKManager.getInstance().getProduct() instanceof Aircraft;
}
...
@Override
public void onProductConnect(@Nullable final BaseProduct baseProduct) {
Logger.v(MessageFormat.format("onProductConnect(product: {0})", baseProduct));
if (baseProduct != null) {
handleProductConnected(baseProduct);
}
}
@Override
public void onProductChanged(@Nullable final BaseProduct baseProduct) {
Logger.v(MessageFormat.format("onProductChanged(product: {0})", baseProduct));
if (baseProduct != null) {
handleProductConnected(baseProduct);
}
}
...
private void handleProductConnected(@NonNull final BaseProduct baseProduct) {
Logger.d(MessageFormat.format("Is null? {0}", baseProduct == null ? "Yes" : "No"));
Logger.d(MessageFormat.format("Type: {0}", baseProduct.getClass().getSimpleName()));
onConnectToUavFinishedSignal.countDown();
}
...
}
问题
上面的代码是我尝试做的,但它不起作用,我猜这是因为我误解了 onProductChange()
和 onProductConnect()
方法的使用。
DJISDKManager.getInstance().getProduct()
总是 returning null。
OBS:总是在 onConnectToUavFinishedSignal.await()
调用结束后立即 returning null。几秒钟后,我得到了飞机的有效实例。
我还注意到,有时调用 onProductChange()
时会使用日志输出的某些值作为 Unknwoun 和 None。这些是什么?我如何测试它们?喜欢if (baseProduct == ???) doSomething()
环境
- Android 9
- MSDK 4.13.1
- 精灵 4 Pro
差异
根据SDK DocsonProductChanged
主要用于检测连接状态从只连接遥控器变为全连接飞行器与SDK运行设备。
请记住,当飞机断开连接时,将使用飞机实例调用此方法,但此实例将与 属性 isConnected
一起作为 false
。如果将飞机对象打印到控制台,您会注意到如果 isConnected
是 true
,它将打印飞机名称,否则将打印“None”。
只要onProductConnect
,总是会在DJISDKManager.getInstance().registerApp()
成功后或手动连接飞行器DJISDKManager.getInstance().startConnectionToProduct()
成功后调用。在我的测试中,即使应用程序注册成功,该方法也会 return false
,因此您可能需要检查 SDKManagerCallback::onRegister
是否导致 DJISDKError.REGISTRATION_SUCCESS
.
解决方案
您需要监听组件变化事件。不幸的是,仅仅因为产品已连接,并不意味着飞行控制器、摄像头等各个组件都已连接。您将需要实施 onComponentChange
并添加侦听器以检测组件何时连接。这些并不总是以相同的顺序连接,可能会在连接产品之前或之后开始连接。
@Override
public void onComponentChange(
BaseProduct.ComponentKey componentKey,
BaseComponent oldBaseComponent,
BaseComponent newBaseComponent
) {
newBaseComponent.setComponentListener(isConnected -> {
// check if component connected and access data
if (isConnected) {
if(componentKey == ComponentKey.FLIGHT_CONTROLLER) {
// DJISDKManager.getInstance().getProduct() should no longer be null
DJISDKManager.getInstance().getProduct().getModel();
}
}
})
}