Viverson Viverson - 6 months ago 7
Java Question

Recording audio by an OnClick event in an if statement

I want to create a button that both starts recording audio and stops recording audio. I am trying to make the button change its text from "Start Recording" to "Stop Recording". However, I am unable to do this.

These are the following issues I have:

1) Not being able to get the xml onClick event to match to the related Class. However, when I highlight the RecordButton code in my class and go find usages it matches to the onClick event in the activity.

2) There is no text displayed on the button on my app

3) When I click the button my app crashes

Also I am very very new to coding.

My Class is as follows:

package kyr.com.knowyourrights;


import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.TextView;



import java.io.IOException;



public class Drugs extends AppCompatActivity {


WebView myBrowser;
MediaRecorder mRecorder;
private static String audioFilePath;
public boolean isRecording = false;


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



myBrowser = (WebView) findViewById(R.id.mybrowser);
myBrowser.loadUrl("file:///android_asset/drugs.html");
myBrowser.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);

Button btndrugslaw = (Button) findViewById(R.id.drugslaw);
Button btnrecord = (Button) findViewById(R.id.RecordButton);



btndrugslaw.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intentdruglaw = new Intent(Drugs.this, DrugLaw.class);
startActivity(intentdruglaw);
}
});}


public void RecordButton (View view) throws IOException {
TextView textView = (TextView) findViewById(R.id.RecordButton);
audioFilePath =
Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/myaudio.3gp";

mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(audioFilePath);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.start();

if (isRecording) {
stopRecording();
isRecording = false;
textView.setText("start");
} else {
startRecording();
isRecording = true;
textView.setText("stop");
}};

public void startRecording() {
mRecorder.start();
}


public void stopRecording() {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}}


my activity is as follows:

<ScrollView
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent">

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="kyr.com.knowyourrights.Drugs"
android:orientation="vertical"
>




<WebView
android:id="@+id/mybrowser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="false"
android:layout_alignParentStart="true"
android:layout_below="@+id/RecordButton"
>

</WebView>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/RecordButton"
android:onClick="RecordButton"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
/>


<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/drugslaw"
android:text="Take me to the law"
android:layout_below="@+id/mybrowser"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true" />

</RelativeLayout>


</ScrollView>


my log cat report:

