Android Open Source - AudioPlayerRecorder Audio Recorder Service






From Project

Back to project page AudioPlayerRecorder.

License

The source code is released under:

MIT License

If you think the Android project AudioPlayerRecorder listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.heavyplayer.audioplayerrecorder.service;
/* w ww . ja  v a 2  s .  c o m*/
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import com.heavyplayer.audioplayerrecorder.util.BuildUtils;
import com.heavyplayer.audioplayerrecorder.widget.AudioRecorderMicrophone;
import com.heavyplayer.audioplayerrecorder.widget.interface_.OnDetachListener;

public class AudioRecorderService extends Service implements AudioManager.OnAudioFocusChangeListener {
  public static final String LOG_TAG = AudioRecorderService.class.getSimpleName();

  private final static int UPDATE_INTERVAL_MS = 100;

  private final IBinder mBinder = new LocalBinder();

  private Handler mHandler;

  private AudioRecorderMicrophone mMicrophone;
  private MicrophoneAmplitudeUpdater mMicrophoneAmplitudeUpdater = new MicrophoneAmplitudeUpdater();

  private AudioRecorderStateListener mStateListener;

  private Long mTimeLimit;
  private TimeLimitStopper mTimeLimitStopper = new TimeLimitStopper();

  private Uri mFileUri;

  private MediaRecorder mRecorder;
  private boolean mIsRecording;

  @Override
  public void onCreate() {
    mHandler = new Handler();

    mIsRecording = false;

    if(BuildUtils.isDebug(this))
      Log.i(LOG_TAG, "Local service started");
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    // We want this service to continue running until it is explicitly stopped, so return sticky.
    return START_STICKY;
  }

  @SuppressLint("InlinedApi")
  protected void start(Uri fileUri) {
    // If the output file changes, we want to stop the current recording.
    if(mFileUri == null || !mFileUri.equals(fileUri)) {
      stop();
      mFileUri = fileUri;
    }

    if(!mIsRecording && mFileUri != null) {
      gainAudioFocus();

      if(mRecorder == null)
        mRecorder = new MediaRecorder();

      try {
        // Configure recorder.
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mRecorder.setOutputFile(mFileUri.getPath());
        mRecorder.setAudioEncoder(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD_MR1 ?
            MediaRecorder.AudioEncoder.AAC
            : 3); /* MediaRecorder.AudioEncoder.AAC was hidden in previous versions, but it's 3. */
        mRecorder.setAudioChannels(1);
        mRecorder.setAudioSamplingRate(22050);
        mRecorder.setAudioEncodingBitRate(65536);

        mRecorder.prepare();

        // Start recording.
        mRecorder.start();
        
        mIsRecording = true;

        scheduleTimeLimitStopper();

        updateMicrophoneState();

        startMicrophoneUpdater();

        if(mStateListener != null)
          mStateListener.onStartRecorder();
      }
      catch(Exception e) {
        Log.w(LOG_TAG, e);

        if(mStateListener != null)
          mStateListener.onStartRecorderFailed(e);
      }
    }
  }

  protected void stop() {
    if(mIsRecording) {
      if(mRecorder != null) {
        try {
          mRecorder.stop();
        }
        catch(Exception e) {
          // This can happen, for instance, when stop is called immediately after start.
          // We will act like if the stop was successful, since the recording is stopped nonetheless.
          Log.w(LOG_TAG, e);
        }

        mRecorder.reset();

        mIsRecording = false;

        removeTimeLimitStopper();

        updateMicrophoneState();

        if(mStateListener != null)
          mStateListener.onStopRecorder();
      }

      abandonAudioFocus();
    }
  }

  protected void destroy() {
    stop();

    if(mRecorder != null) {
      mRecorder.release();
      mRecorder = null;
    }
  }

  @Override
  public void onDestroy() {
    destroy();

    if(BuildUtils.isDebug(this))
      Log.i(LOG_TAG, "Local service stopped");
  }

  protected void gainAudioFocus() {
    final int durationHint;
    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
      durationHint = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT;
    else
      // Request audio focus for recording without being disturbed by system sounds.
      durationHint = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;

    final AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
    audioManager.requestAudioFocus(
        this,
        AudioManager.STREAM_MUSIC,
        durationHint);
  }

  protected void abandonAudioFocus() {
    // Abandon audio focus when the recording complete.
    final AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
    audioManager.abandonAudioFocus(this);
  }

  @Override
  public void onAudioFocusChange(int focusChange) {
    // Do nothing.
  }

