Android Open Source - Billy P Player Service






From Project

Back to project page Billy.

License

The source code is released under:

GNU General Public License

If you think the Android project Billy 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.vibin.billy;
/*from   w w  w  .  java 2 s  . c  om*/
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.RemoteViews;

import com.android.volley.RequestQueue;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;

import org.videolan.libvlc.EventHandler;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.LibVlcException;
import org.videolan.libvlc.MediaList;


public class PPlayerService extends Service implements Handler.Callback {
    private static final String TAG = PPlayerService.class.getSimpleName();
    String streamLink, song, album, artist, artwork;
    LibVLC bp;
    MediaList list;
    int songIndex;
    int bufferPercent;
    Notification note;
    NotificationManager noteMan;
    Bitmap notifIcon;
    RequestQueue req;
    RemoteViews notifView;
    BillyApplication billyapp;
    PhoneStateListener PSlistener;
    TelephonyManager telephony;
    private onBPChangedListener BPlistener;
    private final IBinder mBinder = new PPlayerServiceBinder();
    public static boolean isRunning;
    public static boolean isInCall, isInCallMusicPaused;
    public static boolean isIdle = true;
    boolean onlyOnce = true;

    @Override
    public boolean handleMessage(Message msg) {
        int event = msg.getData().getInt("event");
        switch (event) {
            case EventHandler.MediaPlayerPlaying:
                //Log.d(TAG, "started playing" +bundle2string(msg.getData()));
                break;
            case EventHandler.MediaPlayerEndReached:
                Log.d(TAG, "end reached" +bundle2string(msg.getData()));
                onCompletion();
                break;
            case EventHandler.MediaPlayerEncounteredError:
                Log.d(TAG,"Mediaplayer error occured");
                onError();
                break;
            case EventHandler.MediaPlayerPositionChanged:
                //Log.d(TAG, "position" +bundle2string(msg.getData()));
                onPrepared();
                break;
            case EventHandler.MediaPlayerBuffering:
                onBufferChange(msg.getData().getFloat("data"));
                break;
        }
        return true;
    }

    private void onBufferChange(float percent) {
            bufferPercent = (int) percent;
    }

    public static String bundle2string(Bundle bundle) {
        String string = "Bundle{";
        for (String key : bundle.keySet()) {
            string += " " + key + " => " + bundle.get(key) + ";";
        }
        string += " }Bundle";
        return string;
    }

    public interface onBPChangedListener {
        void onPrepared(int duration);

        void onCompletion();

        void onError();

        void onStop();

        void onNotificationPausePressed();

        void onNotificationPlayPressed();

        void onNotificationStopPressed();
    }

    /**
     * Returns this instance of LocalService so clients can call public methods
     */
    public class PPlayerServiceBinder extends Binder {
        public PPlayerService getService() {
            return PPlayerService.this;
        }

        public void setListener(onBPChangedListener listener) {
            BPlistener = listener;
        }
    }

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

    @Override
    public void onCreate() {
        super.onCreate();
        setCustomExceptionHandler();

        try {
            bp = LibVLC.getInstance();
            bp.init(getBaseContext());
        } catch (LibVlcException e) {
            Log.d(TAG, e.toString());
        }

        Log.d(TAG, "Service's onCreate");
        billyapp = (BillyApplication) this.getApplication();

        isRunning = true;
        notifView = new RemoteViews(this.getPackageName(), R.layout.notification_view);
        noteMan = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        req = billyapp.getRequestQueue();
    }

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            setupPhoneListener();
            streamLink = intent.getStringExtra("streamLink");
            song = intent.getStringExtra("songName");
            album = intent.getStringExtra("albumName");
            artist = intent.getStringExtra("artistName");
            songIndex = intent.getIntExtra("songIndex", 50);
            artwork = intent.getStringExtra("artwork");

            //bp.reset();

//            if (!bp.isPlaying()) {
                //bp.setDataSource(getBaseContext(), Uri.parse(streamLink));

/*
                    URLConnection con = new URL(streamLink).openConnection();
                    con.connect();
                    InputStream is = con.getInputStream();
                    streamLink = con.getURL().toString();
                    is.close();
*/
//                  streamLink="http://ec-media.soundcloud.com/p7Uw60gtODDZ.128.mp3?f10880d39085a94a0418a7ef69b03d522cd6dfee9399eeb9a522009e6bf9b93b1c57cf78a3e4865f4b47b62a40b86e0209984a23f40484b51853d2c1e8a7dc8285658d0e8e&AWSAccessKeyId=AKIAJNIGGLK7XA7YZSNQ&Expires=1412417762&Signature=Oz5cUbgp06dzFOy3aTBm0txXSIY%3D";
                //list = bp.getPrimaryMediaList();
                //list.clear();

