Android Open Source - tunnel_player_workaround Media Player Local Service






From Project

Back to project page tunnel_player_workaround.

License

The source code is released under:

This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a co...

If you think the Android project tunnel_player_workaround 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.h6ah4i.android.music_player;
/*from  w w w  .  j a  v  a  2  s  . c  om*/
import java.io.IOException;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;

import com.h6ah4i.android.example.tunnelplayerworkaround.BuildConfig;
import com.h6ah4i.android.example.tunnelplayerworkaround.MainActivity;
import com.h6ah4i.android.example.tunnelplayerworkaround.R;
import com.h6ah4i.android.utils.LocalServiceBinder;

public class MediaPlayerLocalService extends Service {
    // inner-classes
    public static class LocalBinder extends
            LocalServiceBinder<MediaPlayerLocalService> {
        public LocalBinder(MediaPlayerLocalService service) {
            super(service);
        }
    }

    // interfaces
    public static interface MediaPlayerLocalServiceEventListener {
        void onMediaCompletion(MediaPlayerLocalService mps);

        void onMediaPause(MediaPlayerLocalService mps);

        void onMediaPrepared(MediaPlayerLocalService mps);

        void onMediaResume(MediaPlayerLocalService mps);

        void onMediaStart(MediaPlayerLocalService mps);

        void onMediaStop(MediaPlayerLocalService mps);
    }

    private static final class MediaPlayerLocalServiceNullEventListener
            implements MediaPlayerLocalServiceEventListener {

        @Override
        public void onMediaCompletion(MediaPlayerLocalService mps) {
        }

        @Override
        public void onMediaPause(MediaPlayerLocalService mps) {
        }

        @Override
        public void onMediaPrepared(MediaPlayerLocalService mps) {
        }

        @Override
        public void onMediaResume(MediaPlayerLocalService mps) {
        }

        @Override
        public void onMediaStart(MediaPlayerLocalService mps) {
        }

        @Override
        public void onMediaStop(MediaPlayerLocalService mps) {
        }
    }

    // constants
    private static final String TAG = MediaPlayerLocalService.class.getSimpleName();

    private static final int ONGOING_NOTIFICATION = 1;
    private static final boolean mIsDebuggable = BuildConfig.DEBUG;

    // binder object
    private final IBinder mBinder = new LocalBinder(this);

    // fields
    private MediaPlayer mSilentPlayer;
    private MediaPlayer mPlayer;
    private boolean mIsPlayerPrepared;

    private MediaPlayerLocalServiceEventListener mListener;

