package com.zanehuy.player;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import android.app.Service;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Binder;
import android.os.IBinder;
import android.provider.MediaStore.Audio;
public class PlayerService extends Service {
static public final int STOPED = -1, PAUSED = 0, PLAYING = 1;
private MediaPlayer mediaPlayer;
private ArrayList<Track> tracklist;
private int status, currentTrackPosition;
private boolean taken;
private IBinder playerBinder;
@Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
tracklist = new ArrayList<Track>();
currentTrackPosition = -1;
setStatus(STOPED);
playerBinder = new PlayerBinder();
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer arg0) {
if (currentTrackPosition == tracklist.size()-1) {
stop();
} else {
nextTrack();
}
}
});
restoreTracklist();
}
@Override
public IBinder onBind(Intent intent) {
return playerBinder;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
public void take() {
taken = true;
}
private void untake() {
synchronized (this) {
taken = false;
notifyAll();
}
}
public boolean isTaken() {
return taken;
}
private void setStatus(int s) {
status = s;
}
public int getStatus() {
return status;
}
public ArrayList<Track> getTracklist() {
return tracklist;
}
public Track getTrack(int pos) {
return tracklist.get(pos);
}
public Track getCurrentTrack() {
if (currentTrackPosition < 0) {
return null;
} else {
return tracklist.get(currentTrackPosition);
}
}
public int getCurrentTrackPosition() {
return currentTrackPosition;
}
public void addTrack(Track track) {
tracklist.add(track);
untake();
}
public void addTrack(int id) {
tracklist.add(new Track(id));
untake();
}
public void removeTrack(int pos) {
if (pos == currentTrackPosition) {
stop();
}
if (pos < currentTrackPosition) {
currentTrackPosition--;
}
tracklist.remove(pos);
untake();
}
public void clearTracklist() {
if (status > STOPED) {
stop();
}
tracklist.clear();
untake();
}
public void playTrack(int pos) {
if (status > STOPED) {
stop();
}
FileInputStream file = null;
try {
file = new FileInputStream(new File(tracklist.get(pos).getPath()));
mediaPlayer.setDataSource(file.getFD());
mediaPlayer.prepare();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
currentTrackPosition = pos;
setStatus(PLAYING);
untake();
}
public void play(int pos) {
playTrack(pos);
}
public void play() {
switch (status) {
case STOPED:
if (!tracklist.isEmpty()) {
playTrack(0);
}
break;
case PLAYING:
mediaPlayer.pause();
setStatus(PAUSED);
break;
case PAUSED:
mediaPlayer.start();
setStatus(PLAYING);
break;
}
untake();
}
public void pause() {
mediaPlayer.pause();
setStatus(PAUSED);
untake();
}
public void stop() {
mediaPlayer.stop();
mediaPlayer.reset();
currentTrackPosition = -1;
setStatus(STOPED);
untake();
}
public void nextTrack() {
if (currentTrackPosition < tracklist.size()-1) {
playTrack(currentTrackPosition+1);
}
}
public void prevTrack() {
if (currentTrackPosition > 0) {
playTrack(currentTrackPosition-1);
}
}
public int getCurrentTrackProgress() {
if (status > STOPED) {
return mediaPlayer.getCurrentPosition();
} else {
return 0;
}
}
public int getCurrentTrackDuration() {
if (status > STOPED) {
return tracklist.get(currentTrackPosition).getDuration();
} else {
return 0;
}
}
public void seekTrack(int p) {
if (status > STOPED) {
mediaPlayer.seekTo(p);
untake();
}
}
public void storeTracklist() {
DbOpenHelper dbOpenHelper = new DbOpenHelper(getApplicationContext());
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
dbOpenHelper.onUpgrade(db, 1, 1);
for (int i = 0; i < tracklist.size(); i++) {
ContentValues c = new ContentValues();
c.put(DbOpenHelper.KEY_POSITION, i);
c.put(DbOpenHelper.KEY_FILE, tracklist.get(i).getPath());
db.insert(DbOpenHelper.TABLE_NAME, null, c);
}
dbOpenHelper.close();
}
private void restoreTracklist() {
DbOpenHelper dbOpenHelper = new DbOpenHelper(getApplicationContext());
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor c = db.query(DbOpenHelper.TABLE_NAME, null, null, null, null, null, null);
tracklist.clear();
while (c.moveToNext()) {
tracklist.add(new Track(c.getString(1)));
}
dbOpenHelper.close();
}
public class PlayerBinder extends Binder {
public PlayerService getService() {
return PlayerService.this;
}
}
public class Track {
private String path, artist, album, year, title, genre;
private int id, duration;
public Track(String p) {
path = p;
String[] proj = {Audio.Media.ARTIST, Audio.Media.ALBUM, Audio.Media.YEAR, Audio.Media.TITLE, Audio.Media.DURATION, Audio.Media._ID};
Cursor trackCursor = getContentResolver().query(Audio.Media.EXTERNAL_CONTENT_URI, proj, Audio.Media.DATA+" = '"+path+"' ", null, null);
trackCursor.moveToNext();
artist = trackCursor.getString(0);
album = trackCursor.getString(1);
year = trackCursor.getString(2);
title = trackCursor.getString(3);
duration = Integer.parseInt(trackCursor.getString(4));
id = Integer.parseInt(trackCursor.getString(5));
}
public Track(int id) {
String[] proj = {Audio.Media.ARTIST, Audio.Media.ALBUM, Audio.Media.YEAR, Audio.Media.TITLE, Audio.Media.DURATION, Audio.Media.DATA};
Cursor trackCursor = getContentResolver().query(Audio.Media.EXTERNAL_CONTENT_URI, proj, "_ID = "+id+" ", null, null);
trackCursor.moveToNext();
artist = trackCursor.getString(0);
album = trackCursor.getString(1);
year = trackCursor.getString(2);
title = trackCursor.getString(3);
duration = Integer.parseInt(trackCursor.getString(4));
path = trackCursor.getString(5);
}
public String getPath() {
return path;
}
public String getArtist() {
return artist;
}
public String getAlbum() {
return album;
}
public String getYear() {
return year;
}
public String getTitle() {
return title;
}
public String getGenre() {
return genre;
}
public int getId() {
return id;
}
public int getDuration() {
return duration;
}
}
public static String formatTrackDuration(int d) {
String min = Integer.toString((d/1000)/60);
String sec = Integer.toString((d/1000)%60);
if (sec.length() == 1) sec = "0"+sec;
return min+":"+sec;
}
}