Android MediaRecorder.setAudioSource не удалось

У меня андроид G1 прошивка 1.6, я пытаюсь записать голос из приложения с помощью следующего кода.

MediaRecorder рекордер = новый MediaRecorder();
 recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
 recorder.setOutputFile(PATH_NAME);
 recorder.prepare();
 recorder.start();  

мой manifest.xml имеет:

<использует-разрешение android: name = "android.permission.RECORD_AUDIO" />

Я получил:

09-23 14: 41: 05.531: ОШИБКА /AndroidRuntime(1718): обработчик Uncaught: выход из основного потока из-за необработанного исключения
09-23 14:41:05.551: ОШИБКА /AndroidRuntime(1718): java.lang.RuntimeException: setAudioSource не удалось.
09-23 14:41:05.551: ОШИБКА /AndroidRuntime(1718): на android.media.MediaRecorder.setAudioSource(собственный метод)

как правильно записать голос?

18 ответов

Открыто "AndroidManifest.xml"->

добавлять

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

Я знаю, что это очень старый вопрос, но в Android Marshmallow вы должны зайти в "Настройки> Приложения> Ваше приложение> Разрешения" и включить разрешение "Микрофон".

Если вы работаете на Android M, вам нужно запросить разрешения на запись звука при первом запуске. Для этого спросите пользователя, можете ли вы записывать звук при запуске приложения:

private static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 29;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (mContext.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO},
                MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
    } else {
        Log.d("Home", "Already granted access");
        initializeView(v);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.d("Home", "Permission Granted");
                initializeView(v);
            } else {
                Log.d("Home", "Permission Failed");
                Toast.makeText(getActivity().getBaseContext(), "You must allow permission record audio to your mobile device.", Toast.LENGTH_SHORT).show();
                getActivity().finish();
            }
        }
        // Add additional cases for other permissions you may have asked for
    }
}

Для API 23+ проверьте разрешение аудиозаписи в файле Manifest.xml. <uses-permission android:name="android.permission.RECORD_AUDIO" /> и в коде Java

if (ActivityCompat.checkSelfPermission(cnt, Manifest.permission.RECORD_AUDIO)
            != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(cnt, arrayOf(
                Manifest.permission.RECORD_AUDIO
        ),0)
        return
    }

ВАЖНО - в течение последних нескольких часов я пытался выяснить, как проверить, перехватывается ли MIC другим приложением или нет. Я заметил, что если 2 приложения обращаются к MediaRecorder одновременно, RuntimeException будет брошено, и вы не сможете использовать микрофон, если не перезагрузите свое устройство (!!) Я не знаю, является ли это лучшим решением, но это сработало для меня. возможно, это сэкономит некоторым из вас несколько часов в один прекрасный день..

private void validateMicAvailability() throws MicUnaccessibleException {
    AudioRecord recorder =
        new AudioRecord(AudioSource.MIC, 44100,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_DEFAULT, 44100);
    try{
        if(recorder.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED ){
            throw new MicUnaccessibleException("Mic didn't successfully initialized");
        }

        recorder.startRecording();
        if(recorder.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING){
            recorder.stop();
            throw new MicUnaccessibleException("Mic is in use and can't be accessed");
        }
        recorder.stop();
    } finally{
        recorder.release();
        recorder = null;
    }
}

У меня была именно эта проблема, это решило ее для меня:

На устройстве, которое вы используете для отладки, перейдите в Настройки -> Приложения -> {ваше приложение}. Затем убедитесь, что все разрешения приложения (в этом случае запись звука и запись на внешнее хранилище) разрешены.

Обычно при установке приложения не через Google Play Store вас не просят предоставить разрешения, и на некоторых телефонах это приведет к тому, что ваше приложение отладки не получит некоторые разрешения.

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

Надеюсь это поможет.

Для API 23+ вам необходимо запросить разрешения на чтение / запись, даже если они уже есть в вашем манифесте.

// Check for permissions
int permission = ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);

// If we don't have permissions, ask user for permissions
if (permission != PackageManager.PERMISSION_GRANTED) {
    String[] PERMISSIONS_STORAGE = {
        android.Manifest.permission.READ_EXTERNAL_STORAGE,
        android.Manifest.permission.WRITE_EXTERNAL_STORAGE
    }; 
    int REQUEST_EXTERNAL_STORAGE = 1;

    ActivityCompat.requestPermissions(
        getActivity(),
        PERMISSIONS_STORAGE,
        REQUEST_EXTERNAL_STORAGE
    );
}

Пожалуйста запрос Manifest.permission.RECORD_AUDIO разрешение динамически для зефира и выше версии.

