Android MediaRecorder не работает и аварийно завершает работу при методе stop()

Я изучаю разработку для Android и использую класс MediaRecorder для записи звука. И logcat говорит, что приложение падает в методе stop() и выдает IllegalStateException. Я не понимаю, почему он падает, и я вызываю метод stop перед запуском.

public class MainActivity extends AppCompatActivity {

private MediaRecorder grabacion;
private String archivoSalida = null;
private Button btn_recorder;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btn_recorder = (Button)findViewById(R.id.btn_rec);

    if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO,}, 1000);
    }
}

public void Recorder(View view){
    if (grabacion == null){
        archivoSalida = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Grabacion.mp3";
        grabacion = new MediaRecorder();
        grabacion.setAudioSource(MediaRecorder.AudioSource.MIC);
        grabacion.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        grabacion.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
        grabacion.setOutputFile(archivoSalida);

        try{
            grabacion.prepare();
            grabacion.start();
        } catch (IOException e){
        }

        btn_recorder.setBackgroundResource(R.drawable.rec);
        Toast.makeText(getApplicationContext(), "Grabando...", Toast.LENGTH_SHORT).show();
    } else if (grabacion != null){
        grabacion.stop();
        grabacion.release();
        grabacion = null;
        btn_recorder.setBackgroundResource(R.drawable.stop_rec);
        Toast.makeText(getApplicationContext(), "Grabación finalizada", Toast.LENGTH_SHORT).show();
    }
}

public void reproducir(View view) {

    MediaPlayer mediaPlayer = new MediaPlayer();
    try {
        mediaPlayer.setDataSource(archivoSalida);
        mediaPlayer.prepare();
    } catch (IOException e){
    }

    mediaPlayer.start();
    Toast.makeText(getApplicationContext(), "Reproduciendo audio", Toast.LENGTH_SHORT).show();
}}

Это файл манифеста:

<?xml version = "1.0" encoding = "utf-8"?>

<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name = "android.permission.RECORD_AUDIO"/>

<application
    android:allowBackup = "true"
    android:icon = "@mipmap/ic_launcher"
    android:label = "@string/app_name"
    android:roundIcon = "@mipmap/ic_launcher_round"
    android:supportsRtl = "true"
    android:theme = "@style/AppTheme">
    <activity android:name = ".MainActivity">
        <intent-filter>
            <action android:name = "android.intent.action.MAIN" />

            <category android:name = "android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
And what logcat says:
E/MediaRecorder: stop called in an invalid state: 4
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.recorder, PID: 5386
    java.lang.IllegalStateException: Could not execute method for android:onClick
        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414)
        at android.view.View.performClick(View.java:7870)
        at android.widget.TextView.performClick(TextView.java:14970)
        at android.view.View.performClickInternal(View.java:7839)
        at android.view.View.access$3600(View.java:886)
        at android.view.View$PerformClick.run(View.java:29363)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7948)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
        at android.view.View.performClick(View.java:7870) 
        at android.widget.TextView.performClick(TextView.java:14970) 
        at android.view.View.performClickInternal(View.java:7839) 
        at android.view.View.access$3600(View.java:886) 
        at android.view.View$PerformClick.run(View.java:29363) 
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:7948) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) 
     Caused by: java.lang.IllegalStateException
        at android.media.MediaRecorder._stop(Native Method)
        at android.media.MediaRecorder.stop(MediaRecorder.java:1440)
        at com.example.recorder.MainActivity.Recorder(MainActivity.java:55)
        at java.lang.reflect.Method.invoke(Native Method) 
        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409) 
        at android.view.View.performClick(View.java:7870) 
        at android.widget.TextView.performClick(TextView.java:14970) 
        at android.view.View.performClickInternal(View.java:7839) 
        at android.view.View.access$3600(View.java:886) 
        at android.view.View$PerformClick.run(View.java:29363) 
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:7948) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) 
I/Process: Sending signal. PID: 5386 SIG: 9

Спасибо!

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
1 773
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В документации для метода stop() указано, что он выдаст IllegalStateException

если он вызывается перед start()

Поскольку это, кажется, единственный раз, когда эта ошибка будет выброшена, это, скорее всего, то, что происходит и в вашем случае.

Взгляните на свой Recorder() метод. Единственный раз, когда stop() будет вызываться, это когда ваша переменная не равна нулю. Это означает, что ваш экземпляр был правильно инициализирован. Однако, поскольку возникает исключение, это означает, что даже если ваша переменная ссылается на экземпляр MediaRecorder, он не был запущен.

Чтобы узнать почему, взгляните на код, который должен запускать ваш MediaRecorder:

    try {
        grabacion.prepare();
        grabacion.start();
    } catch (IOException e){
    }

Хотя он находится внутри конструкции try-catch, блок catch на самом деле не содержит никакого кода, поэтому любые ошибки просто игнорируются. Следовательно, проблема, с которой вы столкнулись, является результатом того, что grabacion.prepare(); или grabacion.start(); не удается, что приводит к тому, что рекордер не запускается.

Учитывая, что start() выдает только IllegalStateException согласно документации , вызов prepare() должен быть причиной проблемы. Это также соответствует моему собственному опыту, так как при звонке prepare() многое может пойти не так. Вот что он делает на основе его описания в документации:

Подготавливает рекордер к началу захвата и кодирования данных. Этот метод должен вызываться после настройки желаемых аудио- и видеоисточников, кодировщиков, формата файла и т. д., но до start().

Так что, как вы понимаете, мне сейчас нелегко определить точную причину. Однако я могу добавить, что вы использовали Environment.getExternalStorageDirectory(), который устарел с API 29 для улучшения конфиденциальности пользователей. Хотя это может быть проблемой в вашем случае, я не могу подтвердить это с полной уверенностью.

Чтобы точно узнать, что вызывает ошибку, вы должны использовать этот IOException, который вы получаете в этом try-catch. Вы можете, например, зарегистрировать его трассировку стека, чтобы узнать больше о проблеме.

Вы были правы, я попробовал приложение на устройстве с Android 8 вместо 10, и оно отлично работает, поэтому я изменил метод .getExternalStorageDirectory() на другой, и теперь он работает на Android 8 и 10, спасибо. для вашей помощи

Matias Pardini 26.12.2020 02:08

Здорово, что в итоге получилось. Я рад, что смог помочь :).

Johannes Maagk 26.12.2020 12:31

Другие вопросы по теме