本文中所述的所有内容仅对1C开发人员而言很有趣。今天,我们将分析“ 1C移动应用程序”的外部组件。 本文出现的原因有两个。 我们将在同一个ATOL Smart.Lite下开发所有内容
- 开发本机应用程序比我最初想象的要复杂得多。
- 收到了一些专门针对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);
这样,我们将字符串从
jstring
为
std::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; }
对于那些不想安装所有内容并自己编译的人。 这是成品版。
仅此而已。 等待评论。