Приложение вылетает при попытке записать звук

Я пытаюсь создать простое приложение, которое записывает звук, пока нажата кнопка, а затем сохраняет записанный файл в определенном месте. Это код, который у меня есть до сих пор, и он падает, как только я касаюсь кнопки изображения:

package com.whizzappseasyvoicenotepad;

import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;

public class MainActivity extends Activity {

MediaRecorder recorder;
String storagePath;
String externalStoragePath;

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

    //AUDIO RECORDER
    recorder = new MediaRecorder();
    recorder.reset();       
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
    {
        externalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
        recorder.setOutputFile(externalStoragePath + "/easyvoicenotepad/test.3gp");
    }
    else
    {
        storagePath = Environment.getDataDirectory().getAbsolutePath();
        recorder.setOutputFile(storagePath + "/easyvoicenotepad/test.3gp");
    }

    //IMAGE BUTTON ONTOUCHLISTENER
    final ImageButton recBtn = (ImageButton) findViewById(R.id.recButton);
    recBtn.setOnTouchListener(new OnTouchListener(){

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            if (event.getAction() == MotionEvent.ACTION_DOWN)
            {
                recBtn.setImageResource(R.drawable.record_btn_pressed);
                try {
                    recorder.prepare();
                    recorder.start();
                } catch (IllegalStateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else if (event.getAction() == MotionEvent.ACTION_UP)
            {
                recBtn.setImageResource(R.drawable.record_btn);
                try {
                    recorder.prepare();
                    recorder.stop();
                    recorder.reset();
                    recorder.release();
                    recorder = null;
                } catch (IllegalStateException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Log.i(STORAGE_SERVICE, "File saved to: " + externalStoragePath + "/easyvoicenotepad/test.3gp");
            }
            return true;
        }

    });
} //END OF ONCREATE

public void playTest(View v){

}

/*@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}*/

}

Разрешения:

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

Логкат-файл:

07-30 23:37:25.175: E/MediaRecorder(26382): start called in an invalid state: 4
07-30 23:37:25.175: E/InputEventReceiver(26382): Exception dispatching input event.
07-30 23:37:25.175: E/MessageQueue-JNI(26382): Exception in MessageQueue callback: handleReceiveCallback
07-30 23:37:25.183: E/MessageQueue-JNI(26382): java.lang.IllegalStateException
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.media.MediaRecorder.start(Native Method)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at com.whizzappseasyvoicenotepad.MainActivity$1.onTouch(MainActivity.java:49)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.View.dispatchTouchEvent(View.java:7379)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1910)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1910)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1910)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1910)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1966)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1418)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.app.Activity.dispatchTouchEvent(Activity.java:2424)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1914)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.View.dispatchPointerEvent(View.java:7564)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3883)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3778)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3483)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3540)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5419)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5399)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5370)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5493)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:182)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.os.MessageQueue.nativePollOnce(Native Method)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.os.MessageQueue.next(MessageQueue.java:132)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.os.Looper.loop(Looper.java:124)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at android.app.ActivityThread.main(ActivityThread.java:5103)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at java.lang.reflect.Method.invokeNative(Native Method)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at java.lang.reflect.Method.invoke(Method.java:525)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-30 23:37:25.183: E/MessageQueue-JNI(26382):  at dalvik.system.NativeStart.main(Native Method)
07-30 23:37:25.191: E/AndroidRuntime(26382): FATAL EXCEPTION: main
07-30 23:37:25.191: E/AndroidRuntime(26382): java.lang.IllegalStateException
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.media.MediaRecorder.start(Native Method)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at com.whizzappseasyvoicenotepad.MainActivity$1.onTouch(MainActivity.java:49)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.View.dispatchTouchEvent(View.java:7379)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1910)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1910)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1910)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1910)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1966)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1418)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.app.Activity.dispatchTouchEvent(Activity.java:2424)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1914)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.View.dispatchPointerEvent(View.java:7564)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3883)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3778)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3483)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3540)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3429)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3398)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3406)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3379)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5419)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5399)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5370)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5493)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:182)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.os.MessageQueue.nativePollOnce(Native Method)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.os.MessageQueue.next(MessageQueue.java:132)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.os.Looper.loop(Looper.java:124)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at android.app.ActivityThread.main(ActivityThread.java:5103)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at java.lang.reflect.Method.invokeNative(Native Method)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at java.lang.reflect.Method.invoke(Method.java:525)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-30 23:37:25.191: E/AndroidRuntime(26382):    at dalvik.system.NativeStart.main(Native Method)