    // listener objects
    private final OnCompletionListener mOnCompletionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            onMediaStop();
            onMediaCompletion();
        }
    };

    private final OnPreparedListener mOnPreparedListener = new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.setLooping(false);

            mIsPlayerPrepared = true;

            onMediaPrepared();

            try {
                mp.start();
                onMediaStart();
            } catch (IllegalStateException ex) {
                Log.e(TAG, "onMediaPrepared", ex);
            }
        }
    };

    public MediaPlayerLocalService() {
        mListener = new MediaPlayerLocalServiceNullEventListener();
    }

    @Override
    public void onCreate() {
        if (mIsDebuggable) {
            Log.d(TAG, "onCreate");
        }

        super.onCreate();

        // create a silent media player to avoid
        // tunnel player's side effect
        mSilentPlayer = createSilentMediaPlayer();

        // create an another media player for normal
        // audio playback
        mPlayer = createMediaPlayer();
    }

    @Override
    public void onDestroy() {
        if (mIsDebuggable) {
            Log.d(TAG, "onDestroy");
        }

        stopInternal();

        safeReleaseMediaPlayer(mPlayer);
        mPlayer = null;
        safeReleaseMediaPlayer(mSilentPlayer);
        mSilentPlayer = null;

        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (mIsDebuggable) {
            Log.d(TAG, "onStartCommand");
        }
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        if (mIsDebuggable) {
            Log.d(TAG, "onBind");
        }
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        if (mIsDebuggable) {
            Log.d(TAG, "onUnbind");
        }
        return super.onUnbind(intent);
    }

    @Override
    public void onRebind(Intent intent) {
        if (mIsDebuggable) {
            Log.d(TAG, "onRebind");
        }
        super.onRebind(intent);
    }

    public void setEventListener(MediaPlayerLocalServiceEventListener listener) {
        if (listener != null) {
            mListener = listener;
        } else {
            if (!(mListener instanceof MediaPlayerLocalServiceNullEventListener)) {
                mListener = new MediaPlayerLocalServiceNullEventListener();
            }
        }
    }

    public int getAudioSessionId() {
        return mPlayer.getAudioSessionId();
    }

    public boolean isPlaying() {
        final MediaPlayer player = mPlayer;

        if (player != null) {
            return player.isPlaying();
        }

        return false;
    }

    public boolean isPrepared() {
        return mIsPlayerPrepared;
    }

    public void pause() {
        final MediaPlayer player = mPlayer;

        if (player == null)
            return;

        if (mIsPlayerPrepared) {
            if (player.isPlaying()) {
                player.pause();
                onMediaPause();
            }
        }
    }

    public void play(Uri uri) {
        final MediaPlayer player = mPlayer;

        try {
            stopInternal();

            player.reset();
            player.setVolume(1.0f, 1.0f);

            player.setOnPreparedListener(mOnPreparedListener);
            player.setOnCompletionListener(mOnCompletionListener);

            player.setDataSource(getApplicationContext(), uri);
            player.prepareAsync();
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "playOne", e);
        } catch (SecurityException e) {
            Log.e(TAG, "playOne", e);
        } catch (IllegalStateException e) {
            Log.e(TAG, "playOne", e);
        } catch (IOException e) {
            Log.e(TAG, "playOne", e);
        }
    }

    public void resume() {

        final MediaPlayer player = mPlayer;

        if (player == null)
            return;

        try {
            player.setVolume(1.0f, 1.0f);
        } catch (Exception e) {
        }

        if (mIsPlayerPrepared) {
            if (!player.isPlaying()) {
                player.start();
                onMediaResume();
            }
        }
    }

    public void stop() {
        stopInternal();
    }

    private void onMediaCompletion() {
        mListener.onMediaCompletion(MediaPlayerLocalService.this);
    }

    private void onMediaPause() {
        stopForeground(true);
        mListener.onMediaPause(this);
    }

    private void onMediaPrepared() {
        stopForeground(true);
        mListener.onMediaPrepared(this);
    }

    private void onMediaResume() {
        startForeground(ONGOING_NOTIFICATION, createServiceNotification(false));
        mListener.onMediaResume(this);
    }

    private void onMediaStart() {
        startForeground(ONGOING_NOTIFICATION, createServiceNotification(true));
        mListener.onMediaStart(this);
    }

    private void onMediaStop() {
        stopForeground(true);
        mListener.onMediaStop(this);
    }

    private Notification createServiceNotification(boolean useTicker) {
        final String tickerStr = "ticker";
        final String titleStr = "title";
        final String textStr = "text";

        Intent notificationIntent = new Intent(this, MainActivity.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
                | Intent.FLAG_ACTIVITY_NEW_TASK);
        notificationIntent.setAction(Intent.ACTION_MAIN);
        final PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                notificationIntent, 0);

        final Notification notification = (new Notification.Builder(this))
                .setSmallIcon(R.drawable.ic_launcher)
                .setTicker(((useTicker) ? tickerStr : null)).setWhen(0)
                .setContentIntent(contentIntent).setContentTitle(titleStr)
                .setContentText(textStr).setOngoing(true).build();

        return notification;
    }

    private MediaPlayer createMediaPlayer() {
        final MediaPlayer player = new MediaPlayer();
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        return player;
    }

    private MediaPlayer createSilentMediaPlayer() {
        final Context context = this;
        boolean result = false;

        MediaPlayer mp = null;
        AssetFileDescriptor afd = null;

        try {
            mp = new MediaPlayer();

            afd = context.getAssets().openFd("workaround_1min.mp3");

            mp.setDataSource(
                    afd.getFileDescriptor(),
                    afd.getStartOffset(),
                    afd.getLength());
            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mp.prepare();

            // NOTE: start() is no needed
            // mp.start();

            result = true;
        } catch (IOException e) {
            Log.e(TAG, "createSilentMediaPlayer()", e);
        } catch (RuntimeException e) {
            Log.e(TAG, "createSilentMediaPlayer()", e);
        } finally {
            if (!result && mp != null) {
                try {
                    mp.release();
                } catch (IllegalStateException e) {
                }
            }
            if (afd != null) {
                try {
                    afd.close();
                } catch (IOException e) {
                }
            }
        }

        return mp;
    }

    private void stopInternal() {
        final MediaPlayer player = mPlayer;

        if (player == null)
            return;

        if (mIsPlayerPrepared) {
            if (player.isPlaying()) {
                player.stop();
                mIsPlayerPrepared = false;
                onMediaStop();
            }
        }
    }

    private static void safeReleaseMediaPlayer(MediaPlayer player) {
        try {
            if (player != null) {
                player.release();
            }
        } catch (IllegalStateException ex) {
        }
    }

}




Java Source Code List

com.h6ah4i.android.example.tunnelplayerworkaround.MainActivity.java
com.h6ah4i.android.example.tunnelplayerworkaround.SimpleVisualizerView.java
com.h6ah4i.android.music_player.MediaPlayerLocalService.java
com.h6ah4i.android.utils.LocalServiceBinder.java