6

Briefly, I cannot get MediaRecorder#record to work on Android 7.1.1 emulator and don't understand why. Here are the further details:

Environment: Operating System: Mac OS X El Capitan version 10.11.6

IDE: AndroidStudio version 2.2.3

Problem: I have written a sample app to demonstrate the issue. This app consists of a button with an OnClickListener which will initialize and configure MediaRecorder instance, prepare and start recording. After enabling the RECORD_AUDIO permission in settings, the code below runs correctly on the Android 7.0 API 24 Emulator (x86_64 Graphics: Hardware) downloaded by and used by the AVD manager, but yields following error on Android 7.1.1 API 25 (with Google APIs) Emulator (x86_64 Graphics: Hardware):

Error only on Android 7.1.1 API 25 java.lang.RuntimeException: start failed. at android.media.MediaRecorder.start(Native Method)

Question Does anyone know what the issue is? Is there problem with my setup that does not cater for Android 7.1.1? This has been replicated on 2 Macs so far.

Code:

MainActivity.java:

package com.abstractx1.testrecord;

import android.media.MediaRecorder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

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

        Button recordButton = (Button) findViewById(R.id.recordButton);

        recordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String path = getFilesDir().getAbsolutePath() + "/" + "AudioRecording.3gp";

                MediaRecorder mediaRecorder = new MediaRecorder();
                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                mediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
                mediaRecorder.setOutputFile(path);

                try {
                    mediaRecorder.prepare();
                    mediaRecorder.start();
                } catch (Exception e) {
                    Log.e("DEBUG-MainActivity", "Error", e);
                    Log.e("DEBUG-MainActivity",     Log.getStackTraceString(e));
                }

                Toast.makeText(MainActivity.this, "Recording started", Toast.LENGTH_LONG).show();
            }
        });
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.abstractx1.testrecord.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

    <Button
        android:text="Record"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/recordButton" />
</RelativeLayout>

AndroidMainfest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.abstractx1.testrecord">

    <uses-feature
        android:name="android.hardware.microphone"
        android:required="false" />

    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        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>

</manifest>

Thank you, and I apologize in advance if this has been answered elsewhere. I have searched for few days without success. Also, if there is ambiguity/lack of information then I will expand and answer questions.

This is such a basic thing that I believe it must be an issue with the emulator.

Can someone please help me with this?

abstractx1
  • 435
  • 6
  • 17

2 Answers2

4

I have encounter similar issue due to not using Environment so media player can not find the path to use to store the audio hence it works on some devices and not in others: https://github.com/alkathirikhalid/android-uni-foundation

I have also reviewed your code I have detected possible errors or at least recommendations

  • File location / path, you should use Environment.getExternalStorageDirectory().getAbsolutePath()... Let the OS give you the location as different devices have different naming conventions
  • Uses feature required is false, then you should have checking to see if devices have mic or not before calling Media Player
  • Uses Permission Write External Storage You are intending to store the recorded audio to store and perhaps use it / play later
  • Finally The emulator is not supported as described in Android documentation "Note: Currently, Media Recorder does not work on the emulator." https://developer.android.com/reference/android/media/MediaRecorder.html

It is highly recommended to use actual devices when dealing with multimedia, locations and other device peripherals such as sensors.

Cheers.

alkathirikhalid
  • 887
  • 12
  • 18
  • Thanks for your answer. This was just a demo to highlight the issue I had found, and agree that in a real app, to check for mic etc. I also agree to test on physical devices but I am not in a position to buy a physical device that runs 7.1.1. With regards to the external storage however, by design and for security reasons I wish to use internal storage to save the recording. "Let the OS give you the location as different devices have different naming conventions" - Can you please explain (with documentation) how this affects the return of getFilesDir()? – abstractx1 Jan 24 '17 at 10:23
  • My answer was also a recommendation when dealing with multimedia it is best to store them on SD card as they consume much space, hence different devices have different naming conventions for external naming, Android does not enforce this hence use Environment. getFilesDir() is also correct, I will assume at this point you have a problem with the device, you will have to wait for official patch. http://stackoverflow.com/questions/21230629/getfilesdir-vs-environment-getdatadirectory – alkathirikhalid Jan 25 '17 at 01:33
1

MediaRecorder is not currently supported on the emulator. This is explicitly stated at the end of the introductory paragraph of the documentation. See the Android MediaRecorder documentation.

Hod
  • 2,236
  • 1
  • 14
  • 22