实例见https://blog.csdn.net/u010349644/article/details/80816701
这个是android源代码(android R)
frameworks/base/media/java/android/media/MediaRecorder.java public class MediaRecorder implements AudioRouting, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AudioRecordingMonitor, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AudioRecordingMonitorClient, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MicrophoneDirection { ? ? ?static { ? ? ? ? ?System.loadLibrary("media_jni"); ? ? ? ? ?native_init(); ? ? ?} ? @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) ? ? ? private static native final void native_init(); ?? ? ? ? @UnsupportedAppUsage ? ? ? private native final void native_setup(Object mediarecorder_this, ? ? ? ? ? ? ? String clientName, String opPackageName) throws IllegalStateException;
?@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) ? ? ? private native final void native_finalize(); ?? ? ? ? @UnsupportedAppUsage ? ? ? private native void setParameter(String nameValuePair);
?public int getPortId() { ? ? ? ? ? if (mNativeContext == 0) { ? ? ? ? ? ? ? return 0; ? ? ? ? ? } ? ? ? ? ? return native_getPortId(); ? ? ? } ?? ? ? ? private native int native_getPortId();
? ?public void setAudioSamplingRate(int samplingRate) { ? ? ? ? ?if (samplingRate <= 0) { ? ? ? ? ? ? ?throw new IllegalArgumentException("Audio sampling rate is not positive"); ? ? ? ? ?} ? ? ? ? ?setParameter("audio-param-sampling-rate=" + samplingRate); ? ? ?} --------------------------------------------------
frameworks/base/media/jni/android_media_MediaRecorder.cpp
// ref-counted object for callbacks class JNIMediaRecorderListener: public MediaRecorderListener { public: ? ? JNIMediaRecorderListener(JNIEnv* env, jobject thiz, jobject weak_thiz); ? ? ~JNIMediaRecorderListener(); ? ? void notify(int msg, int ext1, int ext2); private: ? ? JNIMediaRecorderListener(); ? ? jclass ? ? ?mClass; ? ? // Reference to MediaRecorder class ? ? jobject ? ? mObject; ? ?// Weak ref to MediaRecorder Java object to call on };
JNIMediaRecorderListener::JNIMediaRecorderListener(JNIEnv* env, jobject thiz, jobject weak_thiz) {
? ? // Hold onto the MediaRecorder class for use in calling the static method ? ? // that posts events to the application thread. ? ? jclass clazz = env->GetObjectClass(thiz); ? ? if (clazz == NULL) { ? ? ? ? ALOGE("Can't find android/media/MediaRecorder"); ? ? ? ? jniThrowException(env, "java/lang/Exception", NULL); ? ? ? ? return; ? ? ?} ? ? ?mClass = (jclass)env->NewGlobalRef(clazz); ? ? ? ?// We use a weak reference so the MediaRecorder object can be garbage collected. ? ? ?// The reference is only used as a proxy for callbacks. ? ? ?mObject ?= env->NewGlobalRef(weak_thiz); ?} ? ?JNIMediaRecorderListener::~JNIMediaRecorderListener() ?{ ? ? ?// remove global references ? ? ?JNIEnv *env = AndroidRuntime::getJNIEnv(); ? ? ?env->DeleteGlobalRef(mObject); ? ? ?env->DeleteGlobalRef(mClass); ?} ? ?void JNIMediaRecorderListener::notify(int msg, int ext1, int ext2) ?{ ? ? ?ALOGV("JNIMediaRecorderListener::notify"); ? ? ? ?JNIEnv *env = AndroidRuntime::getJNIEnv(); ? ? ?env->CallStaticVoidMethod(mClass, fields.post_event, mObject, msg, ext1, ext2, NULL); ?} ?
?static void ?android_media_MediaRecorder_setParameter(JNIEnv *env, jobject thiz, jstring params) ?{ ? ? ?ALOGV("setParameter()"); ? ? ?if (params == NULL) ? ? ?{ ? ? ? ? ?ALOGE("Invalid or empty params string. ?This parameter will be ignored."); ? ? ? ? ?return; ? ? ?} ? ? ? ?sp<MediaRecorder> mr = getMediaRecorder(env, thiz); ? ? ?if (mr == NULL) { ? ? ? ? ?jniThrowException(env, "java/lang/IllegalStateException", NULL); ? ? ? ? ?return; ? ? ?} ? ? ? ?const char* params8 = env->GetStringUTFChars(params, NULL); ? ? ?if (params8 == NULL) ? ? ?{ ? ? ? ? ?ALOGE("Failed to covert jstring to String8. ?This parameter will be ignored."); ? ? ? ? ?return; ? ? ?} ? ? ? ?process_media_recorder_call(env, mr->setParameters(String8(params8)), "java/lang/RuntimeException", "setParameter failed."); ? ? ?env->ReleaseStringUTFChars(params,params8); ?} ? ? ?static void ?android_media_MediaRecorder_start(JNIEnv *env, jobject thiz) ?{ ? ? ?ALOGV("start"); ? ? ?sp<MediaRecorder> mr = getMediaRecorder(env, thiz); ? ? ?if (mr == NULL) { ? ? ? ? ?jniThrowException(env, "java/lang/IllegalStateException", NULL); ? ? ? ? ?return; ? ? ?} ? ? ?process_media_recorder_call(env, mr->start(), "java/lang/RuntimeException", "start failed."); ?} ? ?static void ?android_media_MediaRecorder_stop(JNIEnv *env, jobject thiz) ?{ ? ? ?ALOGV("stop"); ? ? ?sp<MediaRecorder> mr = getMediaRecorder(env, thiz); ? ? ?if (mr == NULL) { ? ? ? ? ?jniThrowException(env, "java/lang/IllegalStateException", NULL); ? ? ? ? ?return; ? ? ?} ? ? ?process_media_recorder_call(env, mr->stop(), "java/lang/RuntimeException", "stop failed."); ?} ? ?static void ?android_media_MediaRecorder_pause(JNIEnv *env, jobject thiz) ?{ ? ? ?ALOGV("pause"); ? ? ?sp<MediaRecorder> mr = getMediaRecorder(env, thiz); ? ? ?if (mr == NULL) { ? ? ? ? ?jniThrowException(env, "java/lang/IllegalStateException", NULL); ? ? ? ? ?return; ? ? ?} ? ? ?process_media_recorder_call(env, mr->pause(), "java/lang/RuntimeException", "pause failed."); ?} ? ?static void ?android_media_MediaRecorder_resume(JNIEnv *env, jobject thiz) ?{ ? ? ?ALOGV("resume"); ? ? ?sp<MediaRecorder> mr = getMediaRecorder(env, thiz); ? ? ?if (mr == NULL) { ? ? ? ? ?jniThrowException(env, "java/lang/IllegalStateException", NULL); ? ? ? ? ?return; ? ? ?} ? ? ?process_media_recorder_call(env, mr->resume(), "java/lang/RuntimeException", "resume failed."); ?} ? ?static void ?android_media_MediaRecorder_native_reset(JNIEnv *env, jobject thiz) ?{ ? ? ?ALOGV("native_reset"); ? ? ?sp<MediaRecorder> mr = getMediaRecorder(env, thiz); ? ? ?if (mr == NULL) { ? ? ? ? ?jniThrowException(env, "java/lang/IllegalStateException", NULL); ? ? ? ? ?return; ? ? ?} ? ? ?process_media_recorder_call(env, mr->reset(), "java/lang/RuntimeException", "native_reset failed."); ?} ? ?static void ?android_media_MediaRecorder_release(JNIEnv *env, jobject thiz) ?{ ? ? ?ALOGV("release"); ? ? ?sp<MediaRecorder> mr = setMediaRecorder(env, thiz, 0); ? ? ?if (mr != NULL) { ? ? ? ? ?mr->setListener(NULL); ? ? ? ? ?mr->release(); ? ? ?} ?} ? ?// This function gets some field IDs, which in turn causes class initialization. ?// It is called from a static block in MediaRecorder, which won't run until the ?// first time an instance of this class is used. ?static void ?android_media_MediaRecorder_native_init(JNIEnv *env) ?{ ? ? ?jclass clazz; ? ? ? ?clazz = env->FindClass("android/media/MediaRecorder"); ? ? ?if (clazz == NULL) { ? ? ? ? ?return; ? ? ?} ? ? ? ?fields.context = env->GetFieldID(clazz, "mNativeContext", "J"); ? ? ?if (fields.context == NULL) { ? ? ? ? ?return; ? ? ?} ? ? ? ?fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;"); ? ? ?if (fields.surface == NULL) { ? ? ? ? ?return; ? ? ?} ? ? ? ?jclass surface = env->FindClass("android/view/Surface"); ? ? ?if (surface == NULL) { ? ? ? ? ?return; ? ? ?} ? ? ? ?fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "(Ljava/lang/Object;IIILjava/lang/Object;)V"); ? ? ?if (fields.post_event == NULL) { ? ? ? ? ?return; ? ? ?} ? ? ? ?clazz = env->FindClass("java/util/ArrayList"); ? ? ?if (clazz == NULL) { ? ? ? ? ?return; ? ? ?} ? ? ?gArrayListFields.add = env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"); ? ? ?gArrayListFields.classId = static_cast<jclass>(env->NewGlobalRef(clazz)); ?} ? ? ?static void ?android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? jstring packageName, jstring opPackageName) ?{ ? ? ?ALOGV("setup"); ? ? ? ?ScopedUtfChars opPackageNameStr(env, opPackageName); ? ? ? ?sp<MediaRecorder> mr = new MediaRecorder(String16(opPackageNameStr.c_str())); ? ? ?if (mr == NULL) { ? ? ? ? ?jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); ? ? ? ? ?return; ? ? ?} ? ? ?if (mr->initCheck() != NO_ERROR) { ? ? ? ? ?jniThrowException(env, "java/lang/RuntimeException", "Unable to initialize media recorder"); ? ? ? ? ?return; ? ? ?} ? ? ? ?// create new listener and give it to MediaRecorder ? ? ?sp<JNIMediaRecorderListener> listener = new JNIMediaRecorderListener(env, thiz, weak_this); ? ? ?mr->setListener(listener); ? ? ? ?// Convert client name jstring to String16 ? ? ?const char16_t *rawClientName = reinterpret_cast<const char16_t*>( ? ? ? ? ?env->GetStringChars(packageName, NULL)); ? ? ?jsize rawClientNameLen = env->GetStringLength(packageName); ? ? ?String16 clientName(rawClientName, rawClientNameLen); ? ? ?env->ReleaseStringChars(packageName, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?reinterpret_cast<const jchar*>(rawClientName)); ? ? ? ?// pass client package name for permissions tracking ? ? ?mr->setClientName(clientName); ? ? ? ?setMediaRecorder(env, thiz, mr); ?} ? ?static void ?android_media_MediaRecorder_native_finalize(JNIEnv *env, jobject thiz) ?{ ? ? ?ALOGV("finalize"); ? ? ?android_media_MediaRecorder_release(env, thiz); ?} ? ? ?static void ?android_media_MediaRecorder_enableDeviceCallback(JNIEnv *env, jobject thiz, jboolean enabled) ?{ ? ? ?ALOGV("android_media_MediaRecorder_enableDeviceCallback %d", enabled); ? ? ? ?sp<MediaRecorder> mr = getMediaRecorder(env, thiz); ? ? ?if (mr == NULL) { ? ? ? ? ?jniThrowException(env, "java/lang/IllegalStateException", NULL); ? ? ? ? ?return; ? ? ?} ? ? ? ?process_media_recorder_call(env, mr->enableAudioDeviceCallback(enabled), ? ? ? ? ? ? ?"java/lang/RuntimeException", "enableDeviceCallback failed."); ?} ?
? ?static jint android_media_MediaRecord_getPortId(JNIEnv *env, ?jobject thiz) { ? ? ?sp<MediaRecorder> mr = getMediaRecorder(env, thiz); ? ? ?if (mr == NULL) { ? ? ? ? ?jniThrowException(env, "java/lang/IllegalStateException", NULL); ? ? ? ? ?return (jint)AUDIO_PORT_HANDLE_NONE; ? ? ?} ? ? ? ?audio_port_handle_t portId; ? ? ?process_media_recorder_call(env, mr->getPortId(&portId), ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"java/lang/RuntimeException", "getPortId failed."); ? ? ?return (jint)portId; ?} ? ?// ---------------------------------------------------------------------------- ? ?static const JNINativeMethod gMethods[] = { ? ? ?{"setParameter", ? ? ? ? "(Ljava/lang/String;)V", ? ? ? ? ? (void *)android_media_MediaRecorder_setParameter}, ? ? ?{"start", ? ? ? ? ? ? ? ?"()V", ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)android_media_MediaRecorder_start}, ? ? ?{"stop", ? ? ? ? ? ? ? ? "()V", ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)android_media_MediaRecorder_stop}, ? ? ?{"pause", ? ? ? ? ? ? ? ?"()V", ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)android_media_MediaRecorder_pause}, ? ? ?{"resume", ? ? ? ? ? ? ? "()V", ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)android_media_MediaRecorder_resume}, ? ? ?{"native_reset", ? ? ? ? "()V", ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)android_media_MediaRecorder_native_reset}, ? ? ?{"release", ? ? ? ? ? ? ?"()V", ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)android_media_MediaRecorder_release}, ? ? ?{"native_init", ? ? ? ? ?"()V", ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)android_media_MediaRecorder_native_init}, ? ? ?{"native_setup", ? ? ? ? "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V", ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(void *)android_media_MediaRecorder_native_setup}, ? ? ?{"native_finalize", ? ? ?"()V", ? ? ? ? ? ? ? ? ? ? ? ? ? ? (void *)android_media_MediaRecorder_native_finalize}, ? ? ?{"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface }, ? ?}; ? ?// This function only registers the native methods, and is called from ?// JNI_OnLoad in android_media_MediaPlayer.cpp ?int register_android_media_MediaRecorder(JNIEnv *env) ?{ ? ? ?return AndroidRuntime::registerNativeMethods(env, ? ? ? ? ? ? ? ? ?"android/media/MediaRecorder", gMethods, NELEM(gMethods)); ?} ?
/frameworks/base/media/jni/android_media_MediaPlayer.cpp extern int register_android_media_MediaRecorder(JNIEnv *env);
? jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) ? { ? ? ? JNIEnv* env = NULL; ? ? ? jint result = -1; ?? ? ? ? if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { ? ? ? ? ? ALOGE("ERROR: GetEnv failed\n"); ? ? ? ? ? goto bail; ? ? ? } ? ? ? assert(env != NULL); ... ?if (register_android_media_MediaRecorder(env) < 0) { ? ? ? ? ? ALOGE("ERROR: MediaRecorder native registration failed\n"); ? ? ? ? ? goto bail; ? ? ? }
|