                //list.add(LibVLC.PathToURI(streamLink));
                Log.d(TAG, "service " + streamLink);

                EventHandler eh = EventHandler.getInstance();
                Handler handler = new Handler(this);
                eh.addHandler(handler);

                bp.setNetworkCaching(1);
                //bp.playIndex(0);
                onlyOnce = true;
                bp.playMRL(LibVLC.PathToURI(streamLink));
                //putNotification();
//            }
        }
        return START_STICKY;
    }

    private void setupPhoneListener() {
        telephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        PSlistener = new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
                switch (state) {
                    /**
                     * Lifting or cancelling a call is equivalent to pressing pause/play Notification buttons
                     */
                    case TelephonyManager.CALL_STATE_RINGING:
                        isInCall = true;
                        if (bp != null && !isIdle) {
                            try {
                                if (bp.isPlaying()) {
                                    isInCallMusicPaused = true;
                                    bp.pause();
                                    putNotification();
                                    BPlistener.onNotificationPausePressed();
                                }
                            } catch (IllegalStateException e) {
                                Log.d(TAG, e.toString());
                            }
                        }
                        break;
                    case TelephonyManager.CALL_STATE_IDLE:
                        if (isInCall) {
                            isInCall = false;
                            if (isInCallMusicPaused) {
                                isInCallMusicPaused = false;
                                if (bp != null) {
                                    bp.play();
                                    putNotification();
                                    BPlistener.onNotificationPlayPressed();
                                }
                            }
                        }
                }

            }
        };
        telephony.listen(PSlistener, PhoneStateListener.LISTEN_CALL_STATE);
    }


    public void onPrepared() {
        if(onlyOnce) {
            putNotification();
            Log.d(TAG,"Mediaplayer has prepared");
            isIdle = false;
            onlyOnce = false;
            BPlistener.onPrepared((int) bp.getLength() / 1000); //ms
        }
    }

    public void doPlay() {
        if (!bp.isPlaying()) {
            Log.d(TAG, "play media");
            //onlyOnce = true;
            //bp.playIndex(0);
            bp.play();
        }
        putNotification();
    }

    public void doPause() {
        if(bp.isPlaying()) {
            bp.pause();
        }
        putNotification();
    }

    public void onError() {
        stopForeground(true);
        BPlistener.onError();
    }

    public void onCompletion() {
        Log.d(TAG, "Service onCompletion");
        BPlistener.onCompletion();
        stopForeground(true);
        try {
            unregisterReceiver(NotificationMediaControl);
        } catch (IllegalArgumentException e) {
            Log.d(TAG, e.toString());
        }
        stopMedia();
    }

    public void stopMedia() {
  //      if (bp.isPlaying()) {
            bp.stop();
            BPlistener.onStop();
  //      }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Service onDestroy");
        if (bp != null) {
            if (bp.isPlaying()) {
                bp.stop();
            }
            isIdle = true;
            bp.destroy();
        }
        stopForeground(true);
        try {
            unregisterReceiver(NotificationMediaControl);
        } catch (IllegalArgumentException e) {
            Log.d(TAG, e.toString());
        }
        if (PSlistener != null) {
            telephony.listen(PSlistener, PhoneStateListener.LISTEN_NONE);
        }
        isRunning = false;
    }

    /**
     * Put a sticky notification for media controls
     */
    private void putNotification() {
        Intent resultIntent = new Intent(this, DetailView.class);
        resultIntent.putExtra("song", song);
        resultIntent.putExtra("album", album);
        resultIntent.putExtra("artist", artist);
        resultIntent.putExtra("artwork", artwork);
        resultIntent.putExtra("index", songIndex);
        //resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        //resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        note = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_notification)
                .setOngoing(true)
                .setContentIntent(resultPendingIntent)
                .setPriority(Notification.PRIORITY_MAX)
                .setContentTitle("Billy").build();
        note.bigContentView = notifView;
        notifView.setTextViewText(R.id.song, song);
        notifView.setTextViewText(R.id.artist, artist);
        notifView.setTextViewText(R.id.album, album);

        billyapp.getImageLoader().get(artwork, new ImageLoader.ImageListener() {
            @Override
            public void onResponse(ImageLoader.ImageContainer imageContainer, boolean b) {
                notifIcon = imageContainer.getBitmap();
                notifView.setImageViewBitmap(R.id.artwork, notifIcon);
            }

            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Log.d(TAG, volleyError.toString());
            }
        });

        Intent playIntent = new Intent("com.vibin.billy.ACTION_PLAY");
        Intent pauseIntent = new Intent("com.vibin.billy.ACTION_PAUSE");
        Intent quitIntent = new Intent("com.vibin.billy.ACTION_QUIT");
        PendingIntent pendingQuitIntent = PendingIntent.getBroadcast(getBaseContext(), 100, quitIntent, 0);
        notifView.setOnClickPendingIntent(R.id.dismiss, pendingQuitIntent);
        if (bp.isPlaying()) {
            notifView.setImageViewResource(R.id.control, R.drawable.notification_pause);
            PendingIntent pendingPauseIntent = PendingIntent.getBroadcast(getBaseContext(), 100, pauseIntent, 0);
            notifView.setOnClickPendingIntent(R.id.control, pendingPauseIntent);
        } else {
            notifView.setImageViewResource(R.id.control, R.drawable.notification_play);
            PendingIntent pendingPlayIntent = PendingIntent.getBroadcast(getBaseContext(), 100, playIntent, 0);
            notifView.setOnClickPendingIntent(R.id.control, pendingPlayIntent);
        }
        startForeground(1, note);

        IntentFilter filter = new IntentFilter();
        filter.addAction(playIntent.getAction());
        filter.addAction(pauseIntent.getAction());
        filter.addAction(quitIntent.getAction());
        registerReceiver(NotificationMediaControl, filter);
    }

    private final BroadcastReceiver NotificationMediaControl = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equalsIgnoreCase("com.vibin.billy.ACTION_PAUSE")) {
                BPlistener.onNotificationPausePressed();
                doPause();
            }
            if (action.equalsIgnoreCase("com.vibin.billy.ACTION_PLAY")) {
                BPlistener.onNotificationPlayPressed();
                doPlay();
            }
            if (action.equalsIgnoreCase("com.vibin.billy.ACTION_QUIT")) {
                BPlistener.onNotificationStopPressed();
                stopMedia();
                stopSelf();
            }
        }
    };

    /**
     * Register a custom UncaughtException Handler for dismissing persistent notification on foreground Service's crash
     * Do call the default Android UncaughtException Handler at last, to get the dialog
     */
    private void setCustomExceptionHandler() {
        final Thread.UncaughtExceptionHandler defaultExHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.UncaughtExceptionHandler customExHandler = new Thread.UncaughtExceptionHandler() {

            @Override
            public void uncaughtException(Thread thread, Throwable throwable) {
                stopForeground(true);

                defaultExHandler.uncaughtException(thread, throwable);
            }
        };
        Thread.setDefaultUncaughtExceptionHandler(customExHandler);
    }
}




