Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

((Button)view) inside a service is not working

I am trying to create a button that allows me to record audio through a service, i want the button to have text: "Start Recording". On the OnClick event, i want the button text to change to: "Stop Recording".

I had this code working when it was in a class but now it is not working in a service, however, as I want the audio record to work as a service, I cannot seem to get the button's text to change. I am pretty new to coding so any help will be greatly appreciated!

My code is as follows:

Class:

public class Test extends AppCompatActivity {       

    public void Record(View view) {
        Intent intent = new Intent(this, RecordService.class);
        startService(intent);
    }    

    public void Play(View view) {
        Intent intent = new Intent(this, RecordService.class);
        stopService(intent);    
    }
}

Service:

import android.app.Service;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.IBinder;
import android.widget.Button;
import android.view.View;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class RecordService extends Service {

    MediaRecorder mRecorder;
    public static String audioFilePath;
    public boolean isRecording = false;

    public RecordService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public void onCreate () {

        if(mRecorder == null){

            SimpleDateFormat s = new SimpleDateFormat("ddMMyyyy_hhmmss");
            String format = s.format(new Date());

            audioFilePath = Environment.getExternalStorageDirectory().
                    getAbsolutePath() +  "/" + format + ".3gpp";

            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 Recording");
            }catch(Exception e){
                e.printStackTrace();
            }
        } else {
            try{
                startRecording();
                isRecording = true;
                ((Button)view).setText("Stop Recording");
            }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();
    }


    public void onStartCommand()
    {
        SimpleDateFormat s = new SimpleDateFormat("ddMMyyyy_hhmmss");
        String format = s.format(new Date());

        audioFilePath = Environment.getExternalStorageDirectory().
                getAbsolutePath() +  "/" + format + ".3gpp";

        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setOutputFile(audioFilePath);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        try {
            mRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mRecorder.start();

    }

    public void onDestroy()
    {
       super.onDestroy();
        mRecorder.stop();
        mRecorder.release();

    }


}

Activity:

<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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="kyr.com.knowyourrights.Test">

    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

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

</RelativeLayout>
like image 803
Viverson Avatar asked May 12 '16 11:05

Viverson


People also ask

Why my setOnClickListener is not working?

You need to put the setOnClickListener in one of the activity callbacks. In your onCreate() method, move the button there and then setOnClickListener() . Save this answer.

How to implement OnClickListener in java?

Link the button from the XML by calling findViewById() method and set the onClick listener by using setOnClickListener() method. setOnClickListener takes an OnClickListener object as the parameter. Basically it's creating an anonymous subclass OnClickListener in the parameter.

How to activate button in Android studio?

To define the click event handler for a button, add the android:onClick attribute to the <Button> element in your XML layout. The value for this attribute must be the name of the method you want to call in response to a click event. The Activity hosting the layout must then implement the corresponding method.

Which listener you can use when you Click a button?

The listener you need is called an OnClickListener (not an ActionListener or ButtonClickListener , etc.) You add the listener with the setOnClickListener method, and. You need to implement the onClick method.


2 Answers

This, indeed, can't work here since your ((Button) view) isn't instantiate in your onCreate().

What I suggest is to call, from the service, a function inside the Activity that performs what you want to do (here, change the text). You can achieve this using a BroadcastReceiver.

To do that, you can do the following :

Inside your Activity :

@Override
public void onResume() {
  super.onResume();

  // Register mMessageReceiver to receive messages.
  LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
      new IntentFilter("change-text"));
}

// handler for received Intents for the "change-text" event 
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    // Extract data included in the Intent
    String message = intent.getStringExtra("message");
    button.setText(message); //Assuming you have instantiate properly your button inside your onCreate()
  }
};

@Override
protected void onPause() {
  // Unregister since the activity is not visible
  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
  super.onPause();
} 

Inside your Service :

// Send an Intent with an action named "change-text". 
private void sendMessage(boolean startRecording) {
  Intent intent = new Intent("change-text");
  // add data
  if (startRecording) intent.putExtra("message", "Start Recording");
  else intent.putExtra("message","Stop Recording");
  LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
} 

To change the text button from your service, you will just have to call the sendMessage function with either true or false as parameter depending on what you want to do !

You can see the source of the code, which I adapted to your situation, here : http://www.vogella.com/tutorials/AndroidBroadcastReceiver/article.html#ownreceiver_localbroadcastmanager

like image 79
Xema Avatar answered Sep 30 '22 14:09

Xema


You want to call button in service, try to use BroadcastReceiver

like image 30
hoanngothanh Avatar answered Sep 30 '22 13:09

hoanngothanh