person Guy    schedule 30.07.2013    source источник


Ответы (2)


Ваш выходной файл неполный

if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
    String externalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
    recorder.setOutputFile(externalStoragePath + "/easyvoicenotepad/test.3gp");
}
person Hoan Nguyen    schedule 30.07.2013
comment
после рекордера.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); Вы должны реализовать else для обработки случая, когда внешнее хранилище не подключено. Для многих телефонов, когда USB подключен к ПК, внешнее хранилище недоступно. - person Hoan Nguyen; 31.07.2013
comment
Проверьте мой отредактированный код, пожалуйста. Я все еще получаю сообщение об ошибке. Сейчас немного лучше. Приложение теперь вылетает, когда я перестаю касаться кнопки, но все равно вылетает - person Guy; 31.07.2013
comment
Теперь это работает, приложение больше не падает, но я не могу найти файл после того, как остановил запись, если у вас есть идеи, почему, пожалуйста, дайте мне знать - person Guy; 31.07.2013
comment
Вы можете указать полный путь externalStoragePath + /easyvoicenotepad/test.3gp, а затем найти его. - person Hoan Nguyen; 31.07.2013
comment
У меня нет внешнего хранилища, поэтому мне придется использовать обычное хранилище, но я буквально обыскал весь каталог и каждую подпапку, но не могу его найти. - person Guy; 31.07.2013
comment
Вам не нужно иметь SD-карту, чтобы иметь внешнее хранилище. Я забыл, где они находятся, так как теперь я использую каталог кеша, чтобы при удалении приложения файлы удалялись. Если вы используете String externalStoragePath = externalStorage.getAbsolutePath(); вы найдете файл в Android --> Имя вашего пакета --> Cache. Вы должны запустить свое приложение с подключенным USB-кабелем, чтобы получить самую новую версию, затем отключить его, очистить данные и запустить снова. - person Hoan Nguyen; 31.07.2013
comment
Хорошо, я думаю, что нашел проблему, я зарегистрировал ее, и она говорит, что она сохранена в «null/easyvoicenotepad/test.3gp», есть идеи, почему это происходит? - person Guy; 31.07.2013
comment
Это из "если" или "иначе"? В любом случае, если вы последуете моему комментарию выше, у вас не будет проблем. - person Hoan Nguyen; 31.07.2013
comment
только что нашел это из if, я добавил Log.i(STORAGE_SERVICE, externalStoragePath + /easyvoicenotepad/test.3gp); в код, и теперь он говорит, что элемент сохранен в /storage/emulated/0/easyvoicenotepad/test.3gp, но я также не могу найти это, я также не могу найти его по имени вашего пакета --> кешировать как указано в вашем комментарии - person Guy; 31.07.2013
comment
Я не использую эмулятор, поэтому я не знаю, где он находится в эмуляторе, измените свое хранилище на getExternalCacheDir().getAbsolutePath(); вместо Environment.getExternalStorageDirectory().getAbsolutePath(); - person Hoan Nguyen; 31.07.2013
comment
Я тоже не использую эмулятор, так почему это происходит? Кроме того, для меня нет опции getExternalCacheDir - person Guy; 31.07.2013
comment
давайте продолжим обсуждение в чате - person Hoan Nguyen; 31.07.2013

Если вы считаете, что MediaRecorder не должен быть окончательным, настройте его как глобальную переменную.

public class MainActivity extends Activity {
MediaRecorder recorder;

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

    //AUDIO RECORDER
    recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    recorder.setOutputFile("/easyvoicenotepad/test.3gp");
person Hadriel    schedule 30.07.2013
comment
Я думаю, это не проблема :/ Я сделал, но это все еще не работает - person Guy; 31.07.2013
comment
Вы уверены, что функция recorder.prepare() была вызвана раньше, чем функция recorder.start()? - person Hadriel; 31.07.2013