  protected void scheduleTimeLimitStopper() {
    if(mTimeLimit != null)
      mHandler.postDelayed(mTimeLimitStopper, mTimeLimit);
  }

  protected void removeTimeLimitStopper() {
    mHandler.removeCallbacks(mTimeLimitStopper);
  }

  protected void updateMicrophoneState() {
    if(mMicrophone != null) {
      mMicrophone.setSelected(mIsRecording);

      if(!mIsRecording)
        mMicrophone.updateAmplitude(0, UPDATE_INTERVAL_MS * 3);
    }
  }

  protected void startMicrophoneUpdater() {
    // Star updating microphones amplitude.
    mHandler.removeCallbacks(mMicrophoneAmplitudeUpdater);
    mHandler.post(mMicrophoneAmplitudeUpdater);
  }

  private class MicrophoneAmplitudeUpdater implements Runnable {
    @Override
    public void run() {
      if(mIsRecording && mRecorder != null && mMicrophone != null) {
        final int amplitude = mRecorder.getMaxAmplitude();

        mMicrophone.updateAmplitude(amplitude, UPDATE_INTERVAL_MS);

        // Post animation runnable to update the animation.
        mHandler.postDelayed(mMicrophoneAmplitudeUpdater, UPDATE_INTERVAL_MS);
      }
    }
  }

  /**
   * Stops the recorder if the time limit is reached.
   */
  public class TimeLimitStopper implements Runnable {
    @Override
    public void run() {
      stop();

      if(mStateListener != null)
        mStateListener.onTimeLimitExceeded();
    }
  }

  @Override
  public IBinder onBind(Intent intent) {
    return mBinder;
  }

  public class LocalBinder extends Binder {
    public void register(AudioRecorderMicrophone microphone, AudioRecorderStateListener listener) {
      mMicrophone = microphone;
      mStateListener = listener;

      // Configure microphone state.
      microphone.setSelected(mIsRecording);

      microphone.setOnDetachListener(new OnDetachListener() {
        @Override
        public void onDetachedFromWindow(View v) {
          if(mMicrophone == v)
            mMicrophone = null;
        }

        @Override
        public void onStartTemporaryDetach(View v) { }
      });

      // Start microphone update.
      startMicrophoneUpdater();
    }

    /**
     * Time limit will apply the next time you call {@link #startRecorder(android.net.Uri)}.
     */
    public void setTimeLimit(long timeLimit) {
      mTimeLimit = timeLimit;
    }

    public void startRecorder(Uri fileUri) {
      start(fileUri);
    }

    public void stopRecorder() {
      stop();
    }

    public void destroyRecorder() {
      destroy();
    }

    public boolean isRecording() {
      return mIsRecording;
    }
  }

  public static interface AudioRecorderStateListener {
    public void onStartRecorder();
    public void onStartRecorderFailed(Exception e);
    public void onStopRecorder();
    public void onTimeLimitExceeded();
  }
}




Java Source Code List

com.heavyplayer.audioplayerrecorder.fragment.AudioRecorderFragment.java
com.heavyplayer.audioplayerrecorder.sample.activity.PlayerActivity.java
com.heavyplayer.audioplayerrecorder.sample.activity.RecorderActivity.java
com.heavyplayer.audioplayerrecorder.sample.obj.Item.java
com.heavyplayer.audioplayerrecorder.service.AudioPlayerService.java
com.heavyplayer.audioplayerrecorder.service.AudioRecorderService.java
com.heavyplayer.audioplayerrecorder.service.manager.AudioPlayerServiceManager.java
com.heavyplayer.audioplayerrecorder.service.manager.AudioRecorderServiceManager.java
com.heavyplayer.audioplayerrecorder.service.manager.ServiceManager.java
com.heavyplayer.audioplayerrecorder.util.AudioPlayerHandler.java
com.heavyplayer.audioplayerrecorder.util.BuildUtils.java
com.heavyplayer.audioplayerrecorder.util.SafeMediaPlayer.java
com.heavyplayer.audioplayerrecorder.utils.AudioUtils.java
com.heavyplayer.audioplayerrecorder.widget.AudioPlayerLayout.java
com.heavyplayer.audioplayerrecorder.widget.AudioRecorderMicrophone.java
com.heavyplayer.audioplayerrecorder.widget.PlayPauseImageButton.java
com.heavyplayer.audioplayerrecorder.widget.interface_.OnDetachListener.java