1C移动平台的外部组件(BroadcastReceiver)

本文中所述的所有内容仅对1C开发人员而言很有趣。

今天,我们将分析“ 1C移动应用程序”的外部组件。 本文出现的原因有两个。 我们将在同一个ATOL Smart.Lite下开发所有内容

  1. 开发本机应用程序比我最初想象的要复杂得多。
  2. 收到了一些专门针对1C外部组件的请求

在此之前,我已经有编写c++外部组件的经验。 甚至还有x86平台的模板 。 它是在不了解c++情况下编写的。 但是,它可以在两个项目中工作,并且不会失败。 我们转达问题的实质。 需要一个本机组件以接收1C中的广播消息。 我们将遍历Internet,并了解有现成的解决方案。 但是他们都在我不太喜欢的网站上,因为贪婪过多。 而且我不想为黑匣子付费。 尽管如此,这里还是刊登了一篇很棒的文章“用于Android OS的1C移动平台的外部组件” 。 它描述了如何成型组件的移动版本以及需要安装的组件。 据我了解, 是上述文章的源代码。 非常感谢这位好心人的努力。 一个生动的例子有助于理解它的工作原理和工作原理。 然后,我不得不开阔眼界,JNI是如何工作的。 这里这里简单明了。 我建议您熟悉它们。 我确信真正的C ++程序员不会喜欢我的代码。 我请你放纵自己,p可以改善的地方,写得更正确。

让我们开始吧。 我从前面指出的存储库中获取了源代码,并几乎完全重编了它以适应我的需求。 你可以在这里拿。 让我们回顾一下要点。 我们的主要过程是startEventsWatch其中,我们检查是否未连接BroadcastReceiver并重新定义onReceive函数,然后查看发生了什么事件,填写字段,然后调用OnBroadcastReceive函数,现在它是java和C + +之间的连接函数+,将我们从Android的世界带入1C的世界。 稍后再详细介绍。 我们想要在1C中获得的珍贵线路如下所示。

 filter.addAction("com.xcheng.scanner.action.BARCODE_DECODING_BROADCAST"); filter.addAction(NEW_KEY_UP); 

它描述了我们期望扫描仪发生事件。 就我而言,这是com.xcheng.scanner... 根据您的情况,取决于扫描仪,会有另一行。 因此,消息内部的数据也将不同。 通常,可以从TSD的制造商处获得这些数据。 好吧,还是看看logcat。 我还想接收硬件按钮按下代码。 但是问题没有在额头上解决。 仅将onKeyUP添加到代码中并将其发送到sendBroadcast是不成功的。 毫不奇怪,我们的活动不在前台。 因此,我不得不快速抛出AccessibilityService

startEventsWatch
  public void startEventsWatch() { if (m_Receiver==null) { m_Receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent != null) { String event, type, data; switch (intent.getAction()) { case "com.xcheng.scanner.action.BARCODE_DECODING_BROADCAST": event = "NewBarcode"; type = intent.getStringExtra("EXTRA_BARCODE_DECODING_SYMBOLE"); data = intent.getStringExtra("EXTRA_BARCODE_DECODING_DATA"); OnBroadcastReceive(m_V8Object, event, type, data); break; case NEW_KEY_UP: event = "NewKeyUP"; type = "key"; data = intent.getStringExtra(KEY_CODE); OnBroadcastReceive(m_V8Object, event, type, data); } } } }; IntentFilter filter = new IntentFilter(); filter.addAction("com.xcheng.scanner.action.BARCODE_DECODING_BROADCAST"); filter.addAction(NEW_KEY_UP); m_Activity.registerReceiver(m_Receiver, filter); } } 


现在回到1C中的数据发送。 我们的OnBroadcastReceive调用extern "C" JNIEXPORT void JNICALL Java_org_innovait_atolsmartliteutils_MainApp_OnBroadcastReceive(JNIEnv* env, jclass jClass, jlong pObject, jstring j_event, jstring j_type, jstring j_data)我们可以在这里使用extern "C" JNIEXPORT void JNICALL Java_org_innovait_atolsmartliteutils_MainApp_OnBroadcastReceive(JNIEnv* env, jclass jClass, jlong pObject, jstring j_event, jstring j_type, jstring j_data)jstring j_event, jstring j_type, jstring j_data这些是我传递的变量,事件,CC的类型以及CC本身。 可能还有其他数据。

Java_org_innovait_atolsmartliteutils_MainApp_OnBroadcastReceive
 extern "C" JNIEXPORT void JNICALL Java_org_innovait_atolsmartliteutils_MainApp_OnBroadcastReceive(JNIEnv* env, jclass jClass, jlong pObject, jstring j_event, jstring j_type, jstring j_data) { IAddInDefBaseEx *pAddIn = (IAddInDefBaseEx *) pObject; if (pAddIn != nullptr) { std::wstring ws_event =ToWStringJni(j_event); std::wstring ws_type = ToWStringJni(j_type); std::wstring ws_data = ToWStringJni(j_data); std::wstring obj_data{}; obj_data = L"{\"type\": \"" + ws_type + L"\", \"data\": \"" + ws_data + L"\"}"; WcharWrapper wdata((wchar_t*)obj_data.c_str()); WcharWrapper wmsg((wchar_t*)ws_event.c_str()); pAddIn->ExternalEvent(s_EventSource, wmsg, wdata); } } 


std::wstring ws_event =ToWStringJni(j_event); 这样,我们将字符串从jstringstd::wstring ,然后将其全部打包为1C WcharWrapper wmsg((wchar_t*)ws_event.c_str());

感谢聪明人的转换功能。 第二个功能来自示例1C中的框。

扰流板方向
 std::wstring ToWStringJni(jstring jstr) { std::wstring ret; if (jstr) { JNIEnv* env = getJniEnv(); const jchar* jChars = env->GetStringChars(jstr, NULL); jsize jLen = env->GetStringLength(jstr); ret.assign(jChars, jChars + jLen); env->ReleaseStringChars(jstr, jChars); } return ret; } 


对于那些不想安装所有内容并自己编译的人。 这是成品版。


仅此而已。 等待评论。

Source: https://habr.com/ru/post/zh-CN479132/


All Articles