android - 没有 API < 26 的虚拟方法 MediaRecorder.setOutputFile?

标签 android audio mediarecorder nosuchmethoderror

我正在我的应用程序中录制音频,但我正在努力处理 MediaRecorder 类

import android.media.MediaRecorder;

问题是代码编译但似乎无法在 API 级别 < 26 的设备上运行,因为根据Android Studio 中的内联错误消息。同样,当我在具有 API 24 的模拟器上运行代码时,我遇到了运行时错误崩溃:

java.lang.NoSuchMethodError: No virtual method setOutputFile(Ljava/io/File;)V in class Landroid/media/MediaRecorder; or its super classes (declaration of 'android.media.MediaRecorder' appears in /system/framework/framework.jar)

作为快速修复,我只是将 gradle 文件中的最低 SDK 级别提高到 26,一切正常。但是,我不希望我的应用仅限于 Android 8.0 及更高版本,因为 7.x 仍然很受欢迎。

所以我的第一个问题是:怎么可能整个MediaRecorder库只有一个函数不可用,人们是怎么使用MediaRecorder 在 API 26 之前?我在网上找不到任何相关信息。

第二个问题:如何解决这个问题,以便我可以为 API 级别 24+ 录制音频?我必须使用其他库吗?

这是我的 Activity 的一部分,我正在其中设置记录器并开始记录。同样,当最小 SDK 为 26 时,这可以正常工作...

private MediaRecorder recorder;

private void startRecording(){
    if(!recordingActive) {
        recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setAudioChannels(1);
        recorder.setOutputFormat(output_formats[currentFormat]);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        switch(activeAudioButton) {
            case AUDIO_BUTTON_A:
                recorder.setOutputFile(tempSoundFileA); // <-- 
                break;
            case AUDIO_BUTTON_B:
                recorder.setOutputFile(tempSoundFileB); // <-- 
                break;
        }
        recorder.setOnErrorListener(errorListener);
        recorder.setOnInfoListener(infoListener);
        try {
            recorder.prepare();
            recorder.start();
            recordingActive = true;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    speakNowTextView.setVisibility(View.VISIBLE);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这是我的 gradle 文件:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.my.app"
        minSdkVersion 24
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:support-v4:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support:preference-v7:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
}

最佳答案

当使用低于 26 的 API 级别时,您可以传入包含文件路径的字符串。如果您特别需要使用 File 对象,请在 Java 中使用 file.getAbsolutePath() 或在 Kotlin 中使用 file.absolutePath

关于android - 没有 API < 26 的虚拟方法 MediaRecorder.setOutputFile?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52864868/

相关文章:

java - 如何从 android Surfaceview 中的视频获取当前帧?

启用 proguard 的 Android 单元测试

android - 带有wma编解码器的Android Mediaplayer广播流

delphi - 如何使用 Lazarus 在 WinCE 中从麦克风录音并保存为 WAV 文件?

Android - 记录时检查文件大小

android - 如何 append 到 Android MediaRecorder 输出文件

android - Android DNS 需要预热吗?

android - 迁移到Androidx问题。多个具有 “duplicate value for resource”问题的第三方库

java - 已编译.Jar Crashes(无Java控制台),但在Eclipse中编译并运行?

android - 调用 AudioRecord.start() 时出现 IllegalStateException