05-11 23:18:31.893 29728-29728/? I/art﹕ Late-enabling -Xcheck:jni
05-11 23:18:32.051 29728-29746/kyr.com.knowyourrights D/OpenGLRenderer﹕ Use EGL_SWAP_BEHAVIOR_PRESERVED: true
05-11 23:18:32.059 29728-29728/kyr.com.knowyourrights D/Atlas﹕ Validating map...
05-11 23:18:32.116 29728-29746/kyr.com.knowyourrights I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build: Nondeterministic_AU_msm8974_LA.BF.1.1.1.C3__release_AU ()
OpenGL ES Shader Compiler Version: E031.25.03.06
Build Date: 04/27/15 Mon
Local Branch: mybranch9445032
Remote Branch: quic/LA.BF.1.1.1.c3_1
Local Patches: NONE
Reconstruct Branch: NOTHING
05-11 23:18:32.118 29728-29746/kyr.com.knowyourrights I/OpenGLRenderer﹕ Initialized EGL, version 1.4
05-11 23:18:32.143 29728-29746/kyr.com.knowyourrights D/OpenGLRenderer﹕ Enabling debug mode 0
05-11 23:18:32.237 29728-29728/kyr.com.knowyourrights I/Timeline﹕ Timeline: Activity_idle id: android.os.BinderProxy@1a037f4a time:44708449
05-11 23:18:40.297 29728-29728/kyr.com.knowyourrights I/Timeline﹕ Timeline: Activity_launch_request id:kyr.com.knowyourrights time:44716509
05-11 23:18:40.373 29728-29728/kyr.com.knowyourrights I/WebViewFactory﹕ Loading com.google.android.webview version 50.0.2661.86 (code 266108600)
05-11 23:18:40.392 29728-29728/kyr.com.knowyourrights I/cr_LibraryLoader﹕ Time to load native libraries: 1 ms (timestamps 6603-6604)
05-11 23:18:40.392 29728-29728/kyr.com.knowyourrights I/cr_LibraryLoader﹕ Expected native library version number "50.0.2661.86", actual native library version number "50.0.2661.86"
05-11 23:18:40.401 29728-29728/kyr.com.knowyourrights V/WebViewChromiumFactoryProvider﹕ Binding Chromium to main looper Looper (main, tid 1) {2db660c6}
05-11 23:18:40.401 29728-29728/kyr.com.knowyourrights I/cr_LibraryLoader﹕ Expected native library version number "50.0.2661.86", actual native library version number "50.0.2661.86"
05-11 23:18:40.401 29728-29728/kyr.com.knowyourrights I/chromium﹕ [INFO:library_loader_hooks.cc(143)] Chromium logging enabled: level = 0, default verbosity = 0
05-11 23:18:40.414 29728-29728/kyr.com.knowyourrights I/cr_BrowserStartup﹕ Initializing chromium process, singleProcess=true
05-11 23:18:40.420 29728-29728/kyr.com.knowyourrights E/ApkAssets﹕ Error while loading asset assets/natives_blob_64.bin: java.io.FileNotFoundException: assets/natives_blob_64.bin
05-11 23:18:40.420 29728-29728/kyr.com.knowyourrights E/ApkAssets﹕ Error while loading asset assets/snapshot_blob_64.bin: java.io.FileNotFoundException: assets/snapshot_blob_64.bin
05-11 23:18:40.466 29728-29833/kyr.com.knowyourrights W/cr_media﹕ Requires BLUETOOTH permission
05-11 23:18:40.471 29728-29728/kyr.com.knowyourrights I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.android.webview.chromium.WebViewContentsClientAdapter$WebResourceErrorImpl>
05-11 23:18:40.472 29728-29728/kyr.com.knowyourrights I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.android.webview.chromium.WebViewContentsClientAdapter$WebResourceErrorImpl>
05-11 23:18:40.507 29728-29728/kyr.com.knowyourrights I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<org.chromium.content.browser.FloatingWebActionModeCallback>
05-11 23:18:40.507 29728-29728/kyr.com.knowyourrights I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<org.chromium.content.browser.FloatingWebActionModeCallback>
05-11 23:18:40.523 29728-29728/kyr.com.knowyourrights D/cr_Ime﹕ [InputMethodManagerWrapper.java:30] Constructor
05-11 23:18:40.530 29728-29728/kyr.com.knowyourrights W/cr_AwContents﹕ onDetachedFromWindow called when already detached. Ignoring
05-11 23:18:40.531 29728-29728/kyr.com.knowyourrights D/cr_Ime﹕ [InputMethodManagerWrapper.java:59] isActive: false
05-11 23:18:40.543 29728-29728/kyr.com.knowyourrights I/cr_Ime﹕ ImeThread is not enabled.
05-11 23:18:40.576 29728-29843/kyr.com.knowyourrights E/libEGL﹕ validate_display:255 error 3008 (EGL_BAD_DISPLAY)
05-11 23:18:40.622 29728-29746/kyr.com.knowyourrights D/OpenGLRenderer﹕ endAllStagingAnimators on 0xb499db80 (RippleDrawable) with handle 0xae82c9c0
05-11 23:18:40.636 29728-29728/kyr.com.knowyourrights W/cr_BindingManager﹕ Cannot call determinedVisibility() - never saw a connection for the pid: 29728
05-11 23:18:40.637 29728-29728/kyr.com.knowyourrights D/cr_Ime﹕ [InputMethodManagerWrapper.java:59] isActive: true
05-11 23:18:40.637 29728-29728/kyr.com.knowyourrights D/cr_Ime﹕ [InputMethodManagerWrapper.java:68] hideSoftInputFromWindow
05-11 23:18:40.640 29728-29728/kyr.com.knowyourrights I/Timeline﹕ Timeline: Activity_idle id: android.os.BinderProxy@3ba92c8b time:44716852
05-11 23:18:44.165 29728-29728/kyr.com.knowyourrights E/MediaRecorder﹕ start called in an invalid state: 4
05-11 23:18:44.166 29728-29728/kyr.com.knowyourrights D/AndroidRuntime﹕ Shutting down VM
05-11 23:18:44.167 29728-29728/kyr.com.knowyourrights E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: kyr.com.knowyourrights, PID: 29728
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View$1.onClick(View.java:4029)
at android.view.View.performClick(View.java:4789)
at android.view.View$PerformClick.run(View.java:19881)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5294)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View$1.onClick(View.java:4024)
            at android.view.View.performClick(View.java:4789)
            at android.view.View$PerformClick.run(View.java:19881)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5294)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
Caused by: java.lang.IllegalStateException
at android.media.MediaRecorder.start(Native Method)
at kyr.com.knowyourrights.Drugs.RecordButton(Drugs.java:64)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at android.view.View$1.onClick(View.java:4024)
            at android.view.View.performClick(View.java:4789)
            at android.view.View$PerformClick.run(View.java:19881)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5294)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

Answer

You're creating a new MediaRecorder every time the R.id.RecordButton button is clicked which means that after you start recording, when you press stop, you're trying to stop a MediaRecorder which was never started (the newly created one).

Also, you have to call prepare() before start() and R.id.RecordButton is a Button not a TextView.

Try this:

public void RecordButton (View view) {
    if(mRecorder == null){
        audioFilePath = Environment.getExternalStorageDirectory().getAbsolutePath()
                    + "/myaudio.3gp";
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setOutputFile(audioFilePath);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);    
    }
    if (isRecording) {
        try{
            stopRecording();
            isRecording = false;
            ((Button)view).setText("start");
        }catch(Exception e){
           e.printStackTrace();
        }
    } else {
        try{
            startRecording();
            isRecording = true;
            ((Button)view).setText("stop");
        }catch(Exception e){
           e.printStackTrace();
        }
    }
}

public void startRecording() throws IllegalStateException, IOException{
    mRecorder.prepare();
    mRecorder.start();
}
public void stopRecording() throws IllegalStateException, IOException{
    mRecorder.stop();
    mRecorder.release();
}