Componente externo para la plataforma m贸vil 1C (BroadcastReceiver)

Todo lo dicho en el art铆culo ser谩 interesante exclusivamente para los desarrolladores de 1C.

Hoy analizaremos el componente externo para la "Aplicaci贸n m贸vil 1C". Este art铆culo apareci贸 por dos razones. Desarrollaremos todo bajo el mismo ATOL Smart.Lite

  1. El desarrollo de una aplicaci贸n nativa result贸 ser mucho m谩s complicado de lo que pensaba originalmente.
  2. Se recibieron varias solicitudes espec铆ficamente para el componente externo para 1C

Antes de eso, ya ten铆a experiencia escribiendo componentes externos de c++ . E incluso hay una plantilla para la plataforma x86. Fue escrito sin ning煤n conocimiento de c++ . Sin embargo, funciona en dos proyectos y no cae. Pasamos a la esencia del problema. Necesita un componente nativo para recibir mensajes de difusi贸n en 1C. Revisaremos Internet y entenderemos que hay soluciones preparadas. Pero todos est谩n en mi sitio no tan favorito, por codicia excesiva. Y no quer铆a pagar la caja negra. Sin embargo, apareci贸 un excelente art铆culo "Componentes externos de la plataforma m贸vil 1C para el sistema operativo Android" . Describe c贸mo moldear una versi贸n m贸vil de un componente y qu茅 debe instalarse. Seg煤n tengo entendido, aqu铆 est谩 el c贸digo fuente del art铆culo anterior. Muchas gracias al hombre amable por sus esfuerzos. Ayud贸 mucho con un ejemplo vivo para entender qu茅 y c贸mo funciona. Luego tuve que ampliar un poco mis horizontes sobre c贸mo funciona JNI. Simple y claro aqu铆 y aqu铆 . Te recomiendo que te familiarices con ellos. Estoy seguro de que a los programadores reales de c ++ no les gustar谩 mi c贸digo. Te pido que seas indulgente y que toques lo que se puede mejorar y que escribas m谩s correctamente.

Empecemos Tom茅 el c贸digo fuente del repositorio que indiqu茅 anteriormente, y lo rehice casi por completo para satisfacer mis necesidades. Puedes llevarlo aqu铆 . Repasemos los puntos principales. El procedimiento principal para nosotros es startEventsWatch En 茅l, verificamos que no tenemos BroadcastReceiver conectado y redefinimos la funci贸n onReceive All铆 observamos qu茅 evento nos lleg贸, completamos los campos y llamamos a la funci贸n OnBroadcastReceive y ahora es la funci贸n de conexi贸n entre java y C + + y nos lleva del mundo de Android al mundo de 1C. M谩s sobre esto m谩s tarde. Las l铆neas apreciadas de lo que queremos obtener en 1C se ven as铆.

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

Describe que esperamos un evento del esc谩ner. En mi caso, este es com.xcheng.scanner... En su caso, dependiendo del esc谩ner, habr谩 otra l铆nea. En consecuencia, los datos dentro del mensaje tambi茅n ser谩n diferentes. Como regla general, estos datos se pueden obtener del fabricante del TSD. Bueno, o mira logcat. Tambi茅n quer铆a recibir c贸digos de presi贸n de botones de hardware. Pero el problema no se resolvi贸 en la frente. Simplemente agregar onKeyUP al c贸digo y enviarlo a sendBroadcast no tuvo 茅xito. No es sorprendente, nuestra actividad no est谩 en primer plano. Por esta raz贸n, tuve que lanzar r谩pidamente 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); } } 


Ahora volvamos a nuestro env铆o de datos en 1C. Nuestro OnBroadcastReceive llama al 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 Estas son las variables en las que paso, el evento, el tipo de jstring j_event, jstring j_type, jstring j_data de jstring j_event, jstring j_type, jstring j_data s铆. Puede haber otros datos.

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); Con esto traducimos la cadena de jstring a std::wstring , y luego lo empaquetamos todo para 1C WcharWrapper wmsg((wchar_t*)ws_event.c_str());

Gracias a la persona inteligente por la funci贸n de conversi贸n. La segunda funci贸n proviene del cuadro en el ejemplo de 1C.

Encabezado de spoiler
 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; } 


Para aquellos que no quieren instalar todo y compilarlo ellos mismos. Aqu铆 est谩n los lanzamientos terminados.


Eso es todo. Esperando comentarios.

Source: https://habr.com/ru/post/479132/


All Articles