1

My app is crashing every time I try to click the start button. I am getting the "play() called on uninitialized AudioTrack" but the audioTrack is initialized. I've tried other solutions to the problem but I can't seem to find my own solution.

Complete stack trace:

FATAL EXCEPTION: main
Process: com.example.recorder, PID: 5010
java.lang.IllegalStateException: Could not execute method for android:onClick
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
    at android.view.View.performClick(View.java:6600)
    at android.view.View.performClickInternal(View.java:6577)
    at android.view.View.access$3100(View.java:781)
    at android.view.View$PerformClick.run(View.java:25912)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6923)
    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:870)
 Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
    at android.view.View.performClick(View.java:6600) 
    at android.view.View.performClickInternal(View.java:6577) 
    at android.view.View.access$3100(View.java:781) 
    at android.view.View$PerformClick.run(View.java:25912) 
    at android.os.Handler.handleCallback(Handler.java:873) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:193) 
    at android.app.ActivityThread.main(ActivityThread.java:6923) 
    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:870) 
 Caused by: java.lang.IllegalStateException: play() called on uninitialized AudioTrack.
    at android.media.AudioTrack.play(AudioTrack.java:2074)
    at com.example.recorder.MainActivity.start(MainActivity.java:93)
    at com.example.recorder.MainActivity.requestAudioPermissions(MainActivity.java:152)
    at com.example.recorder.MainActivity.startRecording(MainActivity.java:49)

MainActivity:

private int freq =44100;//frequencia de amostragem
private AudioRecord audioRecord = null;//variavel para gravação
private Thread Rthread = null;

//private AudioManager audioManager=null;
private AudioTrack audioTrack=null;//variavel para play
//byte[] buffer = new byte[freq];
public static final String LOG_TAG = "YOUR-TAG-NAME";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
//função com chamada as permissões nescessárias para captação e execução de áudio pelo celular
public void startRecording(View view) {
    requestAudioPermissions();
}    
protected void start() {
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

        final int bufferSizeIn = AudioRecord.getMinBufferSize(freq,   //buffer
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT);

        final int bufferSizeOut = AudioTrack.getMinBufferSize(freq,   //buffer
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT);

        //configurando as variaveis que serão utilizadas para captação e reprodução do áudio
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, freq,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT, bufferSizeIn);

        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, freq,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT, bufferSizeOut,
                AudioTrack.MODE_STATIC);

        //audioTrack.setPlaybackRate(freq);
        final byte[] bufferIn = new byte[bufferSizeIn];
        final byte[] bufferOut = new byte[bufferSizeOut];
        audioRecord.startRecording(); //começa a captar a voz
        Log.i(LOG_TAG, "Audio Recording started");
        audioTrack.play(); //começa a transmitir a voz
        Log.i(LOG_TAG, "Audio Playing started");
        Rthread = new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        audioRecord.read(bufferIn, 0, bufferSizeIn);

                        audioTrack.write(bufferOut, 0, bufferSizeOut);

                    } catch (Throwable t) {
                        Log.e("Error", "Read write failed");
                        t.printStackTrace();
                    }
                }
            }
        });
        Rthread.start();
    }

    public void stopRecording(View view) {
        if(audioRecord!=null){
            audioRecord.stop();
        }
    }
    //Requesting run-time permissions

    //Create placeholder for user's consent to record_audio permission.
    //This will be used in handling callback
    private final int MY_PERMISSIONS_RECORD_AUDIO = 1;

    private void requestAudioPermissions() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.RECORD_AUDIO)
                != PackageManager.PERMISSION_GRANTED) {

            //When permission is not granted by user, show them message why this permission is needed.
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.RECORD_AUDIO)) {
                Toast.makeText(this, "Please grant permissions to record audio", Toast.LENGTH_LONG).show();

                //Give user option to still opt-in the permissions
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.RECORD_AUDIO},
                        MY_PERMISSIONS_RECORD_AUDIO);

            } else {
                // Show user dialog to grant permission to record audio
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.RECORD_AUDIO},
                        MY_PERMISSIONS_RECORD_AUDIO);
            }
        }
        //If permission is granted, then go ahead recording audio
        else if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.RECORD_AUDIO)
                == PackageManager.PERMISSION_GRANTED) {

            //Go ahead with recording audio now
            start();
        }
    }

    //Handling callback
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_RECORD_AUDIO: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // permission was granted, yay!
                    start();
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(this, "Permissions Denied to record audio", Toast.LENGTH_LONG).show();
                }
                return;
            }
        }
    }

activity_main:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Aperte Start para começar"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintHorizontal_bias="0.503"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.274" />

<Button
    android:id="@+id/btnStart"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="116dp"
    android:layout_marginLeft="116dp"
    android:layout_marginTop="188dp"
    android:layout_marginEnd="8dp"
    android:layout_marginRight="116dp"
    android:onClick="startRecording"
    android:text="Start"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/btnStop"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="116dp"
    android:layout_marginTop="28dp"
    android:layout_marginEnd="116dp"
    android:layout_marginRight="116dp"
    android:onClick="stopRecording"
    android:text="Stop"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="1.0"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/btnStart" />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_begin="20dp" />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_begin="20dp" />

<androidx.constraintlayout.widget.Barrier
    android:id="@+id/barrier"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:barrierDirection="top" />

AndroidManifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.recorder">

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

<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>

Can't find what is wrong.

Denis Zavedeev
  • 7,627
  • 4
  • 32
  • 53
  • 1
    Try using `setOnClickListener` in your `MainActivity` class. – Axiumin_ Aug 12 '19 at 16:26
  • Take a look here: https://stackoverflow.com/questions/11298949/audiotrack-play-called-on-uninitialized-audiotrack – Gaurav Mall Aug 12 '19 at 16:27
  • When you call the start method, play() is called on an uninitialized AudioTrack. – Fernando Barbosa Aug 12 '19 at 16:36
  • 1
    If using `MODE_STATIC` you need to first `write` the audio data to the hardware before playback. See this answer for example: https://stackoverflow.com/a/21043290/2711811. Since you are reading/writing in launched thread you'll need to coordinate the thread with the play call. –  Aug 12 '19 at 16:47
  • 2
    Note also the last exception listed in an exception chain is usually the most interesting - which leads to the AudioTrack play error. –  Aug 12 '19 at 16:55
  • thanks i've change to MODE_STREAM and now is working good. – Sarah Sales Aug 12 '19 at 17:10
  • @niks: Every one of your edits has to be reviewed by at least two reviewers. Please restrict yourself to making **significant** edits and not minor ones like this. Thank you. – President James K. Polk Aug 12 '19 at 20:23
  • @JamesKPolk Thanks for letting me know. I am new and I agree it was minor but should I just ignore it in such cases? – niks Aug 13 '19 at 08:29
  • 1
    @niks: For edits that minor, yes. Once you get a high enough score your edits don't have to be reviewed and then you should feel free to make even minor improvements. – President James K. Polk Aug 13 '19 at 11:53
  • Seems one of you guys found a solution, it would be better if you write it here, so more people can get help from this question. @SarahSales – Ricardo A. Oct 29 '19 at 17:53

0 Answers0