com.racoon.ampdroid.Mp3PlayerService.java Source code

Java tutorial

Introduction

Here is the source code for com.racoon.ampdroid.Mp3PlayerService.java

Source

/**
 * The MIT License (MIT)
 * 
 * Copyright (c) 2014 Daniel Schruhl
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 */
package com.racoon.ampdroid;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Base64;
import android.util.Log;
import android.widget.RemoteViews;

import com.racoon.ampache.Song;

import org.apache.http.util.ByteArrayBuffer;

public class Mp3PlayerService extends Service {

    private MediaPlayer mediaPlayer;
    private ArrayList<Song> playList;
    private int cursor;
    private Song currentSong;
    private NotificationManager notifManager;
    public static final int NOTIFICATION_ID = 1556;
    private boolean pause;
    private boolean allowRebind;
    private String session;
    private String oCuser;
    private String oCpassword;

    @Override
    public void onCreate() {
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer.setOnCompletionListener(new SongComplitionListener());
        pause = false;
        session = "";

    }

    @SuppressWarnings("unchecked")
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String action = intent.getStringExtra("ACTION");
            oCuser = intent.getStringExtra("oCuser");
            oCpassword = intent.getStringExtra("oCpassword");

            if (action != null && intent.getSerializableExtra("com.racoon.ampdroid.NowPlaying") != null) {
                playList = (ArrayList<Song>) intent.getSerializableExtra("com.racoon.ampdroid.NowPlaying");
                if (action.equals("play") && !mediaPlayer.isPlaying()) {
                    cursor = intent.getIntExtra("CURSOR", 0);
                    session = intent.getStringExtra("SESSION");
                    play(cursor);
                    Log.d("service", "cursor: " + String.valueOf(cursor));
                } else if (action.equals("pause")) {
                    pause();
                } else if (action.equals("next")) {
                    next();
                } else if (action.equals("previous")) {
                    previous();
                }

            } else {
                // TODO error handling
            }
        }

        return 0;
    }

    @Override
    public void onDestroy() {
        mediaPlayer.release();
        // mediaPlayer.reset();
        super.onDestroy();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        // All clients have unbound with unbindService()
        return allowRebind;
    }

    @Override
    public void onRebind(Intent intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }

    public void pause() {
        Log.d("service", "status: " + pause);
        if (pause) {
            pause = false;
            mediaPlayer.start();
        } else {
            pause = true;
            mediaPlayer.pause();
        }
        setNotifiction();
    }

    public void stop() {
        mediaPlayer.reset();
        setNotifiction();
        currentSong = null;
        stopSelf();
    }

    public void next() {
        if (playList != null) {
            int size = playList.size();
            if ((cursor + 1) < size) {
                cursor++;
                play(cursor);
            } else {
                stop();
            }
        }
    }

    public void previous() {
        if ((cursor - 1) >= 0) {
            cursor--;
            play(cursor);
        } else {
            stop();
        }
    }

    public void DownloadFromUrl(String DownloadURL, String LocalFileName, String User, String Password) {
        try {
            URL url = new URL(DownloadURL);
            File file = new File(LocalFileName);

            long startTime = System.currentTimeMillis();
            //Log.d("bugs", "download begining");
            //Log.d("bugs", "download url:" + url);
            //Log.d("bugs", "download to file:" + fileName);

            HttpURLConnection con = (HttpURLConnection) url.openConnection();

            String credentials = User + ":" + Password;
            credentials = Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT);
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setRequestProperty("Authorization", "Basic " + credentials);
            con.connect();

            InputStream is = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);

            //Read bytes to the Buffer until there is nothing more to read(-1).
            ByteArrayBuffer baf = new ByteArrayBuffer(50);
            int current = 0;
            while ((current = bis.read()) != -1) {
                baf.append((byte) current);
            }

            //Convert the Bytes read to a String.
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baf.toByteArray());
            fos.close();
            Log.d("bugs", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");

            con.disconnect();

        } catch (IOException e) {
            Log.d("bugs", "Error: " + e);
        }

    }

    private void play(int id) {
        mediaPlayer.reset();
        try {
            Log.d("bugs", "song url " + playList.get(id).getUrl());
            String pattern = "ssid=([a-z]|[0-9])*&";
            String dataUrl = playList.get(id).getUrl().replaceAll(pattern, "ssid=" + session + "&");
            Log.d("bugs", "session " + session);
            Log.d("bugs", "data url " + dataUrl);
            //mediaPlayer.setDataSource(dataUrl);

            File extStore = Environment.getExternalStorageDirectory();
            String tmpfilename = extStore.getPath() + "/tmp/Ampdroid.mp3";

            File tmpfile = new File(tmpfilename);
            tmpfile.delete();

            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.ic_stat_notify)
                    .setContentTitle(getResources().getString(R.string.app_name))
                    .setContentText(getResources().getString(R.string.downloadinfo));
            int mNotificationId = 1;
            NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            mNotifyMgr.notify(mNotificationId, mBuilder.build());

            DownloadFromUrl(dataUrl, tmpfilename, oCuser, oCpassword);
            mediaPlayer.setDataSource(tmpfilename);

            mNotifyMgr.cancel(mNotificationId);

            mediaPlayer.prepare();
            currentSong = playList.get(id);
            mediaPlayer.start();
            setNotifiction();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private class SongComplitionListener implements OnCompletionListener {

        @Override
        public void onCompletion(MediaPlayer mp) {
            next();
        }
    }

    public String getCurrentTitle() {
        String result = "";
        if (currentSong != null) {
            result = currentSong.getTitle();
        }
        return result;
    }

    public String getArtist() {
        String result = "";
        if (currentSong != null) {
            result = currentSong.getArtist();
        }
        return result;
    }

    public boolean isPlaying() {
        boolean result = false;
        if (mediaPlayer != null) {
            try {
                result = mediaPlayer.isPlaying();
            } catch (IllegalStateException e) {
                Log.d("error", e.getStackTrace().toString());
            }
        }
        return result;
    }

    /**
     * @return the mediaPlayer
     */
    public MediaPlayer getMediaPlayer() {
        return mediaPlayer;
    }

    /**
     * @return the currentSong
     */
    public Song getCurrentSong() {
        return currentSong;
    }

    /**
     * @return the cursor
     */
    public int getCursor() {
        return cursor;
    }

    /**
     * @return the session
     */
    public String getSession() {
        return session;
    }

    /**
     * @param session the session to set
     */
    public void setSession(String session) {
        this.session = session;
    }

    /**
     * Binding
     */
    private final IBinder binder = new Mp3Binder();

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

    public class Mp3Binder extends Binder {
        Mp3PlayerService getService() {
            return Mp3PlayerService.this;
        }
    }

    private void setNotifiction() {
        RemoteViews notificationView = new RemoteViews(this.getPackageName(), R.layout.player_notification);
        notificationView.setTextViewText(R.id.notificationSongArtist, getArtist());
        notificationView.setTextViewText(R.id.notificationSongTitle, getCurrentTitle());
        /* 1. Setup Notification Builder */
        Notification.Builder builder = new Notification.Builder(this);

        /* 2. Configure Notification Alarm */
        builder.setSmallIcon(R.drawable.ic_stat_notify).setAutoCancel(true).setWhen(System.currentTimeMillis())
                .setTicker(getCurrentTitle());

        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent notifIntent = PendingIntent.getActivity(this, 0, intent, 0);

        builder.setContentIntent(notifIntent);
        builder.setContent(notificationView);

        /* 4. Create Notification and use Manager to launch it */
        Notification notification = builder.getNotification();
        String ns = Context.NOTIFICATION_SERVICE;
        notifManager = (NotificationManager) getSystemService(ns);
        notifManager.notify(NOTIFICATION_ID, notification);
        startForeground(NOTIFICATION_ID, notification);
    }

}