0

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)
Viverson
  • 85
  • 10

2 Answers2

0

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();
}
Titus
  • 22,031
  • 1
  • 23
  • 33
  • Hey I get this error when i run this code: Error:(75, 26) error: unreported exception IOException; must be caught or declared to be thrown @Titus – Viverson May 11 '16 at 11:30
  • It partially works! The issues I am still having are that when I get onto the relevant screen in my App the button starts with no text. Once I click the button it then says "Stop", when I click "Stop" it then says "start". If I click "start" again the app crashes. @Titus – Viverson May 11 '16 at 11:47
  • @Viverson You can add a `android:text="Start"` attribute in the xml file to the `@+id/RecordButton` button so it won't be empty. If you want to start recording more then once, in your `stopRecording()` method, you need to call `reset()` instead of `release()`. Keep in mind that you need to release the `MediaRecorder` when you're done with it (you won't call `start()` again). – Titus May 11 '16 at 11:56
  • Having a little bit of difficulty, so i replaced the reset() with a release() and I understand i need to make a new instance of MediaRecorder, so I thought I had to place MediaRecorder mrecorder = new MediaRecorder somewhere? And also have to put the function release() somewhere – Viverson May 12 '16 at 06:43
  • @Viverson If you want to reuse the `MediaRecorder` instance, just replace `mRecorder.release();` with `mRecorder.reset();` in the `stopRecording()`, if you don't want to reuse it, add `mRecorder = null;` at the end of the `stopRecording()` method and next time you press the button, a new instance will be created. – Titus May 12 '16 at 08:24
0

//Updated..

Let's fix this! So first you need to remove the android:onClick="RecordButton" from the Layout file and set Text as:

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

Then in your onCreate() do the changes like this.

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

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

    btnrecord.setOnClickListener(new EventHandler());
    btndrugslaw.setOnClickListener(new EventHandler());
    }



    private class EventHandler implements OnClickListener
        {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                switch(v.getId())
                {
                    case R.id.RecordButton:
                     if(btnrecord.getText().equalsIgnoreCase("Start Recording"))
                     {
            btnrecord.setText("Stop Recording");
    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();

                      }
              else{
               btnrecord.setText("Start Recording");
                 //code to stop the player
}                  
                    break;

                    case R.id.drugslaw:
                    Your action here...
                    break;
    }
}
Akshat Vajpayee
  • 274
  • 1
  • 3
  • 15