mirror of
https://github.com/clangen/musikcube.git
synced 2024-10-02 04:52:32 +00:00
android client v1.0.2
This commit is contained in:
parent
e95ce2035c
commit
a3dbc24aa8
@ -1,11 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.musikcube"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
android:versionName="1.0.2" android:versionCode="2">
|
||||
<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">
|
||||
android:label="@string/app_name" android:launchMode="singleTask" android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
@ -10,7 +10,8 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:drawSelectorOnTop="false"/>
|
||||
android:drawSelectorOnTop="false"
|
||||
android:choiceMode="multipleChoice" android:fastScrollEnabled="true" />
|
||||
|
||||
<LinearLayout android:id="@id/android:empty"
|
||||
android:orientation="horizontal"
|
||||
|
8
src/android/res/layout/category_select_footer.xml
Normal file
8
src/android/res/layout/category_select_footer.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?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="wrap_content">
|
||||
<Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:textSize="22sp" android:text="Save" android:id="@+id/SaveButton"></Button>
|
||||
|
||||
</LinearLayout>
|
@ -1,7 +1,8 @@
|
||||
<?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>
|
||||
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="28sp"
|
||||
android:maxLines="1"
|
||||
android:checkMark="?android:attr/listChoiceIndicatorMultiple" />
|
||||
|
@ -3,8 +3,10 @@
|
||||
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>
|
||||
|
||||
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="musikCube is a application that is able to play music from you own desktop computer or server. Although it can be a little bit tricky to get it up and running since you probably need to do some port forwarding in your gateway to be able to access the server from outside your network." android:padding="4sp"></TextView>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="First of all, musikCube requires you to run a windows applications called musikServer that can be downloaded from:" android:padding="4sp"></TextView>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="http://code.google.com/p/musikcube/" android:textColor="#ffffff" android:padding="4sp"></TextView>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="On the project site you will also find help regarding gateway and firewall settings." android:padding="4sp"></TextView>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Once installed and opened up in gateways and firewalls you go to the settings in this application and edit where to find your musikServer." android:padding="4sp"></TextView>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Enjoy!" android:padding="4sp"></TextView>
|
||||
</LinearLayout>
|
||||
|
@ -10,11 +10,13 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:orientation="vertical" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="0.8">
|
||||
<TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:text="Browse by:" android:layout_width="fill_parent" android:background="@color/headlineColor" android:textSize="16sp" android:padding="4sp"></TextView>
|
||||
<TextView android:id="@+id/TextView01" android:layout_height="wrap_content" android:text="Browse by:" android:layout_width="fill_parent" android:background="@color/headlineColor" android:textSize="20sp" android:padding="4sp"></TextView>
|
||||
<Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:textSize="22sp" android:text="Genre" android:id="@+id/GenresButton"></Button>
|
||||
<Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:textSize="22sp" android:id="@+id/ArtistsButton" android:text="Artist"></Button>
|
||||
<Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:textSize="22sp" android:id="@+id/YearButton" android:text="Year"></Button>
|
||||
<Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:textSize="22sp" android:id="@+id/BPMButton" android:text="Workout mode"></Button>
|
||||
<TextView android:id="@+id/TextView02" android:layout_height="wrap_content" android:text="Workout mode by:" android:layout_width="fill_parent" android:background="@color/headlineColor" android:textSize="20sp" android:padding="4sp"></TextView>
|
||||
<Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:textSize="22sp" android:id="@+id/BPMGenreButton" android:text="Genre"></Button>
|
||||
<Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:textSize="22sp" android:id="@+id/BPMArtistButton" android:text="Artist"></Button>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView android:id="@+id/StatusView" android:text="Status: -" android:layout_width="fill_parent" android:background="@color/headlineColor" android:textSize="16sp" android:padding="4sp" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_weight="0.1"></TextView>
|
||||
|
@ -4,42 +4,38 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp" android:gravity="center_vertical|center_horizontal">
|
||||
android:paddingRight="8dp" android:gravity="center_horizontal">
|
||||
|
||||
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content">
|
||||
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical">
|
||||
<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>
|
||||
<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 android:id="@+id/LinearLayout01" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="left" android:layout_width="160sp" android:layout_gravity="left" android:paddingLeft="10sp">
|
||||
<TextView android:layout_height="wrap_content" android:textSize="20sp" android:id="@+id/TrackTitle" android:lines="1" android:layout_width="wrap_content" android:text="Title:"></TextView>
|
||||
<TextView android:layout_height="wrap_content" android:textSize="14sp" android:text="Album:" android:id="@+id/TrackAlbum" android:lines="1" android:layout_width="wrap_content"></TextView>
|
||||
<TextView android:layout_width="wrap_content" android:textSize="14sp" android:layout_height="wrap_content" android:text="Artists:" android:id="@+id/TrackArtist" android:lines="1"></TextView>
|
||||
</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">
|
||||
<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 android:id="@+id/LinearLayout02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_margin="20sp">
|
||||
<TextView android:layout_height="wrap_content" android:textSize="20sp" android:id="@+id/BPMTitle" android:lines="1" android:layout_width="wrap_content" android:text="BPM:"></TextView>
|
||||
<SeekBar android:layout_height="50sp" android:layout_width="200sp" android:max="1000" android:id="@+id/BPM" android:progress="500"></SeekBar>
|
||||
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical">
|
||||
<ToggleButton android:id="@+id/ToggleAccelerator" android:layout_width="wrap_content" android:layout_height="wrap_content"></ToggleButton>
|
||||
<TextView android:layout_height="wrap_content" android:textSize="18sp" android:lines="1" android:layout_width="wrap_content" android:text="Accelerometer"></TextView>
|
||||
</LinearLayout>
|
||||
</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">
|
||||
|
||||
|
||||
<LinearLayout android:id="@+id/LinearLayout03" 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>
|
@ -19,6 +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>
|
||||
<string name="help_main">musikCube is a application that connects to your musikServer that you have installed on your desktop/server computer. The musikServer can be downloaded from http://code.google.com/p/musikcube/\nOnce 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.\n</string>
|
||||
|
||||
</resources>
|
||||
|
@ -5,7 +5,6 @@ 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;
|
||||
@ -21,7 +20,6 @@ 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;
|
||||
|
||||
|
@ -5,26 +5,28 @@ 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.Workout;
|
||||
import org.musikcube.core.IQuery.OnQueryResultListener;
|
||||
|
||||
import android.app.ListActivity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.util.SparseBooleanArray;
|
||||
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.view.View.OnClickListener;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckedTextView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* @author doy
|
||||
@ -51,7 +53,7 @@ public class CategorySelect extends ListActivity implements OnQueryResultListene
|
||||
};
|
||||
|
||||
static class CategoryViewHolder{
|
||||
CheckBox title;
|
||||
CheckedTextView title;
|
||||
}
|
||||
|
||||
public class ResultAdapter extends BaseAdapter{
|
||||
@ -66,28 +68,15 @@ public class CategorySelect extends ListActivity implements OnQueryResultListene
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
int size = this.query.resultsInts.size();
|
||||
if(size==0){
|
||||
return 0;
|
||||
}else{
|
||||
return size+1;
|
||||
}
|
||||
return this.query.resultsInts.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
if(position==0){
|
||||
return 0;
|
||||
}else{
|
||||
return this.query.resultsInts.get(position-1);
|
||||
}
|
||||
return this.query.resultsInts.get(position);
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
if(position==0){
|
||||
return 0;
|
||||
}else{
|
||||
return this.query.resultsInts.get(position-1);
|
||||
}
|
||||
return this.query.resultsInts.get(position);
|
||||
}
|
||||
|
||||
public View getView(int position, View view, ViewGroup parent) {
|
||||
@ -95,23 +84,43 @@ public class CategorySelect extends ListActivity implements OnQueryResultListene
|
||||
if(view==null){
|
||||
view = inflator.inflate(R.layout.category_select_item, null);
|
||||
holder = new CategoryViewHolder();
|
||||
holder.title = (CheckBox) view.findViewById(R.id.text);
|
||||
holder.title = (CheckedTextView) 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));
|
||||
}
|
||||
holder.title.setText(this.query.resultsStrings.get(position));
|
||||
return view;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private OnClickListener onSaveClick = new OnClickListener() {
|
||||
public void onClick(View v){
|
||||
final Intent intent = new Intent(CategorySelect.this, PlayerBPMControl.class);
|
||||
|
||||
// Get selection
|
||||
final SparseBooleanArray selectionList = CategorySelect.this.getListView().getCheckedItemPositions();
|
||||
final ArrayList<Integer> selections = new ArrayList<Integer>();
|
||||
ArrayList<Integer> list = CategorySelect.this.query.resultsInts;
|
||||
int listSize = list.size();
|
||||
for(int i=0;i<listSize;i++){
|
||||
if(selectionList.get(i)){
|
||||
selections.add(list.get(i));
|
||||
}
|
||||
}
|
||||
Workout.GetInstance().SetCategory(selections, CategorySelect.this.category);
|
||||
Log.v("mC2::SAVE",CategorySelect.this.category);
|
||||
Log.v("mC2::SAVE",selections.toString());
|
||||
intent.putExtra("org.musikcube.PlayerBPMControl.category", CategorySelect.this.category);
|
||||
intent.putExtra("org.musikcube.PlayerBPMControl.selection", selections);
|
||||
startActivity(intent);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private ResultAdapter listAdapter;
|
||||
|
||||
@Override
|
||||
@ -120,6 +129,15 @@ public class CategorySelect extends ListActivity implements OnQueryResultListene
|
||||
//Log.v("musikcube.CategoryList", "start");
|
||||
this.setContentView(R.layout.category_select);
|
||||
|
||||
final ListView list = this.getListView();
|
||||
list.setItemsCanFocus(false);
|
||||
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
||||
View footer = this.getLayoutInflater().inflate(R.layout.category_select_footer, null);
|
||||
list.addFooterView(footer);
|
||||
|
||||
Button saveButton = (Button)findViewById(R.id.SaveButton);
|
||||
saveButton.setOnClickListener(this.onSaveClick);
|
||||
|
||||
Intent intent = this.getIntent();
|
||||
|
||||
this.query.SetResultListener(this);
|
||||
@ -169,8 +187,6 @@ public class CategorySelect extends ListActivity implements OnQueryResultListene
|
||||
|
||||
}
|
||||
|
||||
//Log.v("musikcube.CategoryList", "onCreate end");
|
||||
|
||||
}
|
||||
|
||||
public void OnResults(){
|
||||
@ -187,6 +203,7 @@ public class CategorySelect extends ListActivity implements OnQueryResultListene
|
||||
this.callbackHandler.post(this.callbackRunnable);
|
||||
}
|
||||
|
||||
/*
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id){
|
||||
@ -221,7 +238,7 @@ public class CategorySelect extends ListActivity implements OnQueryResultListene
|
||||
intent.putExtra("org.musikcube.CategoryList.selectedCategoryId", selectedCategoryIds);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package org.musikcube;
|
||||
|
||||
import org.musikcube.core.Player;
|
||||
import org.musikcube.core.Workout;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
@ -20,7 +20,7 @@ public class Helper {
|
||||
context.startActivity(new Intent(context, org.musikcube.main.class));
|
||||
return true;
|
||||
case R.id.context_controls:
|
||||
if(Player.GetInstance().GetBPMMode()){
|
||||
if(Workout.GetInstance().Active()){
|
||||
context.startActivity(new Intent(context, org.musikcube.PlayerBPMControl.class));
|
||||
}else{
|
||||
context.startActivity(new Intent(context, org.musikcube.PlayerControl.class));
|
||||
|
@ -8,7 +8,6 @@ import org.musikcube.core.Player.OnTrackListUpdateListener;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@ -40,8 +39,6 @@ public class NowPlayingList extends TrackListBase implements OnTrackListUpdateLi
|
||||
|
||||
this.setTitle("musikCube: Now playing");
|
||||
|
||||
org.musikcube.core.Library library = org.musikcube.core.Library.GetInstance();
|
||||
|
||||
this.registerForContextMenu(this.getListView());
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,9 @@ import java.net.URL;
|
||||
import org.musikcube.core.Library;
|
||||
import org.musikcube.core.Player;
|
||||
import org.musikcube.core.Track;
|
||||
import org.musikcube.core.Workout;
|
||||
import org.musikcube.core.Player.OnTrackUpdateListener;
|
||||
import org.musikcube.core.Workout.OnWorkoutListener;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
@ -15,18 +17,21 @@ 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.CompoundButton;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ToggleButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
|
||||
public class PlayerBPMControl extends Activity implements OnTrackUpdateListener {
|
||||
public class PlayerBPMControl extends Activity implements OnTrackUpdateListener, OnWorkoutListener {
|
||||
|
||||
private Track track = new Track();
|
||||
private int duration = 0;
|
||||
@ -36,7 +41,6 @@ public class PlayerBPMControl extends Activity implements OnTrackUpdateListener
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
Log.v("MC2::PC","OnCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.play_bpm_control);
|
||||
|
||||
@ -44,12 +48,12 @@ public class PlayerBPMControl extends Activity implements OnTrackUpdateListener
|
||||
nextButton.setOnClickListener(this.onNextClick);
|
||||
ImageButton pauseButton = (ImageButton)findViewById(R.id.MediaPause);
|
||||
pauseButton.setOnClickListener(this.onPauseClick);
|
||||
ToggleButton acc = (ToggleButton)findViewById(R.id.ToggleAccelerator);
|
||||
acc.setOnCheckedChangeListener(this.onAcceleratorToggle);
|
||||
SeekBar bpmBar = (SeekBar)findViewById(R.id.BPM);
|
||||
bpmBar.setOnSeekBarChangeListener(this.onBPMChanged);
|
||||
|
||||
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() {
|
||||
@ -62,10 +66,44 @@ public class PlayerBPMControl extends Activity implements OnTrackUpdateListener
|
||||
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");
|
||||
if(Workout.GetInstance().Active()){
|
||||
intent.putExtra("org.musikcube.Service.action", "workoutstop");
|
||||
}else{
|
||||
intent.putExtra("org.musikcube.Service.action", "workoutstart");
|
||||
}
|
||||
startService(intent);
|
||||
// PlayerBPMControl.this.OnUpdateTrackUI();
|
||||
}
|
||||
};
|
||||
private OnCheckedChangeListener onAcceleratorToggle = new OnCheckedChangeListener(){
|
||||
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
|
||||
Workout.GetInstance().UseAccelerometer(isChecked);
|
||||
}
|
||||
};
|
||||
private OnSeekBarChangeListener onBPMChanged = new OnSeekBarChangeListener(){
|
||||
|
||||
public void onProgressChanged(SeekBar seekBar, int progress,
|
||||
boolean fromUser) {
|
||||
if(fromUser){
|
||||
if(!Workout.GetInstance().Accelerometer()){
|
||||
// Seek
|
||||
float bpm = (float) ((float)progress*150.0/1000.0+50.0);
|
||||
Workout.GetInstance().SetBPM(bpm);
|
||||
|
||||
TextView bpmTitle = (TextView)PlayerBPMControl.this.findViewById(R.id.BPMTitle);
|
||||
bpmTitle.setText("BPM: "+bpm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
public void OnTrackBufferUpdate(int percent) {
|
||||
this.callbackTrackPositionsUpdateHandler.post(this.callbackTrackPositionsUpdateRunnable);
|
||||
@ -80,18 +118,24 @@ public class PlayerBPMControl extends Activity implements OnTrackUpdateListener
|
||||
@Override
|
||||
protected void onPause() {
|
||||
this.enable = false;
|
||||
Log.v("MC2::PC","OnPause");
|
||||
org.musikcube.core.Library.GetInstance().RemovePointer();
|
||||
Player.GetInstance().SetUpdateListener(null);
|
||||
Workout.GetInstance().SetListener(null);
|
||||
super.onPause();
|
||||
}
|
||||
@Override
|
||||
protected void onResume() {
|
||||
this.enable = true;
|
||||
Log.v("MC2::PC","OnResume");
|
||||
org.musikcube.core.Library.GetInstance().AddPointer();
|
||||
Player.GetInstance().SetUpdateListener(this);
|
||||
super.onResume();
|
||||
this.OnUpdateTrackPositionsUI();
|
||||
this.OnUpdateTrackUI();
|
||||
|
||||
Workout.GetInstance().SetListener(this);
|
||||
|
||||
ToggleButton acc = (ToggleButton)findViewById(R.id.ToggleAccelerator);
|
||||
acc.setChecked(Workout.GetInstance().Accelerometer());
|
||||
}
|
||||
|
||||
// Need handler for callbacks to the UI thread
|
||||
@ -169,6 +213,15 @@ public class PlayerBPMControl extends Activity implements OnTrackUpdateListener
|
||||
}
|
||||
}
|
||||
|
||||
// Update play button
|
||||
ImageButton playButton = (ImageButton)findViewById(R.id.MediaPause);
|
||||
if(Workout.GetInstance().Active()){
|
||||
playButton.setImageResource(R.drawable.ic_media_pause);
|
||||
}else{
|
||||
playButton.setImageResource(R.drawable.ic_media_play);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private class DownloadAlbumCoverTask extends AsyncTask<String,Integer,Bitmap>{
|
||||
@ -184,7 +237,6 @@ public class PlayerBPMControl extends Activity implements OnTrackUpdateListener
|
||||
Bitmap bm = BitmapFactory.decodeStream(is);
|
||||
return bm;
|
||||
} catch (Exception e) {
|
||||
Log.v("mC2:PLAYER","Error "+e.getMessage());
|
||||
// e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
@ -231,6 +283,16 @@ public class PlayerBPMControl extends Activity implements OnTrackUpdateListener
|
||||
}
|
||||
}
|
||||
|
||||
// Update BPM
|
||||
SeekBar bpmBar = (SeekBar)findViewById(R.id.BPM);
|
||||
final int startBPM = 50;
|
||||
final int endBPM = 200;
|
||||
final float currentBPM = Workout.GetInstance().GetBPM();
|
||||
bpmBar.setProgress( (int) (((float)currentBPM-startBPM)*1000/(endBPM-startBPM)) );
|
||||
|
||||
TextView bpmTitle = (TextView)findViewById(R.id.BPMTitle);
|
||||
bpmTitle.setText("BPM: "+currentBPM);
|
||||
|
||||
// Next callback in 0.5 seconds
|
||||
this.callbackTrackPositionsUpdateHandler.postDelayed(callbackTrackPositionsUpdateRunnable,500);
|
||||
|
||||
@ -249,5 +311,8 @@ public class PlayerBPMControl extends Activity implements OnTrackUpdateListener
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
}
|
||||
public void OnBPMUpdate() {
|
||||
this.callbackTrackUpdateHandler.post(this.callbackTrackUpdateRunnable);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ 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;
|
||||
@ -33,10 +32,10 @@ public class PlayerControl extends Activity implements OnTrackUpdateListener {
|
||||
private Object lock = new Object();
|
||||
private boolean enable = false;
|
||||
private int currentAlbumCoverId = 0;
|
||||
private boolean playing = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
Log.v("MC2::PC","OnCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.play_control);
|
||||
|
||||
@ -74,7 +73,11 @@ public class PlayerControl extends Activity implements OnTrackUpdateListener {
|
||||
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");
|
||||
if(Player.GetInstance().Playing()){
|
||||
intent.putExtra("org.musikcube.Service.action", "stop");
|
||||
}else{
|
||||
intent.putExtra("org.musikcube.Service.action", "play");
|
||||
}
|
||||
startService(intent);
|
||||
}
|
||||
};
|
||||
@ -124,14 +127,14 @@ public class PlayerControl extends Activity implements OnTrackUpdateListener {
|
||||
@Override
|
||||
protected void onPause() {
|
||||
this.enable = false;
|
||||
Log.v("MC2::PC","OnPause");
|
||||
org.musikcube.core.Library.GetInstance().RemovePointer();
|
||||
Player.GetInstance().SetUpdateListener(null);
|
||||
super.onPause();
|
||||
}
|
||||
@Override
|
||||
protected void onResume() {
|
||||
this.enable = true;
|
||||
Log.v("MC2::PC","OnResume");
|
||||
org.musikcube.core.Library.GetInstance().AddPointer();
|
||||
Player.GetInstance().SetUpdateListener(this);
|
||||
super.onResume();
|
||||
this.OnUpdateTrackPositionsUI();
|
||||
@ -213,6 +216,14 @@ public class PlayerControl extends Activity implements OnTrackUpdateListener {
|
||||
}
|
||||
}
|
||||
|
||||
// Update play button
|
||||
ImageButton playButton = (ImageButton)findViewById(R.id.MediaPause);
|
||||
if(Player.GetInstance().Playing()){
|
||||
playButton.setImageResource(R.drawable.ic_media_pause);
|
||||
}else{
|
||||
playButton.setImageResource(R.drawable.ic_media_play);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class DownloadAlbumCoverTask extends AsyncTask<String,Integer,Bitmap>{
|
||||
@ -228,8 +239,6 @@ public class PlayerControl extends Activity implements OnTrackUpdateListener {
|
||||
Bitmap bm = BitmapFactory.decodeStream(is);
|
||||
return bm;
|
||||
} catch (Exception e) {
|
||||
Log.v("mC2:PLAYER","Error "+e.getMessage());
|
||||
// e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,9 @@
|
||||
package org.musikcube;
|
||||
|
||||
import org.musikcube.core.Library;
|
||||
import org.musikcube.core.PaceDetector;
|
||||
import org.musikcube.core.Player;
|
||||
import org.musikcube.core.Track;
|
||||
import org.musikcube.core.Workout;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
@ -16,7 +16,6 @@ import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @author doy
|
||||
@ -27,7 +26,8 @@ public class Service extends android.app.Service {
|
||||
Library library;
|
||||
Player player;
|
||||
boolean showingNotification = false;
|
||||
PaceDetector paceDetector;
|
||||
boolean bpmMode = false;
|
||||
Workout workout;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -47,7 +47,6 @@ public class Service extends android.app.Service {
|
||||
|
||||
@Override
|
||||
public void onCreate(){
|
||||
Log.i("musikcube::Service","CREATE");
|
||||
this.player = Player.GetInstance();
|
||||
this.player.service = this;
|
||||
this.library = org.musikcube.core.Library.GetInstance();
|
||||
@ -78,19 +77,22 @@ public class Service extends android.app.Service {
|
||||
public void onStart(Intent intent, int startId) {
|
||||
// TODO Auto-generated method stub
|
||||
super.onStart(intent, startId);
|
||||
|
||||
|
||||
boolean stopWorkout = false;
|
||||
|
||||
String action = intent.getStringExtra("org.musikcube.Service.action");
|
||||
if(action==null){
|
||||
return;
|
||||
}
|
||||
|
||||
if(action.equals("playlist")){
|
||||
Player player = Player.GetInstance();
|
||||
player.Play(intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist"), intent.getIntExtra("org.musikcube.Service.position", 0));
|
||||
stopWorkout = true;
|
||||
}
|
||||
if(action.equals("appendlist")){
|
||||
Player player = Player.GetInstance();
|
||||
player.Append(intent.getIntegerArrayListExtra("org.musikcube.Service.tracklist"));
|
||||
stopWorkout = true;
|
||||
}
|
||||
if(action.equals("remove_from_list")){
|
||||
Player player = Player.GetInstance();
|
||||
@ -113,9 +115,7 @@ 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);
|
||||
}
|
||||
stopWorkout = true;
|
||||
}
|
||||
if(action.equals("play")){
|
||||
Player player = Player.GetInstance();
|
||||
@ -124,21 +124,30 @@ public class Service extends android.app.Service {
|
||||
if(action.equals("shutdown")){
|
||||
//Log.i("musikcube::Service","Shutdown");
|
||||
this.stopSelf();
|
||||
stopWorkout = true;
|
||||
}
|
||||
if(action.equals("bpmstart")){
|
||||
Player.GetInstance().SetBPMMode(true);
|
||||
if(this.paceDetector==null){
|
||||
this.paceDetector = new PaceDetector();
|
||||
this.paceDetector.StartSensor(this);
|
||||
|
||||
if(stopWorkout){
|
||||
if(this.workout!=null){
|
||||
this.workout.Stop();
|
||||
this.workout = null;
|
||||
}
|
||||
}
|
||||
if(action.equals("bpmstop")){
|
||||
if(this.paceDetector!=null){
|
||||
this.paceDetector.StopSensor(this);
|
||||
|
||||
if(action.equals("workoutstart")){
|
||||
this.workout = Workout.GetInstance();
|
||||
this.workout.Startup(this);
|
||||
}
|
||||
if(action.equals("workoutstop")){
|
||||
if(this.workout!=null){
|
||||
this.workout.Stop();
|
||||
this.workout = null;
|
||||
}
|
||||
Player player = Player.GetInstance();
|
||||
player.Stop();
|
||||
}
|
||||
|
||||
if(action.equals("player_start")){
|
||||
if(action.equals("player_start") || this.workout!=null){
|
||||
Track track = Player.GetInstance().GetCurrentTrack();
|
||||
|
||||
this.showingNotification = true;
|
||||
@ -165,7 +174,13 @@ public class Service extends android.app.Service {
|
||||
contentText += trackArtist;
|
||||
}
|
||||
}
|
||||
Intent notificationIntent = new Intent(this, Player.GetInstance().GetBPMMode()?PlayerBPMControl.class:PlayerControl.class);
|
||||
Intent notificationIntent;
|
||||
if(this.workout==null){
|
||||
notificationIntent = new Intent(this, PlayerControl.class);
|
||||
}else{
|
||||
notificationIntent = new Intent(this, PlayerBPMControl.class);
|
||||
}
|
||||
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
|
||||
|
||||
notification.flags |= Notification.FLAG_ONGOING_EVENT|Notification.FLAG_NO_CLEAR;
|
||||
@ -174,7 +189,7 @@ public class Service extends android.app.Service {
|
||||
mNotificationManager.notify(1, notification);
|
||||
}
|
||||
|
||||
if(action.equals("player_end")){
|
||||
if(action.equals("player_end") && this.workout==null){
|
||||
this.showingNotification = false;
|
||||
String ns = Context.NOTIFICATION_SERVICE;
|
||||
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
|
||||
|
@ -2,31 +2,28 @@ package org.musikcube.core;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.musikcube.core.IQuery.OnQueryResultListener;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
public class PaceDetector implements Runnable, SensorEventListener, OnQueryResultListener {
|
||||
public class PaceDetector implements Runnable, SensorEventListener{
|
||||
|
||||
static public float MAX_BPM = 85;
|
||||
static public float MIN_BPM = 40;
|
||||
static public int WAVE_MEMORY = 20;
|
||||
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
|
||||
static public float BPM_THRESHOLD = 10; // if BPM is off by more than 10 bpm, switch track
|
||||
static final public float MAX_BPM = 100;
|
||||
static final public float MIN_BPM = 40;
|
||||
static final public int WAVE_MEMORY = 20;
|
||||
static final public int WAVE_MIN_CALC = 10;
|
||||
static final public float WAVE_MIN_BPM_DIFF = 100; // This is in miliseconds
|
||||
static final public int WAVE_COMPARE = 4;
|
||||
static final public int MIN_PLAYTIME = 20000; // Play at leased 20 seconds of a track
|
||||
//static final public float BPM_THRESHOLD = 10; // if BPM is off by more than 10 bpm, switch track
|
||||
|
||||
private float currentBPM = 0;
|
||||
private float currentAccuracy = 0;
|
||||
private long currentBPMstart = 0;
|
||||
private Object lock = new Object();
|
||||
|
||||
private Context context;
|
||||
|
||||
@ -43,7 +40,7 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
public float currentAccuracy = 0;
|
||||
|
||||
final public void NextValue(float value){
|
||||
float diff = value-this.lastValue;
|
||||
final float diff = value-this.lastValue;
|
||||
|
||||
if(value<this.currentMin){
|
||||
this.currentMin = value;
|
||||
@ -55,12 +52,10 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
if(this.lastDiff>=0 && diff<0){
|
||||
|
||||
// Amplitude must be at leased 5
|
||||
if(this.currentMax-this.currentMin<7){
|
||||
if(this.currentMax-this.currentMin<4){
|
||||
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);
|
||||
@ -143,6 +138,21 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
|
||||
}
|
||||
|
||||
public interface OnBPMListener{
|
||||
public void OnBPMUpdate();
|
||||
}
|
||||
protected OnBPMListener listener = null;
|
||||
|
||||
public void SetListener(OnBPMListener listener){
|
||||
synchronized(this.lock){
|
||||
this.listener = listener;
|
||||
if(this.listener!=null){
|
||||
this.listener.OnBPMUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private PaceDimension xAxis = new PaceDimension();
|
||||
private PaceDimension yAxis = new PaceDimension();
|
||||
private PaceDimension zAxis = new PaceDimension();
|
||||
@ -159,38 +169,40 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
}
|
||||
|
||||
public void ChangeBPM(float bpm,float accuracy){
|
||||
bpm *= 2; // BPM should be the double
|
||||
while(bpm<85){
|
||||
bpm *= 2;
|
||||
}
|
||||
while(bpm>200){
|
||||
bpm *= 0.5;
|
||||
}
|
||||
|
||||
if(accuracy>=this.xAxis.currentAccuracy && accuracy>=this.yAxis.currentAccuracy && accuracy>=this.zAxis.currentAccuracy && accuracy>150){
|
||||
// The BPM has changed
|
||||
|
||||
long currentTime = android.os.SystemClock.elapsedRealtime();
|
||||
if(currentTime>this.currentBPMstart+MIN_PLAYTIME){
|
||||
// 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);
|
||||
// if(bpm>this.currentBPM+BPM_THRESHOLD || bpm<this.currentBPM-BPM_THRESHOLD){
|
||||
// BPM has changed enough to switch track
|
||||
this.currentBPMstart = currentTime;
|
||||
|
||||
this.currentBPM = bpm;
|
||||
|
||||
synchronized(lock){
|
||||
this.currentBPM = bpm;
|
||||
if(this.listener!=null){
|
||||
this.listener.OnBPMUpdate();
|
||||
}
|
||||
}
|
||||
this.currentAccuracy = accuracy;
|
||||
|
||||
BPMQuery query = new BPMQuery();
|
||||
query.queryForBPM = this.currentBPM;
|
||||
query.SetResultListener(this);
|
||||
Library.GetInstance().AddQuery(query);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public void StartSensor(Context context){
|
||||
this.context = context;
|
||||
Log.v("mC2::ACC","Sensor");
|
||||
SensorManager sensorMgr = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
|
||||
Sensor accelerometer = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
sensorMgr.registerListener(this,accelerometer,SensorManager.SENSOR_DELAY_GAME);
|
||||
@ -204,19 +216,11 @@ public class PaceDetector implements Runnable, SensorEventListener, OnQueryResul
|
||||
|
||||
|
||||
public void run() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
intent.putExtra("org.musikcube.Service.position", 0);
|
||||
intent.putExtra("org.musikcube.Service.action", "playlist_prepare");
|
||||
this.context.startService(intent);
|
||||
|
||||
public float GetBPM(){
|
||||
synchronized(this.lock){
|
||||
return currentBPM;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -452,5 +452,11 @@ public final class Player implements TrackPlayer.OnTrackStatusListener, OnQueryR
|
||||
}
|
||||
}
|
||||
|
||||
public boolean Playing(){
|
||||
synchronized(this.lock){
|
||||
return (this.library!=null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.musikcube.core;
|
||||
|
||||
import android.media.MediaPlayer;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener,MediaPlayer.OnBufferingUpdateListener {
|
||||
|
||||
@ -33,7 +33,6 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener,
|
||||
String url = Library.GetInstance().GetTrackURL(this.trackId);
|
||||
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);
|
||||
}
|
||||
@ -64,6 +63,7 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener,
|
||||
|
||||
if(currentStatus==STATUS_PLAYING)
|
||||
this.mediaPlayer.start();
|
||||
|
||||
|
||||
synchronized(this.lock){
|
||||
this.started = true;
|
||||
@ -85,18 +85,21 @@ public class TrackPlayer implements Runnable, MediaPlayer.OnCompletionListener,
|
||||
}
|
||||
this.started = false;
|
||||
}
|
||||
|
||||
|
||||
this.mediaPlayer.stop();
|
||||
this.mediaPlayer.release();
|
||||
synchronized(this.lock){
|
||||
this.mediaPlayer = null;
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
}
|
||||
synchronized(this.lock){
|
||||
this.status = STATUS_EXIT;
|
||||
}
|
||||
|
||||
|
||||
this.CallListener();
|
||||
|
||||
|
188
src/android/src/org/musikcube/core/Workout.java
Normal file
188
src/android/src/org/musikcube/core/Workout.java
Normal file
@ -0,0 +1,188 @@
|
||||
package org.musikcube.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.musikcube.core.IQuery.OnQueryResultListener;
|
||||
import org.musikcube.core.PaceDetector.OnBPMListener;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class Workout implements OnBPMListener, Runnable, OnQueryResultListener {
|
||||
|
||||
|
||||
private static org.musikcube.core.Workout workout = null;
|
||||
private PaceDetector paceDetector;
|
||||
private Context context;
|
||||
private Object lock = new Object();
|
||||
private float bpm = 100;
|
||||
private Thread thread;
|
||||
private boolean active = false;
|
||||
private boolean useAccelerometer = false;
|
||||
private long lastQueryTime = -30000;
|
||||
private int minimumPlaytime = 30000;
|
||||
static final public float BPM_THRESHOLD = 10; // if BPM is off by more than 10 bpm, switch track
|
||||
|
||||
private ArrayList<Integer> selectedCategories = new ArrayList<Integer>();
|
||||
private String category = "";
|
||||
|
||||
public static final synchronized Workout GetInstance(){
|
||||
if(Workout.workout==null){
|
||||
Workout.workout = new org.musikcube.core.Workout();
|
||||
}
|
||||
return Workout.workout;
|
||||
}
|
||||
|
||||
protected Workout(){
|
||||
this.bpm = 100+(float)Math.random();
|
||||
}
|
||||
|
||||
public void Startup(Context context){
|
||||
synchronized (lock) {
|
||||
this.context = context;
|
||||
if(this.active==false){
|
||||
org.musikcube.core.Library.GetInstance().AddPointer();
|
||||
}
|
||||
this.active = true;
|
||||
if(this.listener!=null){
|
||||
this.listener.OnBPMUpdate();
|
||||
}
|
||||
this.UseAccelerometer(this.useAccelerometer);
|
||||
this.QueryTracks(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop(){
|
||||
synchronized (lock) {
|
||||
if(this.active==true){
|
||||
org.musikcube.core.Library.GetInstance().RemovePointer();
|
||||
}
|
||||
this.active = false;
|
||||
this.UseAccelerometer(this.useAccelerometer);
|
||||
if(this.listener!=null){
|
||||
this.listener.OnBPMUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCategory(ArrayList<Integer> selectedCategories,String category){
|
||||
synchronized (lock) {
|
||||
this.selectedCategories = selectedCategories;
|
||||
this.category = category;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean Active(){
|
||||
synchronized (lock) {
|
||||
return this.active;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void UseAccelerometer(boolean use){
|
||||
synchronized(lock){
|
||||
this.useAccelerometer = use;
|
||||
if(this.context!=null){
|
||||
if(use && this.active){
|
||||
if(this.paceDetector==null){
|
||||
this.paceDetector = new PaceDetector();
|
||||
this.paceDetector.SetListener(this);
|
||||
this.paceDetector.StartSensor(this.context);
|
||||
}
|
||||
}
|
||||
if(!use || !this.active){
|
||||
if(this.paceDetector!=null){
|
||||
this.paceDetector.StopSensor(this.context);
|
||||
this.paceDetector = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean Accelerometer(){
|
||||
synchronized(lock){
|
||||
return this.useAccelerometer;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBPM(float bpm){
|
||||
synchronized(lock){
|
||||
if(this.paceDetector==null){
|
||||
this.bpm = bpm;
|
||||
if(this.active){
|
||||
this.QueryTracks(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetBPM(){
|
||||
synchronized(lock){
|
||||
return this.bpm;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBPMUpdate() {
|
||||
synchronized(lock){
|
||||
final float bpm = this.paceDetector.GetBPM();
|
||||
if(bpm>0.0){
|
||||
if(bpm>this.bpm+BPM_THRESHOLD || bpm<this.bpm-BPM_THRESHOLD){
|
||||
this.bpm = bpm;
|
||||
if(this.listener!=null){
|
||||
this.listener.OnBPMUpdate();
|
||||
}
|
||||
this.QueryTracks(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void QueryTracks(boolean force){
|
||||
long currentTime = android.os.SystemClock.elapsedRealtime();
|
||||
// Check that minimum time has passed
|
||||
synchronized(lock){
|
||||
if(currentTime>this.lastQueryTime+this.minimumPlaytime || force){
|
||||
this.lastQueryTime = currentTime;
|
||||
// Get new tracks
|
||||
BPMQuery query = new BPMQuery();
|
||||
query.queryForBPM = this.bpm;
|
||||
query.selectionInts = (ArrayList<Integer>) this.selectedCategories.clone();
|
||||
query.selectionStrings.add(this.category);
|
||||
query.SetResultListener(this);
|
||||
Library.GetInstance().AddQuery(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnWorkoutListener{
|
||||
public void OnBPMUpdate();
|
||||
}
|
||||
protected OnWorkoutListener listener = null;
|
||||
|
||||
public void SetListener(OnWorkoutListener listener){
|
||||
synchronized(this.lock){
|
||||
this.listener = listener;
|
||||
if(this.listener!=null){
|
||||
this.listener.OnBPMUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
}
|
||||
|
||||
public void OnQueryResults(IQuery query) {
|
||||
synchronized(this.lock){
|
||||
this.lastQueryTime = android.os.SystemClock.elapsedRealtime();
|
||||
BPMQuery bpmQuery = (BPMQuery)query;
|
||||
if(!bpmQuery.trackList.isEmpty() && this.context!=null){
|
||||
Intent intent = new Intent(this.context, org.musikcube.Service.class);
|
||||
intent.putExtra("org.musikcube.Service.tracklist", bpmQuery.trackList);
|
||||
intent.putExtra("org.musikcube.Service.position", 0);
|
||||
intent.putExtra("org.musikcube.Service.action", "playlist_prepare");
|
||||
this.context.startService(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,6 @@ import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
@ -38,9 +37,12 @@ public class main extends Activity implements OnLibraryStatusListener {
|
||||
yearButton.setOnClickListener(this.onYearClick);
|
||||
yearButton.setEnabled(false);
|
||||
|
||||
Button bpmButton = (Button)findViewById(R.id.BPMButton);
|
||||
bpmButton.setOnClickListener(this.onBPMClick);
|
||||
bpmButton.setEnabled(false);
|
||||
Button bpmGenreButton = (Button)findViewById(R.id.BPMGenreButton);
|
||||
bpmGenreButton.setOnClickListener(this.onBPMGenreClick);
|
||||
bpmGenreButton.setEnabled(false);
|
||||
Button bpmArtistButton = (Button)findViewById(R.id.BPMArtistButton);
|
||||
bpmArtistButton.setOnClickListener(this.onBPMArtistClick);
|
||||
bpmArtistButton.setEnabled(false);
|
||||
|
||||
}
|
||||
|
||||
@ -68,18 +70,22 @@ public class main extends Activity implements OnLibraryStatusListener {
|
||||
}
|
||||
};
|
||||
|
||||
private OnClickListener onBPMClick = new OnClickListener() {
|
||||
private OnClickListener onBPMGenreClick = new OnClickListener() {
|
||||
public void onClick(View v){
|
||||
/* 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);
|
||||
}
|
||||
};
|
||||
|
||||
private OnClickListener onBPMArtistClick = new OnClickListener() {
|
||||
public void onClick(View v){
|
||||
Intent intent = new Intent(main.this, CategorySelect.class);
|
||||
intent.putExtra("org.musikcube.CategorySelect.listCategory", "artist");
|
||||
startActivity(intent);
|
||||
}
|
||||
};
|
||||
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.default_menu, menu);
|
||||
@ -104,7 +110,6 @@ public class main extends Activity implements OnLibraryStatusListener {
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
Log.v("mC2::Main","onResume");
|
||||
super.onResume();
|
||||
startService(new Intent(this, org.musikcube.Service.class));
|
||||
org.musikcube.core.Library.GetInstance().AddPointer();
|
||||
@ -129,18 +134,21 @@ public class main extends Activity implements OnLibraryStatusListener {
|
||||
Button genreButton = (Button)findViewById(R.id.GenresButton);
|
||||
Button artistsButton = (Button)findViewById(R.id.ArtistsButton);
|
||||
Button yearButton = (Button)findViewById(R.id.YearButton);
|
||||
Button bpmButton = (Button)findViewById(R.id.BPMButton);
|
||||
Button bpmGenreButton = (Button)findViewById(R.id.BPMGenreButton);
|
||||
Button bpmArtistButton = (Button)findViewById(R.id.BPMArtistButton);
|
||||
|
||||
if(status==Library.STATUS_CONNECTED){
|
||||
genreButton.setEnabled(true);
|
||||
artistsButton.setEnabled(true);
|
||||
yearButton.setEnabled(true);
|
||||
bpmButton.setEnabled(false);
|
||||
bpmGenreButton.setEnabled(true);
|
||||
bpmArtistButton.setEnabled(true);
|
||||
}else{
|
||||
genreButton.setEnabled(false);
|
||||
artistsButton.setEnabled(false);
|
||||
yearButton.setEnabled(false);
|
||||
bpmButton.setEnabled(false);
|
||||
bpmGenreButton.setEnabled(false);
|
||||
bpmArtistButton.setEnabled(false);
|
||||
}
|
||||
|
||||
TextView statusText = (TextView)findViewById(R.id.StatusView);
|
||||
|
Loading…
Reference in New Issue
Block a user