0

I have been using this code for a while now before I got to find out that Stop recorderButton throws null exception when first clicked before startButton is clicked. I put the recorder in the PopupMenuWindow. So if I open the app and decide to click on stopRecording first, it will throw exception.

But if I click on startRecording first and then click stopRecorder everything works smooth.

This is my RecorderActivity.java

//Init View
        btnPlay = (Button)findViewById(R.id.btnPlay);
        btnStop = (Button) findViewById(R.id.btnStop);
        btnStartRecorder = (Button) findViewById(R.id.startRecord);
        btnStopRecorder = (Button) findViewById(R.id.stopRecord);
        //implementing the actions
        btnStartRecorder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (checkPermissionFromDevice())
                {


                    Intent i = new Intent(getApplicationContext(), MyService.class);
                    i.setAction("C.ACTION_START_SERVICE");
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        startForegroundService(i);
                    }
                    else
                    {
                        startService(i);

                    }

                    btnPlay.setEnabled(false);
                    btnStop.setEnabled(false);
                    btnStopRecorder.setEnabled(true);

                    Toast.makeText(RecorderActivity.this, "Recording...", Toast.LENGTH_SHORT).show();
                }

                else {
                    requestPermission();
                }

            }
        });

        btnStopRecorder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                MyService.mediaRecorder.stop();
                pathSave = MyService.pathSave;
                stopService(new Intent(RecorderActivity.this, MyService.class));
                btnStopRecorder.setEnabled(false);
                btnPlay.setEnabled(true);
                btnStartRecorder.setEnabled(true);
                btnStop.setEnabled(false);
                Toast.makeText(RecorderActivity.this, "Stop Record...", Toast.LENGTH_SHORT).show();
            }
        });

This is MyService.java for the recorder

public class MyService extends Service {
    static MediaRecorder mediaRecorder;
    static final int NOTIFICATION_ID = 543;
    static String pathSave = "";

    public MyService() {
    }

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

    @Override
    public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
            startMyOwnForeground();
        else
            startForeground(1, new Notification());

        pathSave = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/"
                + UUID.randomUUID().toString() + "_audio_record.amr";
        setupMediaRecorder(); // add this line in your service
        try {
            mediaRecorder.prepare();
            mediaRecorder.start();
            Toast.makeText(getApplicationContext(), "Recording...", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    @RequiresApi(Build.VERSION_CODES.O)
    private void startMyOwnForeground() {

        String NOTIFICATION_CHANNEL_ID = "example.permanence";
        String channelName = "Background Service";
        NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
        chan.setLightColor(Color.BLUE);
        chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);


        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        assert manager != null;
        manager.createNotificationChannel(chan);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
        Notification notification = notificationBuilder.setOngoing(true)
                .setContentTitle("App is running in background")
                .setPriority(NotificationManager.IMPORTANCE_MIN)
                .setCategory(Notification.CATEGORY_SERVICE)

                .build();
        startForeground(2, notification);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return START_STICKY;
        //return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    //add this function in your service
    private void setupMediaRecorder() {
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mediaRecorder.setOutputFile(pathSave);

    }

}
davidigbogree
  • 59
  • 1
  • 8

1 Answers1

0

When you click the stop button your MyService isn't running yet. So it is trying to stop something which doesn't exist.

Option 1: Disable the stop button until the service is started.

Option 2: Check if the service is running in your stop buttons onclick method. If running stop it, if not do nothing. Here is another answer which shows how to see if a service is running. How to check if a service is running on Android?

just_user
  • 11,769
  • 19
  • 90
  • 135
  • This shows that you understood my question correctly. If I place this android:enabled="false" in the xml button it works but the issue here is: If the app is recording and I close the popmenu to do play the activity i wish to record and then come back to the popmenu, the status of the button will change to disabled making it impossible for me to stop recorder. Except i touch start and then stop in a flash of second before the recording will finally stop. – davidigbogree Sep 18 '20 at 13:35
  • In this case what will i do? This will confuse the a new user that doesn't know what to do and the recorder will keep recording without the users knowledge. That is when i set android:enabled="true" so that I can get some workaround. Thanks for helping me. – davidigbogree Sep 18 '20 at 13:35
  • Another option to improve the user experience is to make your service a sticky service by adding a notification which is showing for the duration of the service running. Then they will always be able to see it, and if they have accidentally started it and then left your app the notification will still be there, and clicking it should bring them back to the start stop activity. – just_user Sep 21 '20 at 07:29