Я создал и получил многоадресные, wifi и wake-блокировки, а также установил опцию сокета SO_BROADCAST, но все еще не могу получать широковещательные пакеты UDP на android устройствах.
Проект записан в C и использует JNI для создания блокировок.
void android_main(struct android_app* app) {
JavaVM* vm = app->activity->vm;
JNIEnv* env = app->activity->env;
(*vm)->AttachCurrentThread(vm, &env, NULL);
ANativeActivity* activity = app->activity;
jmethodID jtmID;
jclass jNativeClass = (*env)->GetObjectClass(env, activity->clazz);
jtmID = (*env)->GetMethodID(env, jNativeClass, "getApplication", "()Landroid/app/Application;");
jobject jNativeApplication = (jobject)(*env)->CallObjectMethod(env, activity->clazz, jtmID);
jtmID = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, jNativeApplication), "getApplicationContext", "()Landroid/content/Context;");
jobject jNativeContext = (jobject)(*env)->CallObjectMethod(env, jNativeApplication, jtmID);
jfieldID jNativeWIFI_SERVICE_fid = (*env)->GetStaticFieldID(env, (*env)->GetObjectClass(env, jNativeContext), "WIFI_SERVICE", "Ljava/lang/String;");
jstring jNativeSFID_jstr = (jstring)(*env)->GetStaticObjectField(env, (*env)->FindClass(env, "android/content/Context"), jNativeWIFI_SERVICE_fid);
jstring wifiLockjStr = (*env)->NewStringUTF(env, "PROJECT");
jtmID = (*env)->GetMethodID(env, (*env)->FindClass(env, "android/content/Context"), "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject jSystemService = (*env)->CallObjectMethod(env, jNativeContext, jtmID, jNativeSFID_jstr);
jclass jWMClass = (*env)->FindClass(env, "android/net/wifi/WifiManager");
jclass jWMMLClass = (*env)->FindClass(env, "android/net/wifi/WifiManager$MulticastLock");
jtmID = (*env)->GetMethodID(env, jWMClass, "createMulticastLock", "(Ljava/lang/String;)Landroid/net/wifi/WifiManager$MulticastLock;");
jobject jMCObj = (*env)->CallObjectMethod(env, jSystemService, jtmID, wifiLockjStr);
jtmID = (*env)->GetMethodID(env, jWMMLClass, "setReferenceCounted", "(Z)V");
(*env)->CallVoidMethod(env, jMCObj, jtmID, 0);
jtmID = (*env)->GetMethodID(env, jWMMLClass, "acquire", "()V");
(*env)->CallVoidMethod(env, jMCObj, jtmID);
jtmID = (*env)->GetMethodID(env, jWMMLClass, "isHeld", "()Z");
jboolean isheld = (*env)->CallBooleanMethod(env, jMCObj, jtmID);
if (isheld) {
printf("MulticastLock acquired\n");
}
else {
printf("MulticastLock is not acquired\n");
}
... (Create and set socket then start listening)
}
isheld значение true, но многоадресная блокировка не работает. После этого блока кода для трансляции создается сокет udp и устанавливается опция сокета SO_BROADCAST. Часть разъема является кроссплатформенной и может принимать широковещательные сообщения на windows, linux, et c. но не может на android.