http://code.google.com/p/musikcube/source/detail?r=388
Added:
/trunk/src/android/res/drawable/ic_playing.png
/trunk/src/android/res/drawable/running.png
/trunk/src/android/res/layout/category_select.xml
/trunk/src/android/res/layout/category_select_item.xml
/trunk/src/android/res/layout/help.xml
/trunk/src/android/res/layout/play_bpm_control.xml
/trunk/src/android/src/org/musikcube/CategorySelect.java
/trunk/src/android/src/org/musikcube/Helper.java
/trunk/src/android/src/org/musikcube/PlayerBPMControl.java
Deleted:
/trunk/src/android/src/org/musikcube/BPMControl.java
Modified:
/trunk/src/android/AndroidManifest.xml
/trunk/src/android/res/drawable/mc_notify.png
/trunk/src/android/res/layout/category_list_item.xml
/trunk/src/android/res/layout/now_playing_list_item.xml
/trunk/src/android/res/layout/play_control.xml
/trunk/src/android/res/layout-land/play_control.xml
/trunk/src/android/res/menu/default_menu.xml
/trunk/src/android/res/values/strings.xml
/trunk/src/android/src/doep/xml/Reader.java
/trunk/src/android/src/doep/xml/ReaderNode.java
/trunk/src/android/src/doep/xml/Writer.java
/trunk/src/android/src/doep/xml/WriterNode.java
/trunk/src/android/src/org/musikcube/CategoryList.java
/trunk/src/android/src/org/musikcube/NowPlayingList.java
/trunk/src/android/src/org/musikcube/PlayerControl.java
/trunk/src/android/src/org/musikcube/Service.java
/trunk/src/android/src/org/musikcube/TrackListBase.java
/trunk/src/android/src/org/musikcube/core/IQuery.java
/trunk/src/android/src/org/musikcube/core/Library.java
/trunk/src/android/src/org/musikcube/core/ListQuery.java
/trunk/src/android/src/org/musikcube/core/MetadataQuery.java
/trunk/src/android/src/org/musikcube/core/PaceDetector.java
/trunk/src/android/src/org/musikcube/core/Player.java
/trunk/src/android/src/org/musikcube/core/TrackPlayer.java
/trunk/src/android/src/org/musikcube/main.java
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/ic_playing.png Sat Aug 29 14:20:13 2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/src/android/res/drawable/running.png Sat Aug 29 14:20:13 2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/src/android/res/layout/category_select.xml Sat Aug 29 14:20:13
2009
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp">
+
+ <ListView android:id="@id/android:list"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:drawSelectorOnTop="false"/>
+
+ <LinearLayout android:id="@id/android:empty"
+ android:orientation="horizontal"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp" android:layout_width="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_height="fill_parent">
+ <ProgressBar android:id="@+id/ProgressBar01" android:keepScreenOn="true"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></ProgressBar>
+ <TextView android:id="@+id/TextView01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:text="Loading..."
android:layout_marginLeft="10sp"></TextView>
+ </LinearLayout>
+
+</LinearLayout>
=======================================
--- /dev/null
+++ /trunk/src/android/res/layout/category_select_item.xml Sat Aug 29
14:20:13 2009
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <CheckBox android:id="@+id/text" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="28sp"
android:maxLines="1"></CheckBox>
+</LinearLayout>
=======================================
--- /dev/null
+++ /trunk/src/android/res/layout/help.xml Sat Aug 29 14:20:13 2009
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+<TextView android:id="@+id/TextView01" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="@string/help_main"
android:layout_margin="10sp"></TextView>
+
+
+</LinearLayout>
=======================================
--- /dev/null
+++ /trunk/src/android/res/layout/play_bpm_control.xml Sat Aug 29 14:20:13
2009
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp" android:gravity="center_vertical|
center_horizontal">
+
+<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content">
+ <FrameLayout android:id="@+id/FrameLayout01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="10sp" android:padding="2sp"
android:background="#666666">
+ <ImageView android:layout_marginTop="5sp"
android:layout_marginBottom="5sp" android:id="@+id/AlbumCover"
android:background="#000000" android:src="@drawable/running"
android:layout_height="128sp" android:layout_width="128sp"
android:scaleType="fitXY"></ImageView>
+ </FrameLayout>
+</LinearLayout>
+
+<LinearLayout android:id="@+id/LinearLayout01"
android:layout_height="wrap_content" android:orientation="vertical"
android:gravity="left" android:layout_width="wrap_content"
android:layout_gravity="left" android:paddingLeft="20sp">
+ <TextView android:layout_height="wrap_content" android:textSize="24sp"
android:id="@+id/TrackTitle" android:lines="1"
android:layout_width="wrap_content" android:text="Title:"></TextView>
+ <TextView android:layout_height="wrap_content" android:text="Album:"
android:id="@+id/TrackAlbum" android:lines="1"
android:layout_width="wrap_content"></TextView>
+ <TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Artists:"
android:id="@+id/TrackArtist" android:lines="1"></TextView>
+</LinearLayout>
+<LinearLayout android:id="@+id/LinearLayout02"
android:layout_weight="0.5" android:layout_width="wrap_content"
android:layout_height="wrap_content"><TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:id="@+id/BPMText"
android:textSize="32sp" android:text="Pace: -
Bpm"></TextView></LinearLayout>
+<LinearLayout android:id="@+id/LinearLayout01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal">
+
+ <ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:adjustViewBounds="true"
android:id="@+id/MediaPause" android:src="@drawable/ic_media_pause"
android:padding="15sp"></ImageButton>
+ <ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/MediaNext"
android:adjustViewBounds="true" android:src="@drawable/ic_media_next"
android:padding="15sp"></ImageButton>
+
+</LinearLayout>
+
+
+
+
+<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content">
+ <TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="0:00"
android:id="@+id/TrackPosition" android:typeface="monospace"></TextView>
+ <TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="0:00"
android:id="@+id/TrackDuration" android:typeface="monospace"
android:gravity="right"></TextView>
+
+</LinearLayout>
+<SeekBar android:layout_height="wrap_content"
android:layout_width="fill_parent" android:max="1000"
android:id="@+id/TrackProgress" android:progress="0"
android:secondaryProgress="0"></SeekBar>
+
+
+
+
+
+
+
+
+</LinearLayout>
=======================================
--- /dev/null
+++ /trunk/src/android/src/org/musikcube/CategorySelect.java Sat Aug 29
14:20:13 2009
@@ -0,0 +1,252 @@
+/**
+ *
+ */
+package org.musikcube;
+
+import java.util.ArrayList;
+
+import org.musikcube.TrackListBase.TrackViewHolder;
+import org.musikcube.core.IQuery;
+import org.musikcube.core.ListQuery;
+import org.musikcube.core.IQuery.OnQueryResultListener;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+/**
+ * @author doy
+ *
+ */
+public class CategorySelect extends ListActivity implements
OnQueryResultListener {
+
+ private String category = null;
+ private String nextCategoryList = "";
+ private ListQuery query = new ListQuery();
+
+ private ArrayList<String> selectedCategory;
+ private ArrayList<Integer> selectedCategoryIds;
+// private ProgressDialog loadingDialog;
+
+ // Need handler for callbacks to the UI thread
+ final Handler callbackHandler = new Handler();
+
+ // Create runnable for posting
+ final Runnable callbackRunnable = new Runnable() {
+ public void run() {
+ OnResults();
+ }
+ };
+
+ static class CategoryViewHolder{
+ CheckBox title;
+ }
+
+ public class ResultAdapter extends BaseAdapter{
+
+ protected ListQuery query;
+ protected ListActivity context;
+ private LayoutInflater inflator;
+
+ public ResultAdapter(ListActivity context){
+ this.context = context;
+ this.inflator = context.getLayoutInflater();
+ }
+
+ public int getCount() {
+ int size = this.query.resultsInts.size();
+ if(size==0){
+ return 0;
+ }else{
+ return size+1;
+ }
+ }
+
+ public Object getItem(int position) {
+ if(position==0){
+ return 0;
+ }else{
+ return this.query.resultsInts.get(position-1);
+ }
+ }
+
+ public long getItemId(int position) {
+ if(position==0){
+ return 0;
+ }else{
+ return this.query.resultsInts.get(position-1);
+ }
+ }
+
+ public View getView(int position, View view, ViewGroup parent) {
+ final CategoryViewHolder holder;
+ if(view==null){
+ view = inflator.inflate(R.layout.category_select_item, null);
+ holder = new CategoryViewHolder();
+ holder.title = (CheckBox) view.findViewById(R.id.text);
+ view.setTag(holder);
+ }else{
+ holder = (CategoryViewHolder)view.getTag();
+ }
+
+ //
+ if(position==0){
+ holder.title.setText("- All -");
+ }else{
+ holder.title.setText(this.query.resultsStrings.get(position-1));
+ }
+ return view;
+ }
+
+ }
+
+ private ResultAdapter listAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState){
+ super.onCreate(savedInstanceState);
+ //Log.v("musikcube.CategoryList", "start");
+ this.setContentView(R.layout.category_select);
+
+ Intent intent = this.getIntent();
+
+ this.query.SetResultListener(this);
+
+ this.listAdapter = new ResultAdapter(this);
+ this.listAdapter.query = this.query;
+ setListAdapter(this.listAdapter);
+
+
+ // Extract the category order
+ String categoryString =
intent.getStringExtra("org.musikcube.CategorySelect.listCategory");
+ String[] categories = categoryString.split(",");
+ this.category = categories[0];
+
+ // Save the next category lists
+ for(int i=1;i<categories.length;i++){
+ if(i>1){
+ this.nextCategoryList += ",";
+ }
+ this.nextCategoryList += categories[i];
+ }
+
+ this.setTitle("musikCube: "+this.category);
+
+
+ if(this.category!=null){
+ //Log.v("musikcube.CategoryList", "category="+this.category);
+ // Query for data
+ this.query.category = this.category;
+
+ // check for selection
+ this.selectedCategory =
intent.getStringArrayListExtra("org.musikcube.CategoryList.selectedCategory");
+ this.selectedCategoryIds =
intent.getIntegerArrayListExtra("org.musikcube.CategoryList.selectedCategoryId");
+ if(this.selectedCategory!=null){
+ for(int i=0;i<this.selectedCategory.size();i++){
+ this.query.SelectData(this.selectedCategory.get(i),
this.selectedCategoryIds.get(i));
+ }
+ }
+
+ org.musikcube.core.Library library =
org.musikcube.core.Library.GetInstance();
+
+ //this.loadingDialog =
ProgressDialog.show(this, "", "Loading "+this.category+"...", true);
+ library.AddQuery(this.query);
+
+ }else{
+ //Log.v("musikcube.CategoryList", "category=null");
+
+ }
+
+ //Log.v("musikcube.CategoryList", "onCreate end");
+
+ }
+
+ public void OnResults(){
+ //Log.i("CategoryList::OnResults","In right
thread "+this.query.resultsStrings.size());
+ /*if(this.loadingDialog!=null){
+ this.loadingDialog.dismiss();
+ this.loadingDialog = null;
+ }*/
+ this.listAdapter.notifyDataSetChanged();
+ }
+
+ public void OnQueryResults(IQuery query) {
+ // Call in right thread
+ this.callbackHandler.post(this.callbackRunnable);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id){
+ //Log.i("CategoryList::onListItemClick","clicked on "+position+" "+id);
+
+ // List category
+ if(this.selectedCategory==null){
+ this.selectedCategory = new ArrayList<String>();
+ }
+ if(this.selectedCategoryIds==null){
+ this.selectedCategoryIds = new ArrayList<Integer>();
+ }
+ ArrayList<String> selectedCategory =
(ArrayList<String>)this.selectedCategory.clone();
+ ArrayList<Integer> selectedCategoryIds =
(ArrayList<Integer>)this.selectedCategoryIds.clone();
+
+ if(id!=0){
+ selectedCategory.add(this.category);
+ selectedCategoryIds.add((int)id);
+ }
+
+ if(this.nextCategoryList.equals("")){
+ // List tracks
+ Intent intent = new Intent(this, TrackList.class);
+ intent.putExtra("org.musikcube.CategoryList.listCategory",
this.nextCategoryList);
+ intent.putExtra("org.musikcube.CategoryList.selectedCategory",
selectedCategory);
+ intent.putExtra("org.musikcube.CategoryList.selectedCategoryId",
selectedCategoryIds);
+ startActivity(intent);
+ }else{
+ Intent intent = new Intent(this, CategoryList.class);
+ intent.putExtra("org.musikcube.CategoryList.listCategory",
this.nextCategoryList);
+ intent.putExtra("org.musikcube.CategoryList.selectedCategory",
selectedCategory);
+ intent.putExtra("org.musikcube.CategoryList.selectedCategoryId",
selectedCategoryIds);
+ startActivity(intent);
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ org.musikcube.core.Library.GetInstance().RemovePointer();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ startService(new Intent(this, org.musikcube.Service.class));
+ org.musikcube.core.Library.GetInstance().AddPointer();
+ }
+
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.default_menu, menu);
+ return true;
+ }
+
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if(Helper.DefaultOptionsItemSelected(item,this)){
+ return true;
+ }else{
+ return super.onContextItemSelected(item);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /trunk/src/android/src/org/musikcube/Helper.java Sat Aug 29 14:20:13
2009
@@ -0,0 +1,44 @@
+package org.musikcube;
+
+import org.musikcube.core.Player;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.view.MenuItem;
+
+public class Helper {
+
+
+ public static boolean DefaultOptionsItemSelected(MenuItem item,Context
context) {
+
//Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
+ switch (item.getItemId()) {
+ case R.id.context_settings:
+ context.startActivity(new Intent(context,
org.musikcube.Preferences.class));
+ return true;
+ case R.id.context_browse:
+ context.startActivity(new Intent(context, org.musikcube.main.class));
+ return true;
+ case R.id.context_controls:
+ if(Player.GetInstance().GetBPMMode()){
+ context.startActivity(new Intent(context,
org.musikcube.PlayerBPMControl.class));
+ }else{
+ context.startActivity(new Intent(context,
org.musikcube.PlayerControl.class));
+ }
+ return true;
+ case R.id.context_nowplaying:
+ context.startActivity(new Intent(context,
org.musikcube.NowPlayingList.class));
+ return true;
+ case R.id.context_help:
+ Dialog dialog = new Dialog(context);
+ dialog.setContentView(R.layout.help);
+ dialog.setTitle("Help");
+
+ dialog.show();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+}
=======================================
--- /dev/null
+++ /trunk/src/android/src/org/musikcube/PlayerBPMControl.java Sat Aug 29
14:20:13 2009
@@ -0,0 +1,253 @@
+package org.musikcube;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import org.musikcube.core.Library;
+import org.musikcube.core.Player;
+import org.musikcube.core.Track;
+import org.musikcube.core.Player.OnTrackUpdateListener;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+public class PlayerBPMControl extends Activity implements
OnTrackUpdateListener {
+
+ private Track track = new Track();
+ private int duration = 0;
+ private Object lock = new Object();
+ private boolean enable = false;
+ private int currentAlbumCoverId = 0;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ Log.v("MC2::PC","OnCreate");
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.play_bpm_control);
+
+ ImageButton nextButton = (ImageButton)findViewById(R.id.MediaNext);
+ nextButton.setOnClickListener(this.onNextClick);
+ ImageButton pauseButton =
(ImageButton)findViewById(R.id.MediaPause);
+ pauseButton.setOnClickListener(this.onPauseClick);
+
+
this.callbackTrackPositionsUpdateHandler.postDelayed(callbackTrackPositionsUpdateRunnable,500);
+
+ Intent intent = new Intent(PlayerBPMControl.this,
org.musikcube.Service.class);
+ intent.putExtra("org.musikcube.Service.action", "bpmstart");
+ startService(intent);
+ }
+
+ private OnClickListener onNextClick = new OnClickListener() {
+ public void onClick(View v){
+ Intent intent = new Intent(PlayerBPMControl.this,
org.musikcube.Service.class);
+ intent.putExtra("org.musikcube.Service.action", "next");
+ startService(intent);
+ }
+ };
+ private OnClickListener onPauseClick = new OnClickListener() {
+ public void onClick(View v){
+ Intent intent = new Intent(PlayerBPMControl.this,
org.musikcube.Service.class);
+ intent.putExtra("org.musikcube.Service.action", "stop");
+ startService(intent);
+ }
+ };
+
+ public void OnTrackBufferUpdate(int percent) {
+
this.callbackTrackPositionsUpdateHandler.post(this.callbackTrackPositionsUpdateRunnable);
+ }
+ public void OnTrackPositionUpdate(int secondsPlayed) {
+
this.callbackTrackPositionsUpdateHandler.post(this.callbackTrackPositionsUpdateRunnable);
+ }
+ public void OnTrackUpdate() {
+ this.callbackTrackUpdateHandler.post(this.callbackTrackUpdateRunnable);
+ }
+
+ @Override
+ protected void onPause() {
+ this.enable = false;
+ Log.v("MC2::PC","OnPause");
+ Player.GetInstance().SetUpdateListener(null);
+ super.onPause();
+ }
+ @Override
+ protected void onResume() {
+ this.enable = true;
+ Log.v("MC2::PC","OnResume");
+ Player.GetInstance().SetUpdateListener(this);
+ super.onResume();
+ this.OnUpdateTrackPositionsUI();
+ this.OnUpdateTrackUI();
+ }
+
+ // Need handler for callbacks to the UI thread
+ final Handler callbackTrackUpdateHandler = new Handler();
+ // Create runnable for posting
+ final Runnable callbackTrackUpdateRunnable = new Runnable() {
+ public void run() {
+ OnUpdateTrackUI();
+ }
+ };
+
+ public void OnUpdateTrackUI() {
+ TextView titleView = (TextView)findViewById(R.id.TrackTitle);
+ TextView albumView = (TextView)findViewById(R.id.TrackAlbum);
+ TextView artistView = (TextView)findViewById(R.id.TrackArtist);
+ TextView durationView = (TextView)findViewById(R.id.TrackDuration);
+
+ int thumbnailId = 0;
+
+ synchronized(lock){
+
+ this.track = Player.GetInstance().GetCurrentTrack();
+ if(this.track==null){
+ this.track = new Track();
+ }
+
+ String thumbnailString = this.track.metadata.get("thumbnail_id");
+ if(thumbnailString!=null){
+ thumbnailId = Integer.parseInt(thumbnailString);
+ }
+
+ String title = this.track.metadata.get("title");
+ if(title==null){
+ titleView.setText("Title:");
+ }else{
+ titleView.setText("Title: "+title);
+ }
+ String album = this.track.metadata.get("album");
+ if(album==null){
+ albumView.setText("Album:");
+ }else{
+ albumView.setText("Album: "+album);
+ }
+ String artist = this.track.metadata.get("visual_artist");
+ if(artist==null){
+ artistView.setText("Artist:");
+ }else{
+ artistView.setText("Artist: "+artist);
+ }
+
+ String duration = this.track.metadata.get("duration");
+ if(duration==null){
+ this.duration = 0;
+ }else{
+ this.duration = Integer.parseInt(duration);
+ }
+ int minutes = (int)Math.floor(this.duration/60);
+ int seconds = this.duration-minutes*60;
+ String durationText = Integer.toString(minutes)+":";
+ if(seconds<10){ durationText += "0"; }
+ durationText += Integer.toString(seconds);
+ durationView.setText(durationText);
+ }
+
+ // clear image
+ if(this.currentAlbumCoverId!=thumbnailId){
+ this.currentAlbumCoverId=thumbnailId;
+ ImageView cover = (ImageView)findViewById(R.id.AlbumCover);
+ cover.setImageResource(R.drawable.album);
+
+ if(thumbnailId!=0){
+ // Load image
+ Library library = Library.GetInstance();
+ new
DownloadAlbumCoverTask().execute("http://"+library.host+":"+library.httpPort+"/cover/?cover_id="+thumbnailId);
+ }
+ }
+
+ }
+
+ private class DownloadAlbumCoverTask extends
AsyncTask<String,Integer,Bitmap>{
+
+ protected Bitmap doInBackground(String... params) {
+ try {
+ URL url = new URL(params[0]);
+ HttpURLConnection conn= (HttpURLConnection)url.openConnection();
+ conn.setDoInput(true);
+ conn.connect();
+ //int length = conn.getContentLength();
+ InputStream is = conn.getInputStream();
+ Bitmap bm = BitmapFactory.decodeStream(is);
+ return bm;
+ } catch (Exception e) {
+ Log.v("mC2:PLAYER","Error "+e.getMessage());
+// e.printStackTrace();
+ return null;
+ }
+ }
+
+ protected void onPostExecute(Bitmap result){
+ if(result==null){
+ }else{
+ ImageView cover = (ImageView)findViewById(R.id.AlbumCover);
+ cover.setImageBitmap(result);
+ }
+ }
+ }
+
+ // Need handler for callbacks to the UI thread
+ final Handler callbackTrackPositionsUpdateHandler = new Handler();
+ // Create runnable for posting
+ final Runnable callbackTrackPositionsUpdateRunnable = new Runnable() {
+ public void run() {
+ OnUpdateTrackPositionsUI();
+ }
+ };
+
+ public void OnUpdateTrackPositionsUI() {
+ if(this.enable){
+ int msPosition = Player.GetInstance().GetTrackPosition();
+ int position = msPosition/1000;
+ int minutes = (int)Math.floor(position/60);
+ int seconds = position-minutes*60;
+ String positionText = Integer.toString(minutes)+":";
+ if(seconds<10){ positionText += "0"; }
+ positionText += Integer.toString(seconds);
+ TextView positionView = (TextView)findViewById(R.id.TrackPosition);
+ positionView.setText(positionText);
+
+ SeekBar seekBar = (SeekBar)findViewById(R.id.TrackProgress);
+ synchronized (this.lock) {
+ if(this.duration==0){
+ seekBar.setProgress(0);
+ }else{
+ seekBar.setProgress(msPosition/this.duration);
+ }
+ seekBar.setSecondaryProgress(10*Player.GetInstance().GetTrackBuffer());
+ }
+ }
+
+ // Next callback in 0.5 seconds
+
this.callbackTrackPositionsUpdateHandler.postDelayed(callbackTrackPositionsUpdateRunnable,500);
+
+ }
+
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.default_menu, menu);
+ return true;
+ }
+
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if(Helper.DefaultOptionsItemSelected(item,this)){
+ return true;
+ }else{
+ return super.onContextItemSelected(item);
+ }
+ }
+
+}
=======================================
--- /trunk/src/android/src/org/musikcube/BPMControl.java Sun Aug 16
15:27:03 2009
+++ /dev/null
@@ -1,249 +0,0 @@
-package org.musikcube;
-
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import org.musikcube.core.Library;
-import org.musikcube.core.Player;
-import org.musikcube.core.Track;
-import org.musikcube.core.Player.OnTrackUpdateListener;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.widget.ImageView;
-import android.widget.SeekBar;
-import android.widget.TextView;
-
-public class BPMControl extends Activity implements OnTrackUpdateListener {
-
- private Track track = new Track();
- private int duration = 0;
- private Object lock = new Object();
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- Log.v("MC2::PC","OnCreate");
- super.onCreate(savedInstanceState);
- setContentView(R.layout.play_control);
-/*
- ImageButton nextButton = (ImageButton)findViewById(R.id.MediaNext);
- nextButton.setOnClickListener(this.onNextClick);
- ImageButton pauseButton =
(ImageButton)findViewById(R.id.MediaPause);
- pauseButton.setOnClickListener(this.onPauseClick);
- */
-
this.callbackTrackPositionsUpdateHandler.postDelayed(callbackTrackPositionsUpdateRunnable,500);
- }
-/*
- private OnClickListener onNextClick = new OnClickListener() {
- public void onClick(View v){
- Intent intent = new Intent(PlayerControl.this,
org.musikcube.Service.class);
- intent.putExtra("org.musikcube.Service.action", "next");
- startService(intent);
- }
- };
- private OnClickListener onPauseClick = new OnClickListener() {
- public void onClick(View v){
- Intent intent = new Intent(PlayerControl.this,
org.musikcube.Service.class);
- intent.putExtra("org.musikcube.Service.action", "stop");
- startService(intent);
- }
- };
-*/
- public void OnTrackBufferUpdate(int percent) {
- synchronized(lock){
- }
-
this.callbackTrackPositionsUpdateHandler.post(this.callbackTrackPositionsUpdateRunnable);
- }
- public void OnTrackPositionUpdate(int secondsPlayed) {
- synchronized(lock){
- }
-
this.callbackTrackPositionsUpdateHandler.post(this.callbackTrackPositionsUpdateRunnable);
- }
- public void OnTrackUpdate() {
- this.callbackTrackUpdateHandler.post(this.callbackTrackUpdateRunnable);
- }
-
-
- @Override
- protected void onPause() {
- Log.v("MC2::PC","OnPause");
- Player.GetInstance().SetUpdateListener(null);
- super.onPause();
- }
- @Override
- protected void onResume() {
- Log.v("MC2::PC","OnResume");
- Player.GetInstance().SetUpdateListener(this);
- super.onResume();
- }
-
- // Need handler for callbacks to the UI thread
- final Handler callbackTrackUpdateHandler = new Handler();
- // Create runnable for posting
- final Runnable callbackTrackUpdateRunnable = new Runnable() {
- public void run() {
- OnUpdateTrackUI();
- }
- };
-
- public void OnUpdateTrackUI() {
- TextView titleView = (TextView)findViewById(R.id.TrackTitle);
- TextView albumView = (TextView)findViewById(R.id.TrackAlbum);
- TextView artistView = (TextView)findViewById(R.id.TrackArtist);
- TextView durationView = (TextView)findViewById(R.id.TrackDuration);
-
- int thumbnailId = 0;
-
- synchronized(lock){
-
- this.track = Player.GetInstance().GetCurrentTrack();
- if(this.track==null){
- this.track = new Track();
- }
-
- String thumbnailString = this.track.metadata.get("thumbnail_id");
- if(thumbnailString!=null){
- thumbnailId = Integer.parseInt(thumbnailString);
- }
-
- String title = this.track.metadata.get("title");
- if(title==null){
- titleView.setText("Title:");
- }else{
- titleView.setText("Title: "+title);
- }
- String album = this.track.metadata.get("album");
- if(album==null){
- albumView.setText("Album:");
- }else{
- albumView.setText("Album: "+album);
- }
- String artist = this.track.metadata.get("visual_artist");
- if(artist==null){
- artistView.setText("Artist:");
- }else{
- artistView.setText("Artist: "+artist);
- }
-
- String duration = this.track.metadata.get("duration");
- if(duration==null){
- this.duration = 0;
- }else{
- this.duration = Integer.parseInt(duration);
- }
- int minutes = (int)Math.floor(this.duration/60);
- int seconds = this.duration-minutes*60;
- String durationText = Integer.toString(minutes)+":";
- if(seconds<10){ durationText += "0"; }
- durationText += Integer.toString(seconds);
- durationView.setText(durationText);
- }
-
- // clear image
- ImageView cover = (ImageView)findViewById(R.id.AlbumCover);
- cover.setImageResource(R.drawable.album);
-
- if(thumbnailId!=0){
- // Load image
- Library library = Library.GetInstance();
- new
DownloadAlbumCoverTask().execute("http://"+library.host+":"+library.httpPort+"/cover/?cover_id="+thumbnailId);
- }
-
- }
-
- private class DownloadAlbumCoverTask extends
AsyncTask<String,Integer,Bitmap>{
-
- protected Bitmap doInBackground(String... params) {
- try {
- URL url = new URL(params[0]);
- HttpURLConnection conn= (HttpURLConnection)url.openConnection();
- conn.setDoInput(true);
- conn.connect();
- //int length = conn.getContentLength();
- InputStream is = conn.getInputStream();
- Bitmap bm = BitmapFactory.decodeStream(is);
- return bm;
- } catch (Exception e) {
- Log.v("mC2:PLAYER","Error "+e.getMessage());
-// e.printStackTrace();
- return null;
- }
- }
-
- protected void onPostExecute(Bitmap result){
- if(result==null){
- }else{
- ImageView cover = (ImageView)findViewById(R.id.AlbumCover);
- cover.setImageBitmap(result);
- }
- }
- }
-
- // Need handler for callbacks to the UI thread
- final Handler callbackTrackPositionsUpdateHandler = new Handler();
- // Create runnable for posting
- final Runnable callbackTrackPositionsUpdateRunnable = new Runnable() {
- public void run() {
- OnUpdateTrackPositionsUI();
- }
- };
-
- public void OnUpdateTrackPositionsUI() {
- int msPosition = Player.GetInstance().GetTrackPosition();
- int position = msPosition/1000;
- int minutes = (int)Math.floor(position/60);
- int seconds = position-minutes*60;
- String positionText = Integer.toString(minutes)+":";
- if(seconds<10){ positionText += "0"; }
- positionText += Integer.toString(seconds);
- TextView positionView = (TextView)findViewById(R.id.TrackPosition);
- positionView.setText(positionText);
-
- SeekBar seekBar = (SeekBar)findViewById(R.id.TrackProgress);
- synchronized (this.lock) {
- if(this.duration==0){
- seekBar.setProgress(0);
- }else{
- seekBar.setProgress(msPosition/this.duration);
- }
- seekBar.setSecondaryProgress(10*Player.GetInstance().GetTrackBuffer());
- }
-
- // Next callback in 0.5 seconds
-
this.callbackTrackPositionsUpdateHandler.postDelayed(callbackTrackPositionsUpdateRunnable,500);
-
- }
-
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.default_menu, menu);
- return true;
- }
-
- public boolean onOptionsItemSelected(MenuItem item) {
-
//Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
- switch (item.getItemId()) {
- case R.id.context_settings:
- startActivity(new Intent(this, org.musikcube.Preferences.class));
- return true;
- case R.id.context_browse:
- startActivity(new Intent(this, org.musikcube.main.class));
- return true;
- case R.id.context_controls:
- startActivity(new Intent(this, org.musikcube.PlayerControl.class));
- return true;
- default:
- return super.onContextItemSelected(item);
- }
- }
-
-}
=======================================
--- /trunk/src/android/AndroidManifest.xml Wed Aug 26 12:20:37 2009
+++ /trunk/src/android/AndroidManifest.xml Sat Aug 29 14:20:13 2009
@@ -3,7 +3,7 @@
package="org.musikcube"
android:versionCode="1"
android:versionName="1.0">
- <application android:icon="@drawable/icon"
android:label="@string/app_name" android:name="App"
android:debuggable="true">
+ <application android:icon="@drawable/icon"
android:label="@string/app_name" android:name="App"
android:debuggable="false">
<activity android:name=".main"
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
@@ -17,6 +17,8 @@
<activity android:name="Preferences"></activity>
<activity android:name="PlayerControl"
android:launchMode="singleTask"></activity>
<activity android:name="NowPlayingList"
android:launchMode="singleTask"></activity>
+<activity android:name="PlayerBPMControl" android:launchMode="singleTask"
android:screenOrientation="portrait"></activity>
+<activity android:name="CategorySelect"
android:launchMode="singleTask"></activity>
</application>
<uses-sdk android:minSdkVersion="3" />
=======================================
--- /trunk/src/android/res/drawable/mc_notify.png Wed Jul 29 15:56:39 2009
+++ /trunk/src/android/res/drawable/mc_notify.png Sat Aug 29 14:20:13 2009
Binary file, no diff available.
=======================================
--- /trunk/src/android/res/layout/category_list_item.xml Mon Aug 24
23:16:59 2009
+++ /trunk/src/android/res/layout/category_list_item.xml Sat Aug 29
14:20:13 2009
@@ -5,8 +5,6 @@
android:layout_height="fill_parent">
<TextView android:id="@+id/text"
- android:layout_width="0dip"
- android:layout_weight="1.0"
- android:layout_height="wrap_content" android:textSize="28sp"
android:fadingEdge="horizontal" android:maxLines="1"
android:fadingEdgeLength="10sp"/>
+ android:layout_height="wrap_content" android:textSize="28sp"
android:fadingEdge="horizontal" android:maxLines="1"
android:fadingEdgeLength="10sp" android:layout_width="wrap_content"/>
</LinearLayout>
=======================================
--- /trunk/src/android/res/layout/now_playing_list_item.xml Wed Aug 26
12:20:37 2009
+++ /trunk/src/android/res/layout/now_playing_list_item.xml Sat Aug 29
14:20:13 2009
@@ -3,17 +3,17 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
+<ImageView android:id="@+id/PlayingImage" android:layout_height="32sp"
android:layout_width="32sp"></ImageView>
<TextView android:id="@+id/track"
android:layout_width="32sp"
android:layout_height="wrap_content" android:textSize="24sp"
android:fadingEdge="horizontal" android:maxLines="1"
android:fadingEdgeLength="10sp"/>
<LinearLayout
android:layout_height="wrap_content"
android:orientation="vertical" android:layout_width="wrap_content">
<TextView android:id="@+id/title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" android:textSize="24sp"
android:fadingEdge="horizontal" android:maxLines="1"
android:fadingEdgeLength="10sp" android:hint="...."/>
+ android:layout_height="wrap_content" android:textSize="24sp"
android:fadingEdge="horizontal" android:maxLines="1"
android:fadingEdgeLength="10sp" android:hint="...."
android:layout_width="wrap_content"/>
<TextView android:id="@+id/artist"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
android:fadingEdge="horizontal" android:maxLines="1"
android:fadingEdgeLength="10sp" android:textColor="#999999"
android:textSize="16sp"/>
+ android:layout_height="wrap_content"
android:fadingEdge="horizontal" android:maxLines="1"
android:fadingEdgeLength="10sp" android:textColor="#999999"
android:textSize="16sp" android:layout_width="wrap_content"/>
</LinearLayout>
+
</LinearLayout>
=======================================
--- /trunk/src/android/res/layout/play_control.xml Wed Aug 26 13:18:09 2009
+++ /trunk/src/android/res/layout/play_control.xml Sat Aug 29 14:20:13 2009
@@ -14,8 +14,6 @@
<ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/MediaRepeat"
android:src="@drawable/ic_repeat" android:adjustViewBounds="true"
android:padding="10sp"></ImageButton>
<ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:adjustViewBounds="true"
android:padding="10sp" android:id="@+id/MediaShuffle"
android:src="@drawable/ic_shuffle"></ImageButton>
</LinearLayout>
-
-
</LinearLayout>
<LinearLayout android:id="@+id/LinearLayout01"
android:layout_height="wrap_content" android:orientation="vertical"
android:gravity="left" android:layout_width="wrap_content"
android:layout_gravity="left" android:paddingLeft="20sp">
=======================================
--- /trunk/src/android/res/layout-land/play_control.xml Wed Aug 26 13:18:09
2009
+++ /trunk/src/android/res/layout-land/play_control.xml Sat Aug 29 14:20:13
2009
@@ -7,9 +7,15 @@
android:paddingRight="8dp" android:gravity="center_vertical">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content" android:orientation="horizontal"
android:gravity="center_vertical|center_horizontal">
+<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content">
<FrameLayout android:id="@+id/FrameLayout01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="10sp" android:padding="2sp"
android:background="#666666">
<ImageView android:src="@drawable/album" android:layout_marginTop="5sp"
android:layout_marginBottom="5sp" android:layout_height="200sp"
android:layout_width="200sp" android:scaleType="fitXY"
android:id="@+id/AlbumCover" android:background="#000000"></ImageView>
</FrameLayout>
+ <LinearLayout android:id="@+id/LinearLayout01"
android:layout_height="wrap_content" android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical">
+ <ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/MediaRepeat"
android:src="@drawable/ic_repeat" android:adjustViewBounds="true"
android:padding="10sp"></ImageButton>
+ <ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:adjustViewBounds="true"
android:padding="10sp" android:id="@+id/MediaShuffle"
android:src="@drawable/ic_shuffle"></ImageButton>
+ </LinearLayout>
+</LinearLayout>
<LinearLayout android:id="@+id/LinearLayout01"
android:layout_height="wrap_content" android:orientation="vertical"
android:layout_width="wrap_content">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="24sp"
android:id="@+id/TrackTitle" android:text="Title:"
android:lines="1"></TextView>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Album:"
android:id="@+id/TrackAlbum" android:lines="1"></TextView>
=======================================
--- /trunk/src/android/res/menu/default_menu.xml Wed Aug 26 12:20:37 2009
+++ /trunk/src/android/res/menu/default_menu.xml Sat Aug 29 14:20:13 2009
@@ -3,4 +3,5 @@
<item android:title="@string/menu_controls"
android:id="@+id/context_controls" android:enabled="true"
android:visible="true" android:icon="@drawable/ic_menu_play"></item>
<item android:title="@string/menu_settings"
android:id="@+id/context_settings" android:enabled="true"
android:visible="true" android:icon="@drawable/ic_menu_preferences"></item>
<item android:id="@+id/context_nowplaying"
android:title="@string/menu_nowplaying"
android:icon="@drawable/ic_menu_nowplaying"></item>
+<item android:id="@+id/context_help" android:title="@string/menu_help"
android:icon="@drawable/ic_menu_help"></item>
</menu>
=======================================
--- /trunk/src/android/res/values/strings.xml Wed Aug 26 12:20:37 2009
+++ /trunk/src/android/res/values/strings.xml Sat Aug 29 14:20:13 2009
@@ -19,4 +19,6 @@
<string name="menu_controls">Player controls</string>
<string name="menu_browse">Browse</string>
<string name="menu_nowplaying">Now playing</string>
+<string name="help_main">musikCube is a application that connects to you
musikServer that you have installed on your desktop/server computer. Once
musikCube is connected you are able to browse and play all your music
directly on your phone without having to copy them to you SD card.</string>
+
</resources>
=======================================
--- /trunk/src/android/src/doep/xml/Reader.java Wed Jul 29 15:56:39 2009
+++ /trunk/src/android/src/doep/xml/Reader.java Sat Aug 29 14:20:13 2009
@@ -6,10 +6,10 @@
import java.lang.Exception;
-public class Reader extends ReaderNode {
- private InputStream stream;
- private org.xmlpull.v1.XmlPullParser parser;
- private java.util.LinkedList<ReaderNode> nodeLevels = new
java.util.LinkedList<ReaderNode>();
+public final class Reader extends ReaderNode {
+ private final InputStream stream;
+ private final org.xmlpull.v1.XmlPullParser parser;
+ private final java.util.LinkedList<ReaderNode> nodeLevels = new
java.util.LinkedList<ReaderNode>();
public ReaderNode currentNode;
private boolean firstParse = true;
@@ -33,7 +33,7 @@
}
- public void Parse()
+ public final void Parse()
throws Exception
{
int eventType = 0;
=======================================
--- /trunk/src/android/src/doep/xml/ReaderNode.java Wed Jul 29 15:56:39 2009
+++ /trunk/src/android/src/doep/xml/ReaderNode.java Sat Aug 29 14:20:13 2009
@@ -3,10 +3,10 @@
public class ReaderNode {
- public String name = "";
+ public final String name;
public boolean ended = false;
public String content = "";
- public ReaderNode parent;
+ public final ReaderNode parent;
public Reader reader;
public int level = 1;
@@ -25,7 +25,7 @@
* @param attribute
* @return String or null
*/
- public String Attribute(String attribute){
+ public final String Attribute(String attribute){
return this.attributes.get(attribute);
}
@@ -34,7 +34,7 @@
* @param name Name of node to be found
* @return ReaderNode if found, or null if this goes out of scope
*/
- public ReaderNode ChildNode(String name)
+ public final ReaderNode ChildNode(String name)
throws Exception
{
//Log.v("doep::ReaderNode::ChildNode","Node: "+name+"
ended: "+this.ended);
@@ -59,7 +59,7 @@
return null;
}
- public void End()
+ public final void End()
throws Exception
{
while(!this.ended){
@@ -73,7 +73,7 @@
* Wait for a childnode
* @return ReaderNode if found, or null if this goes out of scope
*/
- public ReaderNode ChildNode()
+ public final ReaderNode ChildNode()
throws Exception
{
while(!this.ended){
=======================================
--- /trunk/src/android/src/doep/xml/Writer.java Wed Jul 29 15:56:39 2009
+++ /trunk/src/android/src/doep/xml/Writer.java Sat Aug 29 14:20:13 2009
@@ -1,10 +1,10 @@
package doep.xml;
-public class Writer extends WriterNode {
+public final class Writer extends WriterNode {
public String buffer;
- private java.io.OutputStream stream;
+ private final java.io.OutputStream stream;
public Writer(java.io.OutputStream stream){
super("",null);
@@ -14,7 +14,7 @@
this.state = 1;
}
- public void Write(String content)
+ public final void Write(String content)
throws java.io.IOException
{
//Log.v("doep.xml.Writer","Write "+content);
@@ -22,13 +22,13 @@
// this.buffer += content;
}
- public void Flush()
+ public final void Flush()
throws java.io.IOException
{
this.Flush(false);
}
- public void Flush(boolean writeNull)
+ public final void Flush(boolean writeNull)
throws java.io.IOException
{
//Log.v("doep.xml.Writer","Flush "+writeNull);
=======================================
--- /trunk/src/android/src/doep/xml/WriterNode.java Sun Jul 5 14:53:29 2009
+++ /trunk/src/android/src/doep/xml/WriterNode.java Sat Aug 29 14:20:13 2009
@@ -4,12 +4,12 @@
import java.util.Map;
public class WriterNode {
- public String name = "";
+ public final String name;
public String content = "";
protected WriterNode parent;
protected Writer writer;
- private java.util.List<WriterNode> children = new
java.util.LinkedList<WriterNode>();
- public java.util.SortedMap<String,String> attributes = new
java.util.TreeMap<String,String>();
+ private final java.util.List<WriterNode> children = new
java.util.LinkedList<WriterNode>();
+ public final java.util.SortedMap<String,String> attributes = new
java.util.TreeMap<String,String>();
protected int state = 0;
@@ -27,7 +27,7 @@
return newNode;
}
- public void End()
+ public final void End()
throws java.io.IOException
{
if(this.parent.state==0){
@@ -61,7 +61,7 @@
}
}
- protected void WriteStartTag()
+ protected final void WriteStartTag()
throws java.io.IOException
{
if(this.state==0){
=======================================
--- /trunk/src/android/src/org/musikcube/CategoryList.java Wed Aug 26
12:20:37 2009
+++ /trunk/src/android/src/org/musikcube/CategoryList.java Sat Aug 29
14:20:13 2009
@@ -5,6 +5,7 @@
import java.util.ArrayList;
+import org.musikcube.TrackListBase.TrackViewHolder;
import org.musikcube.core.IQuery;
import org.musikcube.core.ListQuery;
import org.musikcube.core.IQuery.OnQueryResultListener;
@@ -20,6 +21,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
@@ -46,6 +48,10 @@
OnResults();
}
};
+
+ static class CategoryViewHolder{
+ TextView title;
+ }
public class ResultAdapter extends BaseAdapter{
@@ -84,15 +90,21 @@
}
public View getView(int position, View view, ViewGroup parent) {
+ final CategoryViewHolder holder;
if(view==null){
view = inflator.inflate(R.layout.category_list_item, null);
+ holder = new CategoryViewHolder();
+ holder.title = (TextView) view.findViewById(R.id.text);
+ view.setTag(holder);
+ }else{
+ holder = (CategoryViewHolder)view.getTag();
}
//
if(position==0){
- ((TextView) view.findViewById(R.id.text)).setText("- All -");
+ holder.title.setText("- All -");
}else{
- ((TextView)
view.findViewById(R.id.text)).setText(this.query.resultsStrings.get(position-1));
+ holder.title.setText(this.query.resultsStrings.get(position-1));
}
return view;
}
@@ -230,22 +242,10 @@
}
public boolean onOptionsItemSelected(MenuItem item) {
-
//Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
- switch (item.getItemId()) {
- case R.id.context_settings:
- startActivity(new Intent(this, org.musikcube.Preferences.class));
- return true;
- case R.id.context_browse:
- startActivity(new Intent(this, org.musikcube.main.class));
- return true;
- case R.id.context_controls:
- startActivity(new Intent(this, org.musikcube.PlayerControl.class));
- return true;
- case R.id.context_nowplaying:
- startActivity(new Intent(this, org.musikcube.NowPlayingList.class));
- return true;
- default:
- return super.onContextItemSelected(item);
- }
+ if(Helper.DefaultOptionsItemSelected(item,this)){
+ return true;
+ }else{
+ return super.onContextItemSelected(item);
+ }
}
}
=======================================
--- /trunk/src/android/src/org/musikcube/NowPlayingList.java Wed Aug 26
12:20:37 2009
+++ /trunk/src/android/src/org/musikcube/NowPlayingList.java Sat Aug 29
14:20:13 2009
@@ -28,11 +28,11 @@
final static public int ADD_ALL_ID = 2;
final static public int REMOVE_ID = 3;
- public int position = 0;
-
@Override
protected void onCreate(Bundle savedInstanceState){
+ this.markPosition = true;
+
this.trackListViewId = R.layout.now_playing_list;
this.trackListItemViewId = R.layout.now_playing_list_item;
@@ -74,6 +74,11 @@
intent.putExtra("org.musikcube.Service.action", "appendlist");
startService(intent);
return true;
+ case REMOVE_ID:
+ intent.putExtra("org.musikcube.Service.action", "remove_from_list");
+ intent.putExtra("org.musikcube.Service.position", info.position);
+ startService(intent);
+ return true;
default:
return super.onContextItemSelected(item);
}
@@ -86,6 +91,7 @@
menu.add(0, PLAY_THIS_ID, 0, "Play this track");
menu.add(0, ADD_THIS_ID, 0, "Add this to current playlist");
menu.add(0, ADD_ALL_ID, 0, "Add all to current playlist");
+ menu.add(0, REMOVE_ID, 0, "Remove from playlist");
}
public void OnTrackListPositionUpdate() {
@@ -104,7 +110,6 @@
}
this.callbackHandler.post(this.callbackRunnable);
}
-
@Override
@@ -117,6 +122,8 @@
protected void onResume() {
super.onResume();
Player.GetInstance().SetListUpdateListener(this);
+ this.position = Player.GetInstance().GetPosition();
+ this.setSelection(this.position);
}
=======================================
--- /trunk/src/android/src/org/musikcube/PlayerControl.java Thu Aug 27
00:58:26 2009
+++ /trunk/src/android/src/org/musikcube/PlayerControl.java Sat Aug 29
14:20:13 2009
@@ -287,23 +287,11 @@
}
public boolean onOptionsItemSelected(MenuItem item) {
-
//Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
- switch (item.getItemId()) {
- case R.id.context_settings:
- startActivity(new Intent(this, org.musikcube.Preferences.class));
- return true;
- case R.id.context_browse:
- startActivity(new Intent(this, org.musikcube.main.class));
- return true;
- case R.id.context_controls:
- startActivity(new Intent(this, org.musikcube.PlayerControl.class));
- return true;
- case R.id.context_nowplaying:
- startActivity(new Intent(this, org.musikcube.NowPlayingList.class));
- return true;
- default:
- return super.onContextItemSelected(item);
- }
+ if(Helper.DefaultOptionsItemSelected(item,this)){
+ return true;
+ }else{
+ return super.onContextItemSelected(item);
+ }
}
}
=======================================
--- /trunk/src/android/src/org/musikcube/Service.java Wed Aug 26 12:20:37
2009
+++ /trunk/src/android/src/org/musikcube/Service.java Sat Aug 29 14:20:13
2009
@@ -92,6 +92,10 @@
Player player = Player.GetInstance();
player.Append(intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist"));
}
+ if(action.equals("remove_from_list")){
+ Player player = Player.GetInstance();
+
player.RemoveFromList(intent.getIntExtra("org.musikcube.Service.position",
-1));
+ }
if(action.equals("playlist_prepare")){
Player player = Player.GetInstance();
@@ -109,6 +113,9 @@
if(action.equals("stop")){
Player player = Player.GetInstance();
player.Stop();
+ if(this.paceDetector!=null){
+ this.paceDetector.StopSensor(this);
+ }
}
if(action.equals("play")){
Player player = Player.GetInstance();
@@ -119,6 +126,7 @@
this.stopSelf();
}
if(action.equals("bpmstart")){
+ Player.GetInstance().SetBPMMode(true);
if(this.paceDetector==null){
this.paceDetector = new PaceDetector();
this.paceDetector.StartSensor(this);
@@ -157,7 +165,7 @@
contentText += trackArtist;
}
}
- Intent notificationIntent = new Intent(this, PlayerControl.class);
+ Intent notificationIntent = new Intent(this,
Player.GetInstance().GetBPMMode()?PlayerBPMControl.class:PlayerControl.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.flags |= Notification.FLAG_ONGOING_EVENT|
Notification.FLAG_NO_CLEAR;
=======================================
--- /trunk/src/android/src/org/musikcube/TrackListBase.java Wed Aug 26
12:20:37 2009
+++ /trunk/src/android/src/org/musikcube/TrackListBase.java Sat Aug 29
14:20:13 2009
@@ -20,6 +20,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
@@ -39,6 +40,9 @@
protected java.lang.Object lock = new java.lang.Object();
+ protected int position = -1;
+ protected boolean markPosition = false;
+
// Need handler for callbacks to the UI thread
final Handler callbackHandler = new Handler();
@@ -53,6 +57,7 @@
TextView track;
TextView title;
TextView artist;
+ ImageView marker;
}
public class ResultAdapter extends BaseAdapter{
@@ -82,17 +87,28 @@
public View getView(int position, View view, ViewGroup parent) {
TrackViewHolder holder;
if(view==null){
- view = inflator.inflate(R.layout.track_list_item, null);
+ view = inflator.inflate(TrackListBase.this.trackListItemViewId, null);
holder = new TrackViewHolder();
holder.title = (TextView) view.findViewById(R.id.title);
holder.track = (TextView) view.findViewById(R.id.track);
holder.artist = (TextView) view.findViewById(R.id.artist);
+ if(TrackListBase.this.markPosition){
+ holder.marker = (ImageView) view.findViewById(R.id.PlayingImage);
+ }
view.setTag(holder);
}else{
holder = (TrackViewHolder)view.getTag();
}
+
+ if(holder.marker!=null){
+ if(position==this.trackList.position){
+ holder.marker.setImageResource(R.drawable.ic_playing);
+ }else{
+ holder.marker.setImageBitmap(null);
+ }
+ }
Track track = this.trackList.GetTrack(position);
if(track==null){
@@ -248,23 +264,11 @@
}
public boolean onOptionsItemSelected(MenuItem item) {
-
//Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
- switch (item.getItemId()) {
- case R.id.context_settings:
- startActivity(new Intent(this, org.musikcube.Preferences.class));
- return true;
- case R.id.context_browse:
- startActivity(new Intent(this, org.musikcube.main.class));
- return true;
- case R.id.context_controls:
- startActivity(new Intent(this, org.musikcube.PlayerControl.class));
- return true;
- case R.id.context_nowplaying:
- startActivity(new Intent(this, org.musikcube.NowPlayingList.class));
- return true;
- default:
- return super.onContextItemSelected(item);
- }
+ if(Helper.DefaultOptionsItemSelected(item,this)){
+ return true;
+ }else{
+ return super.onContextItemSelected(item);
+ }
}
}
=======================================
--- /trunk/src/android/src/org/musikcube/core/IQuery.java Wed Aug 5
16:16:30 2009
+++ /trunk/src/android/src/org/musikcube/core/IQuery.java Sat Aug 29
14:20:13 2009
@@ -24,7 +24,7 @@
protected WriterNode SendQueryNode(WriterNode parentNode)
{
- WriterNode queryNode = parentNode.ChildNode("query");
+ final WriterNode queryNode = parentNode.ChildNode("query");
queryNode.attributes.put("id",Integer.toString(this.id));
queryNode.attributes.put("uid",Integer.toString(this.uid));
queryNode.attributes.put("type",this.type);
=======================================
--- /trunk/src/android/src/org/musikcube/core/Library.java Wed Aug 26
01:15:01 2009
+++ /trunk/src/android/src/org/musikcube/core/Library.java Sat Aug 29
14:20:13 2009
@@ -18,7 +18,7 @@
* @author doy
*
*/
-public class Library implements Runnable{
+public final class Library implements Runnable{
// private String username;
// private String password;
@@ -67,7 +67,7 @@
public void OnLibraryStatusChange(int status);
}
- public void SetStatusListener(OnLibraryStatusListener statusListener){
+ public final void SetStatusListener(OnLibraryStatusListener
statusListener){
synchronized(this.status){
this.statusListener = statusListener;
if(this.statusListener!=null){
@@ -76,7 +76,7 @@
}
}
- private void SetStatus(int status){
+ private final void SetStatus(int status){
synchronized(this.status){
//Log.v("mC2::Lib","STATUS "+this.status);
this.status = status;
@@ -86,19 +86,19 @@
}
}
- public int GetStatus(){
+ public final int GetStatus(){
synchronized(this.status){
return this.status.intValue();
}
}
- public String GetHost(){
+ public final String GetHost(){
synchronized(this.notifier){
return this.host;
}
}
- public void AddPointer(){
+ public final void AddPointer(){
synchronized(this.notifier){
this.connections++;
@@ -114,7 +114,7 @@
this.notifier.notifyAll();
}
}
- public void RemovePointer(){
+ public final void RemovePointer(){
synchronized(this.notifier){
this.connections--;
if(this.connections==0){
@@ -127,7 +127,7 @@
}
- public void Startup(Context context){
+ public final void Startup(Context context){
this.context = context;
// Startup thread when the application sends the context for the first
time
@@ -136,7 +136,7 @@
this.thread.start();
}
- public void Restart(){
+ public final void Restart(){
synchronized(this.notifier){
this.running = false;
this.restart = true;
@@ -152,7 +152,7 @@
}
}
- public boolean Running(){
+ public final boolean Running(){
synchronized(this.notifier){
if(this.running==true){
return true;
@@ -161,7 +161,7 @@
return false;
}
- private class WriterThreadHelper implements Runnable{
+ private final class WriterThreadHelper implements Runnable{
private Thread thread;
private Library library;
public WriterThreadHelper(Library library){
@@ -169,7 +169,7 @@
this.thread = new Thread(this);
}
- public void Start(){
+ public final void Start(){
this.thread.start();
}
@@ -183,7 +183,7 @@
protected Library(){
}
- public void WaitForAuthroization(){
+ public final void WaitForAuthroization(){
// Log.v("Library::WaitForAuthroization","start");
synchronized (notifier) {
if(this.authorization.equals("")){
@@ -340,7 +340,7 @@
}
}
- public void WriteThread(WriterThreadHelper thread){
+ public final void WriteThread(WriterThreadHelper thread){
//Log.v("Library::WriteThread","Started");
this.SetStatus(STATUS_AUTHENTICATING);
@@ -426,7 +426,7 @@
//Log.v("Library::WriteThread","Ended");
}
- public void Exit(){
+ public final void Exit(){
synchronized(this.notifier){
this.exit = true;
this.running = false;
@@ -451,14 +451,14 @@
}
}
- public void AddQuery(IQuery query){
+ public final void AddQuery(IQuery query){
synchronized(this.sendQueryQueue){
this.sendQueryQueue.addLast(query);
this.sendQueryQueue.notifyAll();
}
}
- public String GetTrackURL(int trackId){
+ public final String GetTrackURL(int trackId){
synchronized (notifier) {
if(this.status==STATUS_CONNECTED){
String trackURL
= "http://"+this.host+":"+this.httpPort+"/track/?track_id="+trackId+"&auth_key="+this.authorization;
=======================================
--- /trunk/src/android/src/org/musikcube/core/ListQuery.java Thu Aug 20
14:19:13 2009
+++ /trunk/src/android/src/org/musikcube/core/ListQuery.java Sat Aug 29
14:20:13 2009
@@ -23,7 +23,7 @@
public void SendQuery(WriterNode node)
throws Exception
{
- WriterNode queryNode = this.SendQueryNode(node);
+ final WriterNode queryNode = this.SendQueryNode(node);
// List selections
WriterNode selectionsNode = queryNode.ChildNode("selections");
@@ -60,8 +60,11 @@
ReaderNode mdNode = null;
while( (mdNode=childNode.ChildNode("md"))!=null ){
mdNode.End();
- this.resultsInts.add(Integer.parseInt(mdNode.attributes.get("id")));
- this.resultsStrings.add(mdNode.content);
+ int resultId = Integer.parseInt(mdNode.attributes.get("id"));
+ if(resultId!=0){
+ this.resultsInts.add(resultId);
+ this.resultsStrings.add(mdNode.content);
+ }
}
}
}else if(childNode.name.equals("tracklist")){
@@ -85,7 +88,7 @@
}
}
- public void SelectData(String category,int selection){
+ public final void SelectData(String category,int selection){
this.selectionStrings.add(category);
this.selectionInts.add(selection);
}
=======================================
--- /trunk/src/android/src/org/musikcube/core/MetadataQuery.java Wed Aug 5
16:16:30 2009
+++ /trunk/src/android/src/org/musikcube/core/MetadataQuery.java Sat Aug 29
14:20:13 2009
@@ -5,9 +5,9 @@
public class MetadataQuery extends IQuery {
- public java.util.ArrayList<Integer> requestedTracks = new
java.util.ArrayList<Integer>();
- public java.util.ArrayList<String> requestedMetakeys = new
java.util.ArrayList<String>();
- public java.util.ArrayList<Track> resultTracks = new
java.util.ArrayList<Track>();
+ public final java.util.ArrayList<Integer> requestedTracks = new
java.util.ArrayList<Integer>();
+ public final java.util.ArrayList<String> requestedMetakeys = new
java.util.ArrayList<String>();
+ public final java.util.ArrayList<Track> resultTracks = new
java.util.ArrayList<Track>();
public MetadataQuery() {
super();
=======================================
--- /trunk/src/android/src/org/musikcube/core/PaceDetector.java Thu Aug 20
14:19:13 2009
+++ /trunk/src/android/src/org/musikcube/core/PaceDetector.java Sat Aug 29
14:20:13 2009
@@ -18,7 +18,7 @@
static public float MAX_BPM = 85;
static public float MIN_BPM = 40;
static public int WAVE_MEMORY = 20;
- static public int WAVE_MIN_CALC = 8;
+ static public int WAVE_MIN_CALC = 10;
static public float WAVE_MIN_BPM_DIFF = 120; // This is in miliseconds
static public int WAVE_COMPARE = 4;
static public int MIN_PLAYTIME = 20000; // Play at leased 20 seconds of a
track
@@ -53,80 +53,88 @@
}
if(this.lastDiff>=0 && diff<0){
- // this is a top on the curve
- this.beatTimes.add(android.os.SystemClock.elapsedRealtime());
- this.amplitude.add(this.currentMax-this.currentMin);
-
- // Reset the amplitude
- this.currentMin = value;
- this.currentMax = value;
-
- // only keep the last 10 waves
- while(this.beatTimes.size()>WAVE_MEMORY){
- this.beatTimes.remove(0);
- this.amplitude.remove(0);
- }
-
- // Lets calculate BPM
- long bpmSum = 0;
- //java.util.TreeSet<Long> bpms = new java.util.TreeSet<Long>();
- java.util.ArrayList<Long> bpms = new java.util.ArrayList<Long>();
- for(int i=0;i<this.beatTimes.size()-WAVE_COMPARE;i++){
- long orgSample = this.beatTimes.get(i);
- for(int j=i+1;j<i+WAVE_COMPARE;j++){
- //float bpmSample = 60000/(this.beatTimes.get(j)-orgSample);
- long bpmSample = this.beatTimes.get(j)-orgSample;
- //Log.v("MC2::C","s "+bpmSample);
- if(bpmSample>(60000/MAX_BPM) && bpmSample<(60000/MIN_BPM)){
- bpms.add(bpmSample);
- bpmSum += bpmSample;
+
+ // Amplitude must be at leased 5
+ if(this.currentMax-this.currentMin<7){
+ this.currentMin = value;
+ this.currentMax = value;
+// Log.v("APM","-- "+(this.currentMax-this.currentMin));
+ }else{
+// Log.v("APM","B "+(this.currentMax-this.currentMin));
+ // this is a top on the curve
+ this.beatTimes.add(android.os.SystemClock.elapsedRealtime());
+ this.amplitude.add(this.currentMax-this.currentMin);
+
+ // Reset the amplitude
+ this.currentMin = value;
+ this.currentMax = value;
+ // only keep the last 10 waves
+ while(this.beatTimes.size()>WAVE_MEMORY){
+ this.beatTimes.remove(0);
+ this.amplitude.remove(0);
+ }
+
+ // Lets calculate BPM
+ long bpmSum = 0;
+ //java.util.TreeSet<Long> bpms = new java.util.TreeSet<Long>();
+ java.util.ArrayList<Long> bpms = new java.util.ArrayList<Long>();
+ for(int i=0;i<this.beatTimes.size()-WAVE_COMPARE;i++){
+ long orgSample = this.beatTimes.get(i);
+ for(int j=i+1;j<i+WAVE_COMPARE;j++){
+ //float bpmSample = 60000/(this.beatTimes.get(j)-orgSample);
+ long bpmSample = this.beatTimes.get(j)-orgSample;
+ //Log.v("MC2::C","s "+bpmSample);
+ if(bpmSample>(60000/MAX_BPM) && bpmSample<(60000/MIN_BPM)){
+ bpms.add(bpmSample);
+ bpmSum += bpmSample;
+ }
}
}
- }
- Collections.sort(bpms);
- //Log.v("MC2::BEAT","B "+(bpms.size()));
-
- // Lets remove the most "off" samples and correct the AVG until we are
down to the desired "diff"
- boolean qualified = false;
- long bpmDiff = 0;
-
- while(!qualified && bpms.size()>=WAVE_MIN_CALC){
- Long first = bpms.get(0);
- Long last = bpms.get(bpms.size()-1);
- bpmDiff = last-first;
- int bpmSize = bpms.size();
-
-// Log.v("MC2::DIFF","diff "+bpmSize+" "+first+"-"+last+" diff="+bpmDiff);
-
- if(bpmDiff<WAVE_MIN_BPM_DIFF){
- qualified = true;
- }else{
- // Remove the element that is most far away from the average
- long avg = bpmSum/bpmSize;
- if(avg-first>last-avg){
- // Remove first
- bpmSum -= first;
- bpms.remove(0);
+ Collections.sort(bpms);
+ //Log.v("MC2::BEAT","B "+(bpms.size()));
+
+ // Lets remove the most "off" samples and correct the AVG until we
are down to the desired "diff"
+ boolean qualified = false;
+ long bpmDiff = 0;
+
+ while(!qualified && bpms.size()>=WAVE_MIN_CALC){
+ Long first = bpms.get(0);
+ Long last = bpms.get(bpms.size()-1);
+ bpmDiff = last-first;
+ int bpmSize = bpms.size();
+
+ // Log.v("MC2::DIFF","diff "+bpmSize+" "+first+"-"+last+" diff="+bpmDiff);
+
+ if(bpmDiff<WAVE_MIN_BPM_DIFF){
+ qualified = true;
}else{
- // Remove last
- bpmSum -= last;
- bpms.remove(bpms.size()-1);
+ // Remove the element that is most far away from the average
+ long avg = bpmSum/bpmSize;
+ if(avg-first>last-avg){
+ // Remove first
+ bpmSum -= first;
+ bpms.remove(0);
+ }else{
+ // Remove last
+ bpmSum -= last;
+ bpms.remove(bpms.size()-1);
+ }
}
}
- }
-
- if(qualified){
- // Get avg amplitude
- float amplitude = this.amplitude.get(0);
- for(int i=1;i<this.amplitude.size();i++){
- amplitude+=this.amplitude.get(i);
- }
- amplitude /= this.amplitude.size();
-
-
- this.currentBPM = ((float)60000*bpms.size())/((float)bpmSum);
- this.currentAccuracy = (100-bpmDiff)+bpms.size()*13+amplitude*5;
- PaceDetector.this.ChangeBPM(this.currentBPM,this.currentAccuracy);
+
+ if(qualified){
+ // Get avg amplitude
+ float amplitude = this.amplitude.get(0);
+ for(int i=1;i<this.amplitude.size();i++){
+ amplitude+=this.amplitude.get(i);
+ }
+ amplitude /= this.amplitude.size();
+
+
+ this.currentBPM = ((float)60000*bpms.size())/((float)bpmSum);
+ this.currentAccuracy = (100-bpmDiff)+bpms.size()*13+amplitude*5;
+ PaceDetector.this.ChangeBPM(this.currentBPM,this.currentAccuracy);
+ }
}
}
this.lastDiff = diff;
@@ -158,10 +166,13 @@
long currentTime = android.os.SystemClock.elapsedRealtime();
if(currentTime>this.currentBPMstart+MIN_PLAYTIME){
+ //Log.v("BPM","3 "+bpm);
// We have played more than minimum time
if(bpm>this.currentBPM+BPM_THRESHOLD ||
bpm<this.currentBPM-BPM_THRESHOLD){
+ Log.v("BPM","4 "+bpm);
// BPM has changed enough to switch track
+ this.currentBPMstart = currentTime;
this.currentBPM = bpm;
this.currentAccuracy = accuracy;
@@ -169,6 +180,8 @@
BPMQuery query = new BPMQuery();
query.queryForBPM = this.currentBPM;
query.SetResultListener(this);
+ Library.GetInstance().AddQuery(query);
+
}
}
@@ -197,6 +210,7 @@
public void OnQueryResults(IQuery query) {
BPMQuery bpmQuery = (BPMQuery)query;
+ Log.v("mC2::PaceDetector","Change tracks "+bpmQuery.trackList.size());
if(!bpmQuery.trackList.isEmpty()){
Intent intent = new Intent(this.context, org.musikcube.Service.class);
intent.putExtra("org.musikcube.Service.tracklist", bpmQuery.trackList);
=======================================
--- /trunk/src/android/src/org/musikcube/core/Player.java Thu Aug 27
00:58:26 2009
+++ /trunk/src/android/src/org/musikcube/core/Player.java Sat Aug 29
14:20:13 2009
@@ -1,18 +1,21 @@
package org.musikcube.core;
import java.util.ArrayList;
+import java.util.Random;
import org.musikcube.core.IQuery.OnQueryResultListener;
+import org.musikcube.core.TrackPlayer.OnTrackPrepareListener;
import android.content.Intent;
-public class Player implements TrackPlayer.OnTrackStatusListener,
OnQueryResultListener{
+public final class Player implements TrackPlayer.OnTrackStatusListener,
OnQueryResultListener, OnTrackPrepareListener{
private ArrayList<Integer> nowPlaying = new ArrayList<Integer>();
private int position = 0;
private boolean repeat = false;
private boolean shuffle = false;
+ private int nextShufflePosition = -1;
private Library library;
@@ -27,6 +30,8 @@
public android.app.Service service;
+ private boolean bpmMode = false;
+
public void run() {
}
@@ -44,6 +49,9 @@
synchronized(this.lock){
this.nowPlaying = playlist;
this.position = position;
+ if(this.listListener!=null){
+ this.listListener.OnTrackListUpdate();
+ }
}
this.Play();
@@ -64,12 +72,13 @@
this.nowPlaying = playlist;
this.position = position;
if(this.nextPlayer!=null){
+ this.nextPlayer.SetPrepareListener(null);
this.nextPlayer.SetListener(null);
this.nextPlayer.Stop();
}
this.playWhenPrepared = true;
this.nextPlayer = this.PrepareTrack(this.position);
- this.nextPlayer.SetListener(this);
+ this.nextPlayer.SetPrepareListener(this);
if(this.listListener!=null){
this.listListener.OnTrackListUpdate();
@@ -182,7 +191,18 @@
public void Next(){
synchronized(this.lock){
this.currentTrack = new Track();
- this.position++;
+
+ if(this.shuffle){
+ if(this.nextShufflePosition==-1){
+ Random rand = new Random();
+ this.position = rand.nextInt(this.nowPlaying.size());
+ }else{
+ this.position = this.nextShufflePosition;
+ this.nextShufflePosition = -1;
+ }
+ }else{
+ this.position++;
+ }
if(this.position>=this.nowPlaying.size()){
if(this.repeat){
@@ -205,8 +225,20 @@
public void Prev(){
synchronized(this.lock){
- this.currentTrack = new Track();
- this.position--;
+ this.currentTrack = new Track();
+
+ if(this.shuffle){
+ if(this.nextShufflePosition==-1){
+ Random rand = new Random();
+ this.position = rand.nextInt(this.nowPlaying.size());
+ }else{
+ this.position = this.nextShufflePosition;
+ this.nextShufflePosition = -1;
+ }
+ }else{
+ this.position--;
+ }
+
if(this.position<0){
this.position = 0;
}
@@ -322,7 +354,17 @@
public void OnTrackAlmostDone(TrackPlayer trackPlayer) {
synchronized(this.lock){
if(this.nextPlayer==null){
- this.nextPlayer = this.PrepareTrack(this.position+1);
+ if(this.shuffle){
+ if(this.nextShufflePosition==-1){
+ Random rand = new Random();
+ this.nextShufflePosition = rand.nextInt(this.nowPlaying.size());
+ this.nextPlayer = this.PrepareTrack(this.nextShufflePosition);
+ }else{
+ this.nextPlayer = this.PrepareTrack(this.nextShufflePosition);
+ }
+ }else{
+ this.nextPlayer = this.PrepareTrack(this.position+1);
+ }
}
}
}
@@ -390,4 +432,25 @@
}
}
-}
+ public void SetBPMMode(boolean bpmMode){
+ synchronized(this.lock){
+ this.bpmMode = bpmMode;
+ }
+ }
+ public boolean GetBPMMode(){
+ synchronized(this.lock){
+ return this.bpmMode;
+ }
+ }
+
+ public void RemoveFromList(int position){
+ synchronized(this.lock){
+ this.nowPlaying.remove(position);
+ if(this.listListener!=null){
+ this.listListener.OnTrackListUpdate();
+ }
+ }
+ }
+
+
+}
=======================================
--- /trunk/src/android/src/org/musikcube/core/TrackPlayer.java Wed Aug 26
01:15:01 2009
+++ /trunk/src/android/src/org/musikcube/core/TrackPlayer.java Sat Aug 29
14:20:13 2009
@@ -31,12 +31,12 @@
this.mediaPlayer.setOnBufferingUpdateListener(this);
String url = Library.GetInstance().GetTrackURL(this.trackId);
- while(url==null && (this.status==STATUS_PREPARED ||
this.status==STATUS_PLAYING)){
- Log.v("mC2::TrackPlayer","Retrying "+this.trackId);
- synchronized(this.lock){
+ synchronized(this.lock){
+ while(url==null && (this.status==STATUS_PREPARED ||
this.status==STATUS_PLAYING)){
+ Log.v("mC2::TrackPlayer","Retrying "+this.trackId);
this.lock.wait(250);
- }
- url = Library.GetInstance().GetTrackURL(this.trackId);
+ url = Library.GetInstance().GetTrackURL(this.trackId);
+ }
}
if(url==null){
@@ -49,8 +49,8 @@
}
synchronized(this.lock){
- if(this.listener!=null){
- this.listener.OnTrackPrepared(this);
+ if(this.listenerPrepare!=null){
+ this.listenerPrepare.OnTrackPrepared(this);
}
while(this.status==STATUS_PREPARED)
@@ -157,18 +157,25 @@
}
public interface OnTrackStatusListener{
- public void OnTrackPrepared(TrackPlayer trackPlayer);
public void OnTrackStatusUpdate(TrackPlayer trackPlayer,int status);
public void OnTrackAlmostDone(TrackPlayer trackPlayer);
}
+ public interface OnTrackPrepareListener{
+ public void OnTrackPrepared(TrackPlayer trackPlayer);
+ }
private OnTrackStatusListener listener = null;
-
public void SetListener(OnTrackStatusListener listener){
synchronized(this.lock){
this.listener = listener;
}
}
+ private OnTrackPrepareListener listenerPrepare = null;
+ public void SetPrepareListener(OnTrackPrepareListener listener){
+ synchronized(this.lock){
+ this.listenerPrepare = listener;
+ }
+ }
public void onCompletion(MediaPlayer mp) {
synchronized(this.lock){
=======================================
--- /trunk/src/android/src/org/musikcube/main.java Wed Aug 26 12:20:37 2009
+++ /trunk/src/android/src/org/musikcube/main.java Sat Aug 29 14:20:13 2009
@@ -70,12 +70,13 @@
private OnClickListener onBPMClick = new OnClickListener() {
public void onClick(View v){
- Intent intent = new Intent(main.this, org.musikcube.Service.class);
- intent.putExtra("org.musikcube.Service.action", "bpmstart");
- startService(intent);
-
- Intent intent2 = new Intent(main.this, PlayerControl.class);
+/* Log.v("mC2::main","onBPMClick 1");
+ Intent intent2 = new Intent(main.this, PlayerBPMControl.class);
startActivity(intent2);
+ Log.v("mC2::main","onBPMClick 2");*/
+ Intent intent = new Intent(main.this, CategorySelect.class);
+
intent.putExtra("org.musikcube.CategorySelect.listCategory", "genre");
+ startActivity(intent);
}
};
@@ -86,23 +87,11 @@
}
public boolean onOptionsItemSelected(MenuItem item) {
-
//Log.i("MC2.onContextItemSelected","item "+item.getItemId()+" "+R.id.context_settings);
- switch (item.getItemId()) {
- case R.id.context_settings:
- startActivity(new Intent(this, org.musikcube.Preferences.class));
- return true;
- case R.id.context_browse:
- startActivity(new Intent(this, org.musikcube.main.class));
- return true;
- case R.id.context_controls:
- startActivity(new Intent(this, org.musikcube.PlayerControl.class));
- return true;
- case R.id.context_nowplaying:
- startActivity(new Intent(this, org.musikcube.NowPlayingList.class));
- return true;
- default:
- return super.onContextItemSelected(item);
- }
+ if(Helper.DefaultOptionsItemSelected(item,this)){
+ return true;
+ }else{
+ return super.onContextItemSelected(item);
+ }
}
@Override
@@ -146,7 +135,7 @@
genreButton.setEnabled(true);
artistsButton.setEnabled(true);
yearButton.setEnabled(true);
-// bpmButton.setEnabled(true);
+ bpmButton.setEnabled(false);
}else{
genreButton.setEnabled(false);
artistsButton.setEnabled(false);