Commit 341564cd authored by Michael Merg's avatar Michael Merg
Browse files

UI: add AudioPlayerActivity

- some icons missing
parent 7dcd1a66
......@@ -3,7 +3,149 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
\ No newline at end of file
android:layout_height="match_parent"
android:background="@drawable/bg_with_shadow">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dip"
android:orientation="horizontal"
android:background="@drawable/header" >
<ImageView
android:src="@drawable/header_logo"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="centerInside"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
<ImageView
android:layout_height="match_parent"
android:layout_width="0dip"
android:layout_weight="1"
android:background="#ffffff"
android:layout_marginLeft="15dip"
android:layout_marginTop="15dip"
android:id="@+id/cover"/>
<LinearLayout
android:layout_width="90dip"
android:layout_height="match_parent"
android:gravity="bottom"
android:paddingLeft="15dip"
android:orientation="vertical">
<ImageButton
android:layout_height="60dip"
android:layout_width="60dip"
android:layout_marginBottom="10dip"
android:id="@+id/shuffle"
android:onClick="onShuffleClick"/>
<ImageButton
android:layout_height="60dip"
android:layout_width="60dip"
android:id="@+id/repeat"
android:onClick="onRepeatClick"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginLeft="15dip"
android:layout_marginTop="10dip"
android:layout_marginRight="15dip">
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="18dip"
android:text="0:00"
android:textColor="#ffffff"
android:id="@+id/time"/>
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="18dip"
android:text="0:00"
android:gravity="right"
android:textColor="#ffffff"
android:id="@+id/length"/>
</LinearLayout>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="4dip"
android:maxHeight="4dip"
android:progressDrawable="@drawable/po_seekbar"
android:thumb="@drawable/ic_seekbar_thumb"
android:paddingTop="5dip"
android:paddingBottom="10dip"
android:paddingLeft="15dip"
android:paddingRight="15dip"
android:id="@+id/timeline"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title"
android:textColor="#ffffff"
android:textSize="20dip"
android:paddingLeft="20dip"
android:paddingRight="20dip"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_marginBottom="4dip"
android:id="@+id/title"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Artist"
android:textColor="#888888"
android:textSize="18dip"
android:paddingLeft="20dip"
android:paddingRight="20dip"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_marginBottom="4dip"
android:id="@+id/artist"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Album"
android:textColor="#888888"
android:textSize="18dip"
android:paddingLeft="20dip"
android:paddingRight="20dip"
android:singleLine="true"
android:ellipsize="marquee"
android:id="@+id/album"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:layout_margin="10dip">
<ImageButton
android:layout_height="50dip"
android:layout_width="50dip"
android:id="@+id/previous"
android:onClick="onPreviousClick"/>
<ImageButton
android:background="@drawable/ic_pause"
android:layout_width="70dip"
android:layout_height="70dip"
android:layout_marginLeft="15dip"
android:layout_marginRight="15dip"
android:id="@+id/play_pause"
android:onClick="onPlayPauseClick"/>
<ImageButton
android:layout_height="50dip"
android:layout_width="50dip"
android:id="@+id/next"
android:onClick="onNextClick"/>
</LinearLayout>
</LinearLayout>
......@@ -25,4 +25,6 @@
<string name="not_show_again">"Don't show this Message again."</string>
<string name="beta_warning">This is a early alpha version\n(NOT STABLE!).</string>
<string name="info_title">Information</string>
<string name="unknown_artist">Unknown Artist</string>
<string name="unknown_album">Unknown Album</string>
</resources>
......@@ -8,6 +8,7 @@ import org.videolan.vlc.android.widget.FlingViewGroup;
import org.videolan.vlc.android.widget.FlingViewGroup.ViewSwitchListener;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
......@@ -48,6 +49,8 @@ public class AudioBrowserActivity extends Activity {
@Override
public void onItemClick(AdapterView<?> av, View v, int p, long id) {
mAudioController.load(mSongsAdapter.getPaths(), p);
Intent intent = new Intent(AudioBrowserActivity.this, AudioPlayerActivity.class);
startActivity(intent);
}
});
updateLists();
......@@ -80,7 +83,7 @@ public class AudioBrowserActivity extends Activity {
private void updateLists() {
List<Media> audioList = MediaLibrary.getInstance().getAudioItems();
List<Media> audioList = MediaLibrary.getInstance(this).getAudioItems();
for (int i = 0; i < audioList.size(); i++) {
mSongsAdapter.add(audioList.get(i));
}
......
......@@ -16,6 +16,8 @@ public interface AudioPlayer {
void play();
void pause();
boolean isPlaying();
void next();
void previous();
}
}
......@@ -2,9 +2,12 @@ package org.videolan.vlc.android;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class AudioPlayerActivity extends Activity implements AudioPlayer {
......@@ -14,7 +17,8 @@ public class AudioPlayerActivity extends Activity implements AudioPlayer {
private TextView mTitle;
private TextView mArtist;
private TextView mAlbum;
private TextView mGenre;
private TextView mTime;
private TextView mLength;
private ImageButton mPlayPause;
private ImageButton mNext;
private ImageButton mPrevious;
......@@ -22,6 +26,9 @@ public class AudioPlayerActivity extends Activity implements AudioPlayer {
private ImageButton mRepeat;
private SeekBar mTimeline;
private AudioServiceController mAudioController;
private boolean mIsTracking = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -30,23 +37,108 @@ public class AudioPlayerActivity extends Activity implements AudioPlayer {
mCover = (ImageView) findViewById(R.id.cover);
mTitle = (TextView) findViewById(R.id.title);
mArtist = (TextView) findViewById(R.id.artist);
// mAlbum = (TextView) findViewById(R.id.album);
// mGenre = (TextView) findViewById(R.id.genre);
// mPlayPause = (ImageButton) findViewById(R.id.play_pause);
// mNext = (ImageButton) findViewById(R.id.next);
// mPrevious = (ImageButton) findViewById(R.id.previous);
// mShuffle = (ImageButton) findViewById(R.id.shuffle);
// mRepeat = (ImageButton) findViewById(R.id.repeat);
mAlbum = (TextView) findViewById(R.id.album);
mTime = (TextView) findViewById(R.id.time);
mLength = (TextView) findViewById(R.id.length);
mPlayPause = (ImageButton) findViewById(R.id.play_pause);
mNext = (ImageButton) findViewById(R.id.next);
mPrevious = (ImageButton) findViewById(R.id.previous);
mShuffle = (ImageButton) findViewById(R.id.shuffle);
mRepeat = (ImageButton) findViewById(R.id.repeat);
mTimeline = (SeekBar) findViewById(R.id.timeline);
mAudioController = AudioServiceController.getInstance();
}
@Override
protected void onStart() {
mAudioController.addAudioPlayer(this);
update();
super.onStart();
}
@Override
protected void onStop() {
mAudioController.removeAudioPlayer(this);
super.onStop();
}
@Override
public void update() {
// Exit the player when there is no media
if (!mAudioController.hasMedia())
finish();
// mCover....
mTitle.setText(mAudioController.getTitle());
mArtist.setText(mAudioController.getArtist());
//mAlbum.setText(mAudioController.getAlbum());
int time = (int) mAudioController.getTime();
int length = (int) mAudioController.getLength();
mTime.setText(Util.millisToString(time));
mLength.setText(Util.millisToString(length));
mTimeline.setMax(length);
if (!mIsTracking)
mTimeline.setProgress(time);
if (mAudioController.isPlaying()) {
mPlayPause.setBackgroundResource(R.drawable.ic_pause);
} else {
mPlayPause.setBackgroundResource(R.drawable.ic_play);
}
mTimeline.setOnSeekBarChangeListener(mTimelineListner);
}
OnSeekBarChangeListener mTimelineListner = new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar sb, int prog, boolean fromUser) {
if (fromUser) {
mAudioController.setTime(prog);
mTime.setText(Util.millisToString(prog))
; }
}
};
public void onPlayPauseClick(View view) {
if (mAudioController.isPlaying()) {
mAudioController.pause();
} else {
mAudioController.play();
}
}
public void onNextClick(View view) {
mAudioController.next();
}
public void onPreviousClick(View view) {
mAudioController.previous();
}
public void onRepeatClick() {
// mAudioController.repeat();
Util.toaster("not implemented :(");
}
public void onShuffleClick() {
// mAudioController.shuffle();
Util.toaster("not implemented :(");
}
}
......@@ -163,6 +163,16 @@ public class AudioService extends Service {
}
}
private void previous() {
int index = mMediaList.indexOf(mCurrentMedia);
if (index > 0) {
mCurrentMedia = mMediaList.get(index -1);
mLibVLC.readMedia(mCurrentMedia.getPath());
showNotification();
}
}
private IAudioService.Stub mInterface = new IAudioService.Stub() {
@Override
......@@ -197,8 +207,7 @@ public class AudioService extends Service {
@Override
public String getArtist() throws RemoteException {
// TODO: add media parameter
return null;
return mCurrentMedia.getArtist();
}
@Override
......@@ -257,6 +266,21 @@ public class AudioService extends Service {
showNotification();
}
@Override
public void next() throws RemoteException {
AudioService.this.next();
}
@Override
public void previous() throws RemoteException {
AudioService.this.previous();
}
@Override
public void setTime(long time) throws RemoteException {
mLibVLC.setTime(time);
}
};
}
......@@ -4,7 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import org.videolan.vlc.android.AudioPlayer.AudioPlayerControl;
import org.videolan.vlc.android.widget.AudioMiniPlayer;
import org.videolan.vlc.android.AudioPlayer;
import android.content.ComponentName;
import android.content.Context;
......@@ -23,7 +23,7 @@ public class AudioServiceController implements AudioPlayerControl {
private Context mContext;
private IAudioService mAudioServiceBinder;
private ServiceConnection mAudioServiceConnection;
private ArrayList<AudioMiniPlayer> mAudioPlayer;
private ArrayList<AudioPlayer> mAudioPlayer;
private IAudioServiceCallback mCallback = new IAudioServiceCallback.Stub() {
@Override
public void update() throws RemoteException {
......@@ -36,7 +36,7 @@ public class AudioServiceController implements AudioPlayerControl {
// Get context from MainActivity
mContext = MainActivity.getInstance();
mAudioPlayer = new ArrayList<AudioMiniPlayer>();
mAudioPlayer = new ArrayList<AudioPlayer>();
// Setup audio service connection
mAudioServiceConnection = new ServiceConnection() {
......@@ -118,7 +118,7 @@ public class AudioServiceController implements AudioPlayerControl {
* Add a AudioPlayer
* @param ap
*/
public void addAudioPlayer(AudioMiniPlayer ap) {
public void addAudioPlayer(AudioPlayer ap) {
mAudioPlayer.add(ap);
}
......@@ -126,7 +126,7 @@ public class AudioServiceController implements AudioPlayerControl {
* Remove AudioPlayer from list
* @param ap
*/
public void removeAudioPlayer(AudioMiniPlayer ap) {
public void removeAudioPlayer(AudioPlayer ap) {
if (mAudioPlayer.contains(ap)) {
mAudioPlayer.remove(ap);
}
......@@ -209,10 +209,12 @@ public class AudioServiceController implements AudioPlayerControl {
@Override
public boolean hasMedia() {
try {
return mAudioServiceBinder.hasMedia();
} catch (RemoteException e) {
Log.e(TAG, "remote procedure call failed: hasMedia()");
if (mAudioServiceBinder != null) {
try {
return mAudioServiceBinder.hasMedia();
} catch (RemoteException e) {
Log.e(TAG, "remote procedure call failed: hasMedia()");
}
}
return false;
}
......@@ -241,6 +243,32 @@ public class AudioServiceController implements AudioPlayerControl {
public Bitmap getCover() {
return null;
}
@Override
public void next() {
try {
mAudioServiceBinder.next();
} catch (RemoteException e) {
Log.e(TAG, "remote procedure call failed: next()");
}
}
@Override
public void previous() {
try {
mAudioServiceBinder.previous();
} catch (RemoteException e) {
Log.e(TAG, "remote procedure call failed: previous()");
}
}
public void setTime(long time) {
try {
mAudioServiceBinder.setTime(time);
} catch (RemoteException e) {
Log.e(TAG, "remote procedure call failed: setTime()");
}
}
......
......@@ -87,7 +87,7 @@ public class BrowserActivity extends ListActivity {
@Override
protected void onStop() {
// Update the MediaList
MediaLibrary.getInstance().loadMediaItems();
MediaLibrary.getInstance(this).loadMediaItems();
super.onStop();
}
......
......@@ -43,6 +43,8 @@ public class DatabaseManager {
private final String SEARCHHISTORY_DATE = "date";
private final String SEARCHHISTORY_KEY = "key";
private Context mContext;
public enum mediaColumn { MEDIA_TABLE_NAME, MEDIA_PATH, MEDIA_TIME, MEDIA_LENGTH,
MEDIA_TYPE, MEDIA_PICTURE, MEDIA_TITLE, MEDIA_ARTIST, MEDIA_GENRE, MEDIA_ALBUM
}
......@@ -54,6 +56,7 @@ public class DatabaseManager {
* @param context
*/
private DatabaseManager(Context context) {
mContext = context;
// create or open database
DatabaseHelper helper = new DatabaseHelper(context);
this.mDb = helper.getWritableDatabase();
......@@ -213,7 +216,7 @@ public class DatabaseManager {
picture = BitmapFactory.decodeByteArray(blob, 0, blob.length);
}
media = new Media(new File(path), cursor.getLong(0),
media = new Media(mContext, new File(path), cursor.getLong(0),
cursor.getLong(1), cursor.getInt(2),
picture, cursor.getString(4),
cursor.getString(5), cursor.getString(6),
......
......@@ -5,6 +5,9 @@ interface IAudioService {
void play();
void pause();
void stop();
void next();
void previous();
void setTime(long time);
String getCurrentMediaPath();
void load(in List<String> mediaPathList, int position);
boolean isPlaying();
......
......@@ -80,6 +80,7 @@ public class MainActivity extends TabActivity {
mAudioController = AudioServiceController.getInstance();
mAudioController.addAudioPlayer(mAudioPlayer);
mAudioPlayer.setAudioPlayerControl(mAudioController);
mAudioPlayer.update();
......@@ -107,7 +108,7 @@ public class MainActivity extends TabActivity {
}
/* Load media items from database and storage */
MediaLibrary.getInstance().loadMediaItems();
MediaLibrary.getInstance(this).loadMediaItems();
}
/** Create menu from XML
......
......@@ -3,6 +3,7 @@ package org.videolan.vlc.android;
import java.io.File;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
......@@ -49,14 +50,17 @@ public class Media implements Comparable<Media> {
private int mWidth = 0;
private int mHeight = 0;
private Bitmap mPicture;
private Context mContext;
/**
* Create an new Media
* @param file: path on the local storage
*/
public Media(File file) {
public Media(Context context, File file) {
this.mFile = file;
mContext = context;
LibVLC mLibVlc = null;
try {
......@@ -73,8 +77,9 @@ public class Media implements Comparable<Media> {
}
public Media(File file, long time, long length, int type, Bitmap picture,
String title, String artist, String genre, String album) {
public Media(Context context, File file, long time, long length, int type,
Bitmap picture, String title, String artist, String genre, String album) {
mContext = context;
mFile = file;
mTime = time;
......@@ -157,7 +162,10 @@ public class Media implements Comparable<Media> {
}
public String getArtist() {
return mArtist;
if (mArtist == null)
return mContext.getString(R.string.unknown_artist);
else
return mArtist;
}