Java Source Code List

com.vibin.billy.BillyApplication.java
com.vibin.billy.BillyItem.java
com.vibin.billy.BitmapLruCache.java
com.vibin.billy.ChangelogDialog.java
com.vibin.billy.CustomBaseAdapter.java
com.vibin.billy.CustomDatabaseAdapter.java
com.vibin.billy.CustomFragmentAdapter.java
com.vibin.billy.CustomListPreference.java
com.vibin.billy.CustomShareActionProvider.java
com.vibin.billy.CustomStringRequest.java
com.vibin.billy.DetailView.java
com.vibin.billy.LicensesFragment.java
com.vibin.billy.MainActivity.java
com.vibin.billy.MediaControl.java
com.vibin.billy.NotifyingScrollView.java
com.vibin.billy.PPlayerService.java
com.vibin.billy.PlayerService.java
com.vibin.billy.ProcessingTask.java
com.vibin.billy.ReorderedListPreference.java
com.vibin.billy.Settings.java
com.vibin.billy.SongsFragment.java
com.vibin.billy.SwingBottomInAnimationAdapter.java
com.vibin.billy.draglistview.DynamicListView.java
com.vibin.billy.draglistview.StableArrayAdapter.java
com.vibin.billy.swipeable.ActivitySwipeDismissListener.java
com.vibin.billy.swipeable.AnimationUtils.java
com.vibin.billy.swipeable.SwipeDismissViewGroup.java
com.vibin.billy.swipeable.SwipeListener.java
com.vibin.billy.swipeable.SwipeableActivity.java
com.vibin.billy.swipeable.WindowDimens.java
com.vibin.billy.swipeable.WindowUtils.java
org.videolan.libvlc.AudioOutput.java
org.videolan.libvlc.EventHandler.java
org.videolan.libvlc.HWDecoderUtil.java
org.videolan.libvlc.IVideoPlayer.java
org.videolan.libvlc.LibVLC.java
org.videolan.libvlc.LibVlcException.java
org.videolan.libvlc.LibVlcUtil.java
org.videolan.libvlc.MediaList.java
org.videolan.libvlc.Media.java
org.videolan.libvlc.TrackInfo.java