mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-06 12:39:54 +00:00
More on the Workout mode.
Shuffle and repeat working. Highlighting the playing track in "now playing" list. More icons. Added help dialog.
This commit is contained in:
parent
13567caf8d
commit
522e3c917b
@ -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" />
|
||||
|
||||
|
BIN
src/android/res/drawable/ic_playing.png
Normal file
BIN
src/android/res/drawable/ic_playing.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 935 B |
Binary file not shown.
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
src/android/res/drawable/running.png
Normal file
BIN
src/android/res/drawable/running.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@ -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>
|
||||
|
@ -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>
|
23
src/android/res/layout/category_select.xml
Normal file
23
src/android/res/layout/category_select.xml
Normal file
@ -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>
|
7
src/android/res/layout/category_select_item.xml
Normal file
7
src/android/res/layout/category_select_item.xml
Normal file
@ -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>
|
10
src/android/res/layout/help.xml
Normal file
10
src/android/res/layout/help.xml
Normal file
@ -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>
|
@ -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>
|
45
src/android/res/layout/play_bpm_control.xml
Normal file
45
src/android/res/layout/play_bpm_control.xml
Normal file
@ -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>
|
@ -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">
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -6,10 +6,10 @@ import java.io.InputStream;
|
||||
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 class Reader extends ReaderNode {
|
||||
}
|
||||
|
||||
|
||||
public void Parse()
|
||||
public final void Parse()
|
||||
throws Exception
|
||||
{
|
||||
int eventType = 0;
|
||||
|
@ -3,10 +3,10 @@ import doep.xml.Reader;
|
||||
|
||||
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 @@ public class ReaderNode {
|
||||
* @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 @@ public class ReaderNode {
|
||||
* @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 @@ public class ReaderNode {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void End()
|
||||
public final void End()
|
||||
throws Exception
|
||||
{
|
||||
while(!this.ended){
|
||||
@ -73,7 +73,7 @@ public class ReaderNode {
|
||||
* 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){
|
||||
|
@ -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 @@ public class Writer extends WriterNode {
|
||||
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 @@ public class Writer extends WriterNode {
|
||||
// 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);
|
||||
|
@ -4,12 +4,12 @@ import java.util.ListIterator;
|
||||
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 @@ public class WriterNode {
|
||||
return newNode;
|
||||
}
|
||||
|
||||
public void End()
|
||||
public final void End()
|
||||
throws java.io.IOException
|
||||
{
|
||||
if(this.parent.state==0){
|
||||
@ -61,7 +61,7 @@ public class WriterNode {
|
||||
}
|
||||
}
|
||||
|
||||
protected void WriteStartTag()
|
||||
protected final void WriteStartTag()
|
||||
throws java.io.IOException
|
||||
{
|
||||
if(this.state==0){
|
||||
|
@ -5,6 +5,7 @@ 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;
|
||||
@ -20,6 +21,7 @@ import android.view.MenuItem;
|
||||
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 @@ public class CategoryList extends ListActivity implements OnQueryResultListener
|
||||
OnResults();
|
||||
}
|
||||
};
|
||||
|
||||
static class CategoryViewHolder{
|
||||
TextView title;
|
||||
}
|
||||
|
||||
public class ResultAdapter extends BaseAdapter{
|
||||
|
||||
@ -84,15 +90,21 @@ public class CategoryList extends ListActivity implements OnQueryResultListener
|
||||
}
|
||||
|
||||
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 class CategoryList extends ListActivity implements OnQueryResultListener
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
252
src/android/src/org/musikcube/CategorySelect.java
Normal file
252
src/android/src/org/musikcube/CategorySelect.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
44
src/android/src/org/musikcube/Helper.java
Normal file
44
src/android/src/org/musikcube/Helper.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -28,11 +28,11 @@ public class NowPlayingList extends TrackListBase implements OnTrackListUpdateLi
|
||||
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 @@ public class NowPlayingList extends TrackListBase implements OnTrackListUpdateLi
|
||||
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 @@ public class NowPlayingList extends TrackListBase implements OnTrackListUpdateLi
|
||||
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() {
|
||||
@ -106,7 +112,6 @@ public class NowPlayingList extends TrackListBase implements OnTrackListUpdateLi
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
@ -117,6 +122,8 @@ public class NowPlayingList extends TrackListBase implements OnTrackListUpdateLi
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
Player.GetInstance().SetListUpdateListener(this);
|
||||
this.position = Player.GetInstance().GetPosition();
|
||||
this.setSelection(this.position);
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,71 +19,79 @@ 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 BPMControl extends Activity implements OnTrackUpdateListener {
|
||||
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_control);
|
||||
/*
|
||||
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(PlayerControl.this, org.musikcube.Service.class);
|
||||
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(PlayerControl.this, org.musikcube.Service.class);
|
||||
Intent intent = new Intent(PlayerBPMControl.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() {
|
||||
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
|
||||
@ -149,13 +157,16 @@ public class BPMControl extends Activity implements OnTrackUpdateListener {
|
||||
}
|
||||
|
||||
// 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -198,24 +209,26 @@ public class BPMControl extends Activity implements OnTrackUpdateListener {
|
||||
};
|
||||
|
||||
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);
|
||||
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());
|
||||
}
|
||||
seekBar.setSecondaryProgress(10*Player.GetInstance().GetTrackBuffer());
|
||||
}
|
||||
|
||||
// Next callback in 0.5 seconds
|
||||
@ -230,20 +243,11 @@ public class BPMControl extends Activity implements OnTrackUpdateListener {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if(Helper.DefaultOptionsItemSelected(item,this)){
|
||||
return true;
|
||||
}else{
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -287,23 +287,11 @@ public class PlayerControl extends Activity implements OnTrackUpdateListener {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -92,6 +92,10 @@ public class Service extends android.app.Service {
|
||||
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 @@ public class Service extends android.app.Service {
|
||||
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 @@ public class Service extends android.app.Service {
|
||||
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 @@ public class Service extends android.app.Service {
|
||||
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;
|
||||
|
@ -20,6 +20,7 @@ import android.view.MenuItem;
|
||||
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 @@ public class TrackListBase extends ListActivity implements OnQueryResultListener
|
||||
|
||||
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 @@ public class TrackListBase extends ListActivity implements OnQueryResultListener
|
||||
TextView track;
|
||||
TextView title;
|
||||
TextView artist;
|
||||
ImageView marker;
|
||||
}
|
||||
|
||||
public class ResultAdapter extends BaseAdapter{
|
||||
@ -82,18 +87,29 @@ public class TrackListBase extends ListActivity implements OnQueryResultListener
|
||||
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){
|
||||
holder.track.setText("");
|
||||
@ -248,23 +264,11 @@ public class TrackListBase extends ListActivity implements OnQueryResultListener
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ public class IQuery extends Object{
|
||||
|
||||
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);
|
||||
|
@ -18,7 +18,7 @@ import org.musikcube.core.IQuery;
|
||||
* @author doy
|
||||
*
|
||||
*/
|
||||
public class Library implements Runnable{
|
||||
public final class Library implements Runnable{
|
||||
|
||||
// private String username;
|
||||
// private String password;
|
||||
@ -67,7 +67,7 @@ public class Library implements Runnable{
|
||||
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 @@ public class Library implements Runnable{
|
||||
}
|
||||
}
|
||||
|
||||
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 class Library implements Runnable{
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class Library implements Runnable{
|
||||
this.notifier.notifyAll();
|
||||
}
|
||||
}
|
||||
public void RemovePointer(){
|
||||
public final void RemovePointer(){
|
||||
synchronized(this.notifier){
|
||||
this.connections--;
|
||||
if(this.connections==0){
|
||||
@ -127,7 +127,7 @@ public class Library implements Runnable{
|
||||
}
|
||||
|
||||
|
||||
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 @@ public class Library implements Runnable{
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
public void Restart(){
|
||||
public final void Restart(){
|
||||
synchronized(this.notifier){
|
||||
this.running = false;
|
||||
this.restart = true;
|
||||
@ -152,7 +152,7 @@ public class Library implements Runnable{
|
||||
}
|
||||
}
|
||||
|
||||
public boolean Running(){
|
||||
public final boolean Running(){
|
||||
synchronized(this.notifier){
|
||||
if(this.running==true){
|
||||
return true;
|
||||
@ -161,7 +161,7 @@ public class Library implements Runnable{
|
||||
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 @@ public class Library implements Runnable{
|
||||
this.thread = new Thread(this);
|
||||
}
|
||||
|
||||
public void Start(){
|
||||
public final void Start(){
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ public class Library implements Runnable{
|
||||
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 class Library implements Runnable{
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteThread(WriterThreadHelper thread){
|
||||
public final void WriteThread(WriterThreadHelper thread){
|
||||
//Log.v("Library::WriteThread","Started");
|
||||
this.SetStatus(STATUS_AUTHENTICATING);
|
||||
|
||||
@ -426,7 +426,7 @@ public class Library implements Runnable{
|
||||
//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 class Library implements Runnable{
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -23,7 +23,7 @@ public class ListQuery extends IQuery {
|
||||
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 @@ public class ListQuery extends IQuery {
|
||||
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 class ListQuery extends IQuery {
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectData(String category,int selection){
|
||||
public final void SelectData(String category,int selection){
|
||||
this.selectionStrings.add(category);
|
||||
this.selectionInts.add(selection);
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ import doep.xml.WriterNode;
|
||||
|
||||
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();
|
||||
|
@ -18,7 +18,7 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
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 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
}
|
||||
|
||||
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);
|
||||
Collections.sort(bpms);
|
||||
//Log.v("MC2::BEAT","B "+(bpms.size()));
|
||||
|
||||
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);
|
||||
// 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);
|
||||
|
||||
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);
|
||||
}
|
||||
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 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
|
||||
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 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
BPMQuery query = new BPMQuery();
|
||||
query.queryForBPM = this.currentBPM;
|
||||
query.SetResultListener(this);
|
||||
Library.GetInstance().AddQuery(query);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -197,6 +210,7 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
|
||||
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);
|
||||
|
@ -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 class Player implements TrackPlayer.OnTrackStatusListener, OnQueryResultL
|
||||
|
||||
public android.app.Service service;
|
||||
|
||||
private boolean bpmMode = false;
|
||||
|
||||
public void run() {
|
||||
}
|
||||
|
||||
@ -44,6 +49,9 @@ public class Player implements TrackPlayer.OnTrackStatusListener, OnQueryResultL
|
||||
synchronized(this.lock){
|
||||
this.nowPlaying = playlist;
|
||||
this.position = position;
|
||||
if(this.listListener!=null){
|
||||
this.listListener.OnTrackListUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
this.Play();
|
||||
@ -64,12 +72,13 @@ public class Player implements TrackPlayer.OnTrackStatusListener, OnQueryResultL
|
||||
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 class Player implements TrackPlayer.OnTrackStatusListener, OnQueryResultL
|
||||
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 class Player implements TrackPlayer.OnTrackStatusListener, OnQueryResultL
|
||||
|
||||
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 class Player implements TrackPlayer.OnTrackStatusListener, OnQueryResultL
|
||||
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 class Player implements TrackPlayer.OnTrackStatusListener, OnQueryResultL
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -31,12 +31,12 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener,
|
||||
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 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener,
|
||||
}
|
||||
|
||||
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 class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener,
|
||||
}
|
||||
|
||||
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){
|
||||
|
@ -70,12 +70,13 @@ public class main extends Activity implements OnLibraryStatusListener {
|
||||
|
||||
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 class main extends Activity implements OnLibraryStatusListener {
|
||||
}
|
||||
|
||||
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 @@ public class main extends Activity implements OnLibraryStatusListener {
|
||||
genreButton.setEnabled(true);
|
||||
artistsButton.setEnabled(true);
|
||||
yearButton.setEnabled(true);
|
||||
// bpmButton.setEnabled(true);
|
||||
bpmButton.setEnabled(false);
|
||||
}else{
|
||||
genreButton.setEnabled(false);
|
||||
artistsButton.setEnabled(false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user