// returns 0 on success or -1 on error (others undefined then) // returns truthy or falsy value in plugged, charged and battery // returns the value in seconds and percent or -1 if not available extern "C" int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent) { LocalReferenceHolder refs(__FUNCTION__); JNIEnv* env = Android_JNI_GetEnv(); if (!refs.init(env)) { return -1; } jmethodID mid; mid = env->GetStaticMethodID(mActivityClass, "getContext", "()Landroid/content/Context;"); jobject context = env->CallStaticObjectMethod(mActivityClass, mid); jstring action = env->NewStringUTF("android.intent.action.BATTERY_CHANGED"); jclass cls = env->FindClass("android/content/IntentFilter"); mid = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;)V"); jobject filter = env->NewObject(cls, mid, action); env->DeleteLocalRef(action); mid = env->GetMethodID(mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); jobject intent = env->CallObjectMethod(context, mid, NULL, filter); env->DeleteLocalRef(filter); cls = env->GetObjectClass(intent); jstring iname; jmethodID imid = env->GetMethodID(cls, "getIntExtra", "(Ljava/lang/String;I)I"); #define GET_INT_EXTRA(var, key) \ iname = env->NewStringUTF(key); \ int var = env->CallIntMethod(intent, imid, iname, -1); \ env->DeleteLocalRef(iname); jstring bname; jmethodID bmid = env->GetMethodID(cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); #define GET_BOOL_EXTRA(var, key) \ bname = env->NewStringUTF(key); \ int var = env->CallBooleanMethod(intent, bmid, bname, JNI_FALSE); \ env->DeleteLocalRef(bname); if (plugged) { GET_INT_EXTRA(plug, "plugged") // == BatteryManager.EXTRA_PLUGGED (API 5) if (plug == -1) { return -1; } // 1 == BatteryManager.BATTERY_PLUGGED_AC // 2 == BatteryManager.BATTERY_PLUGGED_USB *plugged = (0 < plug) ? 1 : 0; } if (charged) { GET_INT_EXTRA(status, "status") // == BatteryManager.EXTRA_STATUS (API 5) if (status == -1) { return -1; } // 5 == BatteryManager.BATTERY_STATUS_FULL *charged = (status == 5) ? 1 : 0; } if (battery) { GET_BOOL_EXTRA(present, "present") // == BatteryManager.EXTRA_PRESENT (API 5) *battery = present ? 1 : 0; } if (seconds) { *seconds = -1; // not possible } if (percent) { GET_INT_EXTRA(level, "level") // == BatteryManager.EXTRA_LEVEL (API 5) GET_INT_EXTRA(scale, "scale") // == BatteryManager.EXTRA_SCALE (API 5) if ((level == -1) || (scale == -1)) { return -1; } *percent = level * 100 / scale; } env->DeleteLocalRef(intent); return 0; }
/* returns 0 on success or -1 on error (others undefined then) * returns truthy or falsy value in plugged, charged and battery * returns the value in seconds and percent or -1 if not available */ int CC_CALL cc_jni_get_power_info(int* plugged, int* charged, int* battery, int* seconds, int* percent) { struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); JNIEnv* env = cc_jni_get_env(); jmethodID mid; if (!LocalReferenceHolder_Init(&refs, env)) { LocalReferenceHolder_Cleanup(&refs); return -1; } mid = (*env)->GetStaticMethodID(env, _activity_class, "getContext", "()Landroid/content/Context;"); jobject context = (*env)->CallStaticObjectMethod(env, _activity_class, mid); jstring action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); jclass cls = (*env)->FindClass(env, "android/content/IntentFilter"); mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); jobject filter = (*env)->NewObject(env, cls, mid, action); (*env)->DeleteLocalRef(env, action); mid = (*env)->GetMethodID(env, _activity_class, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); jobject intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); (*env)->DeleteLocalRef(env, filter); cls = (*env)->GetObjectClass(env, intent); jstring iname; jmethodID imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); #define GET_INT_EXTRA(var, key) \ iname = (*env)->NewStringUTF(env, key); \ int var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ (*env)->DeleteLocalRef(env, iname); jstring bname; jmethodID bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); #define GET_BOOL_EXTRA(var, key) \ bname = (*env)->NewStringUTF(env, key); \ int var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ (*env)->DeleteLocalRef(env, bname); if (plugged) { GET_INT_EXTRA(plug, "plugged") /* == BatteryManager.EXTRA_PLUGGED (API 5) */ if (plug == -1) { LocalReferenceHolder_Cleanup(&refs); return -1; } /* 1 == BatteryManager.BATTERY_PLUGGED_AC */ /* 2 == BatteryManager.BATTERY_PLUGGED_USB */ *plugged = (0 < plug) ? 1 : 0; } if (charged) { GET_INT_EXTRA(status, "status") /* == BatteryManager.EXTRA_STATUS (API 5) */ if (status == -1) { LocalReferenceHolder_Cleanup(&refs); return -1; } /* 5 == BatteryManager.BATTERY_STATUS_FULL */ *charged = (status == 5) ? 1 : 0; } if (battery) { GET_BOOL_EXTRA(present, "present") /* == BatteryManager.EXTRA_PRESENT (API 5) */ *battery = present ? 1 : 0; } if (seconds) { *seconds = -1; /* not possible */ } if (percent) { GET_INT_EXTRA(level, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */ GET_INT_EXTRA(scale, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */ if ((level == -1) || (scale == -1)) { LocalReferenceHolder_Cleanup(&refs); return -1; } *percent = level * 100 / scale; } (*env)->DeleteLocalRef(env, intent); LocalReferenceHolder_Cleanup(&refs); return 0; }
/* * CODE CHUNK IMPORTED FROM SDL 2.0 * returns 0 on success or -1 on error (others undefined then) * returns truthy or falsy value in plugged, charged and battery * returns the value in seconds and percent or -1 if not available */ int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent) { env = Android_JNI_GetEnv(); refs = LocalReferenceHolder_Setup(__FUNCTION__); if (!LocalReferenceHolder_Init(&refs, env)) { LocalReferenceHolder_Cleanup(&refs); return -1; } mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); cls = (*env)->FindClass(env, "android/content/IntentFilter"); mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); filter = (*env)->NewObject(env, cls, mid, action); (*env)->DeleteLocalRef(env, action); mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); (*env)->DeleteLocalRef(env, filter); cls = (*env)->GetObjectClass(env, intent); imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); // Watch out for C89 scoping rules because of the macro #define GET_INT_EXTRA(var, key) \ int var; \ iname = (*env)->NewStringUTF(env, key); \ var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ (*env)->DeleteLocalRef(env, iname); bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); // Watch out for C89 scoping rules because of the macro #define GET_BOOL_EXTRA(var, key) \ int var; \ bname = (*env)->NewStringUTF(env, key); \ var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ (*env)->DeleteLocalRef(env, bname); if (plugged) { // Watch out for C89 scoping rules because of the macro GET_INT_EXTRA(plug, "plugged") // == BatteryManager.EXTRA_PLUGGED (API 5) if (plug == -1) { LocalReferenceHolder_Cleanup(&refs); return -1; } // 1 == BatteryManager.BATTERY_PLUGGED_AC // 2 == BatteryManager.BATTERY_PLUGGED_USB *plugged = (0 < plug) ? 1 : 0; } if (charged) { // Watch out for C89 scoping rules because of the macro GET_INT_EXTRA(status, "status") // == BatteryManager.EXTRA_STATUS (API 5) if (status == -1) { LocalReferenceHolder_Cleanup(&refs); return -1; } // 5 == BatteryManager.BATTERY_STATUS_FULL *charged = (status == 5) ? 1 : 0; } if (battery) { GET_BOOL_EXTRA(present, "present") // == BatteryManager.EXTRA_PRESENT (API 5) *battery = present ? 1 : 0; } if (seconds) { *seconds = -1; // not possible } if (percent) { int level; int scale; // Watch out for C89 scoping rules because of the macro { GET_INT_EXTRA(level_temp, "level") // == BatteryManager.EXTRA_LEVEL (API 5) level = level_temp; } // Watch out for C89 scoping rules because of the macro { GET_INT_EXTRA(scale_temp, "scale") // == BatteryManager.EXTRA_SCALE (API 5) scale = scale_temp; } if ((level == -1) || (scale == -1)) { LocalReferenceHolder_Cleanup(&refs); return -1; } *percent = level * 100 / scale; } (*env)->DeleteLocalRef(env, intent); LocalReferenceHolder_Cleanup(&refs); return 0; }