首页 > 解决方案 > IllegalStateException: play() 在未初始化的 AudioTrack 上调用

问题描述

每次我尝试单击开始按钮时,我的应用程序都会崩溃。我收到“在未初始化的 AudioTrack 上调用的 play()”,但 audioTrack 已初始化。我已经尝试过其他解决方案,但我似乎无法找到自己的解决方案。

完整的堆栈跟踪

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)

主要活动:

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

活动主:

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

安卓清单:

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

找不到问题所在。

标签: javaandroidandroid-audiorecord

解决方案


推荐阅读