Это выглядит правильно. Убедитесь, что другие приложения еще не используют MIC. Возможно, перезагрузите телефон и попробуйте снова.

Этот код работал для меня

 mRecorder = new MediaRecorder();
 mRecorder.reset();
 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

Я перенес это в другую ветку. Все работает.

Вот код:

new Thread(() -> {
    mediaRecorder.reset();
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    mediaRecorder.setOutputFile("/audiorecordtest.3gp");
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        try {
            mediaRecorder.prepare();
            mediaRecorder.start();
            //do something here
            mediaRecorder.stop();
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("Audio","unable to prepare");
        }

}).start();

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

public class MainActivity extends Activity {

    MediaRecorder mRecorder;
    MediaPlayer mediaPlayer;
    Button start, stop, play,stop_play;
    String FileName="";
    File outfile ;

    public static final int request_code = 1000;

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


        start=(Button)findViewById(R.id.btn_start_main);
        stop=(Button)findViewById(R.id.btn_stop_main);
        play=(Button)findViewById(R.id.btn_play_main);
        stop_play=(Button)findViewById(R.id.btn_playstop_main);

        if (checkPermissionFromDevice()){

            start.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    FileName= Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+
                            UUID.randomUUID()+"AudioFile.3gp";

                    SetupMediaRecorder();

                    try {
                        mRecorder.prepare();
                        mRecorder.start();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    start.setEnabled(false);
                    stop.setEnabled(true);
                    play.setEnabled(false);
                    stop_play.setEnabled(false);

                    Toast.makeText(getApplicationContext(),"recording....",Toast.LENGTH_SHORT).show();
                }
            });
            stop.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mRecorder.stop();
                    play.setEnabled(true);
                    start.setEnabled(true);
                    stop.setEnabled(false);
                    stop_play.setEnabled(false);
                    Toast.makeText(getApplicationContext(),"recording stoped....",Toast.LENGTH_SHORT).show();
                }
            });
            play.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mediaPlayer=new MediaPlayer();
                    try {
                        mediaPlayer.setDataSource(FileName);
                        mediaPlayer.prepare();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mediaPlayer.start();
                    start.setEnabled(false);
                    stop.setEnabled(false);
                    play.setEnabled(false);
                    stop_play.setEnabled(true);
                    Toast.makeText(getApplicationContext(),"playing..",Toast.LENGTH_SHORT).show();
                }
            });
            stop_play.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mediaPlayer.stop();
                    SetupMediaRecorder();
                    start.setEnabled(true);
                    stop_play.setEnabled(false);
                    play.setEnabled(false);
                }
            });

        }
        else {

            requestPermissionFromDevice();
        }





    }

    private void SetupMediaRecorder() {
        mRecorder=new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mRecorder.setOutputFile(FileName);
    }

    private void requestPermissionFromDevice() {
        ActivityCompat.requestPermissions(this,new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO},
                request_code);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case request_code:
            {
                if (grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED ){
                    Toast.makeText(getApplicationContext(),"permission granted...",Toast.LENGTH_SHORT).show();
                }
                else {
                    Toast.makeText(getApplicationContext(),"permission denied...",Toast.LENGTH_SHORT).show();
                }
            }
                break;
        }
    }

    private boolean checkPermissionFromDevice() {
        int storage_permission= ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE);
        int recorder_permssion=ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO);
    return storage_permission == PackageManager.PERMISSION_GRANTED && recorder_permssion == PackageManager.PERMISSION_GRANTED;
    }
}

Как CyanogenMod-пользователь я должен был

  1. убедитесь, что разрешения определены в манифесте (android-studio)
  2. убедитесь, что сотрудник службы конфиденциальности разрешил приложению доступ к микрофону (на устройстве)
  3. убедитесь, что система Android установила разрешения под Settings -> Apps -> Выберите приложение -> Permissions -> Проверьте все разрешения (должны быть запрошены манифестом) (на устройстве)

После этого у меня сработало перекодирование.

это работает для меня: -

Запросить разрешение после setContentView (R.layout.activity_main)

val permissions = arrayOf(Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)ActivityCompat.requestPermissions(this, permissions,0)

Ответ "validateMicAvailability() вызывает MicUnaccessibleException" не работает для меня. Исключение MicUnaccessibleException, по-видимому, не существует. Я что-то неправильно понимаю?

Мое предложение может выглядеть глупо, но у меня это сработало:)

Попробуйте дать разрешение в виде вложенного тега. Я полагаю, что где-то есть проблема с синтаксическим анализом XML в библиотеке упаковки Android

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

  • в Настройки -> Приложения -> Выберите приложение -> Разрешения -> Проверьте все разрешения в

+ Изменить

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

в

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

Работал на меня.

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