Remove windows line-endings

This commit is contained in:
Christopher Eby 2010-02-19 19:37:33 -06:00
parent 41dc843dcc
commit 3220ee32be
13 changed files with 1156 additions and 1156 deletions

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="output" path="bin"/>
</classpath>

@ -1,33 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Tumult</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Tumult</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

@ -1,5 +1,5 @@
#Thu Dec 24 11:30:20 CST 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.source=1.5
#Thu Dec 24 11:30:20 CST 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.source=1.5

@ -1,307 +1,307 @@
package org.kreed.tumult;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.Scroller;
public class CoverView extends View {
private static final int SNAP_VELOCITY = 1000;
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private float mLastMotionX;
private float mStartX;
private float mStartY;
private CoverViewWatcher mListener;
Song[] mSongs = new Song[3];
private Bitmap[] mBitmaps = new Bitmap[3];
private int mTentativeCover = -1;
public interface CoverViewWatcher {
public void next();
public void previous();
public void clicked();
}
public CoverView(Context context, AttributeSet attributes)
{
super(context, attributes);
mScroller = new Scroller(context);
}
public void setWatcher(CoverViewWatcher listener)
{
mListener = listener;
}
private RectF scale(Bitmap bitmap, int maxWidth, int maxHeight)
{
float bitmapWidth = bitmap.getWidth();
float bitmapHeight = bitmap.getHeight();
float drawableAspectRatio = bitmapHeight / bitmapWidth;
float viewAspectRatio = (float) maxHeight / maxWidth;
float scale = drawableAspectRatio > viewAspectRatio ? maxHeight / bitmapWidth
: maxWidth / bitmapHeight;
bitmapWidth *= scale;
bitmapHeight *= scale;
float left = (maxWidth - bitmapWidth) / 2;
float top = (maxHeight - bitmapHeight) / 2;
return new RectF(left, top, maxWidth - left, maxHeight - top);
}
private void drawText(Canvas canvas, String text, float left, float top, float width, float maxWidth, Paint paint)
{
float offset = Math.max(0, maxWidth - width) / 2;
canvas.clipRect(left, top, left + maxWidth, top + paint.getTextSize() * 2, Region.Op.REPLACE);
canvas.drawText(text, left + offset, top - paint.ascent(), paint);
}
private void createBitmap(int i)
{
Song song = mSongs[i];
Bitmap bitmap = null;
if (song != null) {
int width = getWidth();
int height = getHeight();
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
Bitmap cover = song.coverPath == null ? null : BitmapFactory.decodeFile(song.coverPath);
if (cover != null) {
RectF dest = scale(cover, width, height);
canvas.drawBitmap(cover, new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), dest, paint);
cover.recycle();
cover = null;
}
paint.setAntiAlias(true);
String title = song.title == null ? "" : song.title;
String album = song.album == null ? "" : song.album;
String artist = song.artist == null ? "" : song.artist;
float titleSize = 20;
float subSize = 14;
float padding = 10;
paint.setTextSize(titleSize);
float titleWidth = paint.measureText(title);
paint.setTextSize(subSize);
float albumWidth = paint.measureText(album);
float artistWidth = paint.measureText(artist);
float boxWidth = Math.max(titleWidth, Math.max(artistWidth, albumWidth)) + padding * 2;
float boxHeight = titleSize + subSize * 2 + padding * 4;
boxWidth = Math.min(boxWidth, width);
boxHeight = Math.min(boxHeight, height);
paint.setARGB(150, 0, 0, 0);
float left = (width - boxWidth) / 2;
float top = (height - boxHeight) / 2;
float right = (width + boxWidth) / 2;
float bottom = (height + boxHeight) / 2;
canvas.drawRect(left, top, right, bottom, paint);
float maxWidth = boxWidth - padding * 2;
paint.setARGB(255, 255, 255, 255);
top += padding;
left += padding;
paint.setTextSize(titleSize);
drawText(canvas, title, left, top, titleWidth, maxWidth, paint);
top += titleSize + padding;
paint.setTextSize(subSize);
drawText(canvas, album, left, top, albumWidth, maxWidth, paint);
top += subSize + padding;
drawText(canvas, artist, left, top, artistWidth, maxWidth, paint);
}
Bitmap oldBitmap = mBitmaps[i];
mBitmaps[i] = bitmap;
if (oldBitmap != null)
oldBitmap.recycle();
}
public void setSongs(Song[] songs)
{
mSongs = songs;
regenerateBitmaps();
}
public void regenerateBitmaps()
{
if (getWidth() == 0 || getHeight() == 0)
return;
for (int i = mSongs.length; --i != -1; )
createBitmap(i);
reset();
}
public void setForwardSong(Song song)
{
if (mSongs[mSongs.length - 1] != null) {
System.arraycopy(mSongs, 1, mSongs, 0, mSongs.length - 1);
System.arraycopy(mBitmaps, 1, mBitmaps, 0, mBitmaps.length - 1);
mBitmaps[mBitmaps.length - 1] = null;
reset();
}
mSongs[mSongs.length - 1] = song;
createBitmap(mSongs.length - 1);
}
public void setBackwardSong(Song song)
{
if (mSongs[0] != null) {
System.arraycopy(mSongs, 0, mSongs, 1, mSongs.length - 1);
System.arraycopy(mBitmaps, 0, mBitmaps, 1, mBitmaps.length - 1);
mBitmaps[0] = null;
reset();
}
mSongs[0] = song;
createBitmap(0);
}
public void reset()
{
if (!mScroller.isFinished())
mScroller.abortAnimation();
scrollTo(getWidth(), 0);
postInvalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
regenerateBitmaps();
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Rect clip = canvas.getClipBounds();
Paint paint = new Paint();
int width = getWidth();
int height = getHeight();
for (int x = 0, i = 0; i != mBitmaps.length; ++i, x += width)
if (mBitmaps[i] != null && clip.intersects(x, 0, x + width, height))
canvas.drawBitmap(mBitmaps[i], x, 0, paint);
paint = null;
}
@Override
public boolean onTouchEvent(MotionEvent ev)
{
// based on code from com.android.launcher.Workspace
if (mVelocityTracker == null)
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(ev);
float x = ev.getX();
int scrollX = getScrollX();
int width = getWidth();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!mScroller.isFinished())
mScroller.abortAnimation();
mStartX = x;
mStartY = ev.getY();
mLastMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
int deltaX = (int) (mLastMotionX - x);
mLastMotionX = x;
if (deltaX < 0) {
int availableToScroll = scrollX - (mBitmaps[0] == null ? width : 0);
if (availableToScroll > 0)
scrollBy(Math.max(-availableToScroll, deltaX), 0);
} else if (deltaX > 0) {
int availableToScroll = getWidth() * 2 - scrollX;
if (availableToScroll > 0)
scrollBy(Math.min(availableToScroll, deltaX), 0);
}
break;
case MotionEvent.ACTION_UP:
if (Math.abs(mStartX - x) + Math.abs(mStartY - ev.getY()) < 10) {
mListener.clicked();
} else {
VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int velocity = (int) velocityTracker.getXVelocity();
int min = mBitmaps[0] == null ? 1 : 0;
int max = 2;
int nearestCover = (scrollX + width / 2) / width;
int whichCover = Math.max(min, Math.min(nearestCover, max));
if (velocity > SNAP_VELOCITY && whichCover != min)
--whichCover;
else if (velocity < -SNAP_VELOCITY && whichCover != max)
++whichCover;
int newX = whichCover * width;
int delta = newX - scrollX;
mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 2);
mTentativeCover = whichCover;
postInvalidate();
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
return true;
}
public void computeScroll()
{
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
} else if (mTentativeCover != -1) {
if (mListener != null) {
if (mTentativeCover == 2)
mListener.next();
else if (mTentativeCover == 0)
mListener.previous();
}
mTentativeCover = -1;
}
}
}
package org.kreed.tumult;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.Scroller;
public class CoverView extends View {
private static final int SNAP_VELOCITY = 1000;
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private float mLastMotionX;
private float mStartX;
private float mStartY;
private CoverViewWatcher mListener;
Song[] mSongs = new Song[3];
private Bitmap[] mBitmaps = new Bitmap[3];
private int mTentativeCover = -1;
public interface CoverViewWatcher {
public void next();
public void previous();
public void clicked();
}
public CoverView(Context context, AttributeSet attributes)
{
super(context, attributes);
mScroller = new Scroller(context);
}
public void setWatcher(CoverViewWatcher listener)
{
mListener = listener;
}
private RectF scale(Bitmap bitmap, int maxWidth, int maxHeight)
{
float bitmapWidth = bitmap.getWidth();
float bitmapHeight = bitmap.getHeight();
float drawableAspectRatio = bitmapHeight / bitmapWidth;
float viewAspectRatio = (float) maxHeight / maxWidth;
float scale = drawableAspectRatio > viewAspectRatio ? maxHeight / bitmapWidth
: maxWidth / bitmapHeight;
bitmapWidth *= scale;
bitmapHeight *= scale;
float left = (maxWidth - bitmapWidth) / 2;
float top = (maxHeight - bitmapHeight) / 2;
return new RectF(left, top, maxWidth - left, maxHeight - top);
}
private void drawText(Canvas canvas, String text, float left, float top, float width, float maxWidth, Paint paint)
{
float offset = Math.max(0, maxWidth - width) / 2;
canvas.clipRect(left, top, left + maxWidth, top + paint.getTextSize() * 2, Region.Op.REPLACE);
canvas.drawText(text, left + offset, top - paint.ascent(), paint);
}
private void createBitmap(int i)
{
Song song = mSongs[i];
Bitmap bitmap = null;
if (song != null) {
int width = getWidth();
int height = getHeight();
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
Bitmap cover = song.coverPath == null ? null : BitmapFactory.decodeFile(song.coverPath);
if (cover != null) {
RectF dest = scale(cover, width, height);
canvas.drawBitmap(cover, new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), dest, paint);
cover.recycle();
cover = null;
}
paint.setAntiAlias(true);
String title = song.title == null ? "" : song.title;
String album = song.album == null ? "" : song.album;
String artist = song.artist == null ? "" : song.artist;
float titleSize = 20;
float subSize = 14;
float padding = 10;
paint.setTextSize(titleSize);
float titleWidth = paint.measureText(title);
paint.setTextSize(subSize);
float albumWidth = paint.measureText(album);
float artistWidth = paint.measureText(artist);
float boxWidth = Math.max(titleWidth, Math.max(artistWidth, albumWidth)) + padding * 2;
float boxHeight = titleSize + subSize * 2 + padding * 4;
boxWidth = Math.min(boxWidth, width);
boxHeight = Math.min(boxHeight, height);
paint.setARGB(150, 0, 0, 0);
float left = (width - boxWidth) / 2;
float top = (height - boxHeight) / 2;
float right = (width + boxWidth) / 2;
float bottom = (height + boxHeight) / 2;
canvas.drawRect(left, top, right, bottom, paint);
float maxWidth = boxWidth - padding * 2;
paint.setARGB(255, 255, 255, 255);
top += padding;
left += padding;
paint.setTextSize(titleSize);
drawText(canvas, title, left, top, titleWidth, maxWidth, paint);
top += titleSize + padding;
paint.setTextSize(subSize);
drawText(canvas, album, left, top, albumWidth, maxWidth, paint);
top += subSize + padding;
drawText(canvas, artist, left, top, artistWidth, maxWidth, paint);
}
Bitmap oldBitmap = mBitmaps[i];
mBitmaps[i] = bitmap;
if (oldBitmap != null)
oldBitmap.recycle();
}
public void setSongs(Song[] songs)
{
mSongs = songs;
regenerateBitmaps();
}
public void regenerateBitmaps()
{
if (getWidth() == 0 || getHeight() == 0)
return;
for (int i = mSongs.length; --i != -1; )
createBitmap(i);
reset();
}
public void setForwardSong(Song song)
{
if (mSongs[mSongs.length - 1] != null) {
System.arraycopy(mSongs, 1, mSongs, 0, mSongs.length - 1);
System.arraycopy(mBitmaps, 1, mBitmaps, 0, mBitmaps.length - 1);
mBitmaps[mBitmaps.length - 1] = null;
reset();
}
mSongs[mSongs.length - 1] = song;
createBitmap(mSongs.length - 1);
}
public void setBackwardSong(Song song)
{
if (mSongs[0] != null) {
System.arraycopy(mSongs, 0, mSongs, 1, mSongs.length - 1);
System.arraycopy(mBitmaps, 0, mBitmaps, 1, mBitmaps.length - 1);
mBitmaps[0] = null;
reset();
}
mSongs[0] = song;
createBitmap(0);
}
public void reset()
{
if (!mScroller.isFinished())
mScroller.abortAnimation();
scrollTo(getWidth(), 0);
postInvalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
regenerateBitmaps();
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Rect clip = canvas.getClipBounds();
Paint paint = new Paint();
int width = getWidth();
int height = getHeight();
for (int x = 0, i = 0; i != mBitmaps.length; ++i, x += width)
if (mBitmaps[i] != null && clip.intersects(x, 0, x + width, height))
canvas.drawBitmap(mBitmaps[i], x, 0, paint);
paint = null;
}
@Override
public boolean onTouchEvent(MotionEvent ev)
{
// based on code from com.android.launcher.Workspace
if (mVelocityTracker == null)
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(ev);
float x = ev.getX();
int scrollX = getScrollX();
int width = getWidth();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!mScroller.isFinished())
mScroller.abortAnimation();
mStartX = x;
mStartY = ev.getY();
mLastMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
int deltaX = (int) (mLastMotionX - x);
mLastMotionX = x;
if (deltaX < 0) {
int availableToScroll = scrollX - (mBitmaps[0] == null ? width : 0);
if (availableToScroll > 0)
scrollBy(Math.max(-availableToScroll, deltaX), 0);
} else if (deltaX > 0) {
int availableToScroll = getWidth() * 2 - scrollX;
if (availableToScroll > 0)
scrollBy(Math.min(availableToScroll, deltaX), 0);
}
break;
case MotionEvent.ACTION_UP:
if (Math.abs(mStartX - x) + Math.abs(mStartY - ev.getY()) < 10) {
mListener.clicked();
} else {
VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int velocity = (int) velocityTracker.getXVelocity();
int min = mBitmaps[0] == null ? 1 : 0;
int max = 2;
int nearestCover = (scrollX + width / 2) / width;
int whichCover = Math.max(min, Math.min(nearestCover, max));
if (velocity > SNAP_VELOCITY && whichCover != min)
--whichCover;
else if (velocity < -SNAP_VELOCITY && whichCover != max)
++whichCover;
int newX = whichCover * width;
int delta = newX - scrollX;
mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 2);
mTentativeCover = whichCover;
postInvalidate();
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
return true;
}
public void computeScroll()
{
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
} else if (mTentativeCover != -1) {
if (mListener != null) {
if (mTentativeCover == 2)
mListener.next();
else if (mTentativeCover == 0)
mListener.previous();
}
mTentativeCover = -1;
}
}
}

@ -1,10 +1,10 @@
package org.kreed.tumult;
import org.kreed.tumult.Song;
oneway interface IMusicPlayerWatcher {
void previousSong(in Song playingSong, in Song nextForwardSong);
void nextSong(in Song playingSong, in Song nextBackwardSong);
void stateChanged(in int oldState, in int newState);
void mediaLengthChanged(in long startTime, in int duration);
package org.kreed.tumult;
import org.kreed.tumult.Song;
oneway interface IMusicPlayerWatcher {
void previousSong(in Song playingSong, in Song nextForwardSong);
void nextSong(in Song playingSong, in Song nextBackwardSong);
void stateChanged(in int oldState, in int newState);
void mediaLengthChanged(in long startTime, in int duration);
}

@ -1,18 +1,18 @@
package org.kreed.tumult;
import org.kreed.tumult.Song;
import org.kreed.tumult.IMusicPlayerWatcher;
interface IPlaybackService {
void registerWatcher(IMusicPlayerWatcher watcher);
Song[] getCurrentSongs();
int getState();
long getStartTime();
int getDuration();
void previousSong();
void togglePlayback();
void nextSong();
void seekToProgress(int progress);
package org.kreed.tumult;
import org.kreed.tumult.Song;
import org.kreed.tumult.IMusicPlayerWatcher;
interface IPlaybackService {
void registerWatcher(IMusicPlayerWatcher watcher);
Song[] getCurrentSongs();
int getState();
long getStartTime();
int getDuration();
void previousSong();
void togglePlayback();
void nextSong();
void seekToProgress(int progress);
}

@ -1,430 +1,430 @@
package org.kreed.tumult;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.preference.PreferenceManager;
public class MusicPlayer implements Runnable, MediaPlayer.OnCompletionListener, SharedPreferences.OnSharedPreferenceChangeListener {
private static final int NOTIFICATION_ID = 2;
public static final int STATE_NORMAL = 0;
public static final int STATE_NO_MEDIA = 1;
public static final int STATE_PLAYING = 2;
public IPlaybackService.Stub mBinder = new IPlaybackService.Stub() {
public Song[] getCurrentSongs()
{
return new Song[] { getSong(-1), getSong(0), getSong(1) };
}
public int getState()
{
return mState;
}
public long getStartTime()
{
if (mMediaPlayer == null)
return 0;
return MusicPlayer.this.getStartTime();
}
public int getDuration()
{
if (mMediaPlayer == null)
return 0;
return mMediaPlayer.getDuration();
}
public void nextSong()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(SET_SONG, 1, 0));
}
public void previousSong()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(SET_SONG, -1, 0));
}
public void togglePlayback()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(PLAY_PAUSE, 0, 0));
}
public void registerWatcher(IMusicPlayerWatcher watcher)
{
if (watcher != null)
mWatchers.register(watcher);
}
public void seekToProgress(int progress)
{
if (mMediaPlayer == null || !mMediaPlayer.isPlaying())
return;
long position = (long)mMediaPlayer.getDuration() * progress / 1000;
mMediaPlayer.seekTo((int)position);
mediaLengthChanged();
}
};
public void queueSong(int songId)
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(QUEUE_ITEM, ITEM_SONG, songId));
}
public void stopQueueing()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(QUEUE_ITEM, ITEM_RESET, 0));
}
private PlaybackService mService;
private RemoteCallbackList<IMusicPlayerWatcher> mWatchers;
private boolean mHeadsetOnly = true;
private Handler mHandler;
private MediaPlayer mMediaPlayer;
private Random mRandom;
private PowerManager.WakeLock mWakeLock;
private int[] mSongs;
private ArrayList<Song> mSongTimeline;
private int mCurrentSong = -1;
private int mQueuePos = 0;
private boolean mPlugged = true;
private int mState = STATE_NORMAL;
public MusicPlayer(PlaybackService service)
{
mService = service;
mWatchers = new RemoteCallbackList<IMusicPlayerWatcher>();
mSongTimeline = new ArrayList<Song>();
new Thread(this).start();
}
private static final int SET_SONG = 0;
private static final int PLAY_PAUSE = 1;
private static final int HEADSET_PLUGGED = 2;
private static final int HEADSET_PREF_CHANGED = 3;
private static final int QUEUE_ITEM = 4;
private static final int TRACK_CHANGED = 5;
private static final int RELEASE_WAKE_LOCK = 6;
private static final int ITEM_SONG = 0;
private static final int ITEM_RESET = 1;
public void run()
{
Looper.prepare();
mMediaPlayer = new MediaPlayer();
mRandom = new Random();
mHandler = new Handler() {
public void handleMessage(Message message)
{
switch (message.what) {
case SET_SONG:
setCurrentSong(message.arg1);
break;
case PLAY_PAUSE:
if (mCurrentSong == -1) {
setCurrentSong(+1);
return;
}
setPlaying(!mMediaPlayer.isPlaying());
break;
case HEADSET_PLUGGED:
boolean plugged = message.arg1 == 1;
if (plugged != mPlugged) {
mPlugged = plugged;
if (mCurrentSong == -1 || mPlugged == mMediaPlayer.isPlaying())
return;
setPlaying(mPlugged);
}
break;
case HEADSET_PREF_CHANGED:
mHeadsetOnly = message.arg1 == 1;
if (mHeadsetOnly && !mPlugged && mMediaPlayer.isPlaying())
pause();
break;
case QUEUE_ITEM:
switch (message.arg1) {
case ITEM_SONG:
int i = mCurrentSong + 1 + mQueuePos++;
Song song = new Song(message.arg2);
Toast.makeText(Tumult.getContext(), "Enqueued " + song.title, Toast.LENGTH_SHORT).show();
if (i < mSongTimeline.size())
mSongTimeline.set(i, song);
else
mSongTimeline.add(song);
break;
case ITEM_RESET:
mQueuePos = 0;
break;
}
break;
case TRACK_CHANGED:
setCurrentSong(+1);
break;
case RELEASE_WAKE_LOCK:
if (mWakeLock.isHeld())
mWakeLock.release();
break;
}
}
};
mService.registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
PowerManager powerManager = (PowerManager)mService.getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TumultSongChangeLock");
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setWakeMode(mService, PowerManager.PARTIAL_WAKE_LOCK);
mMediaPlayer.setOnCompletionListener(this);
retrieveSongs();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mService);
mHeadsetOnly = settings.getBoolean("headset_only", false);
settings.registerOnSharedPreferenceChangeListener(this);
mHandler.post(new Runnable() {
public void run()
{
setCurrentSong(1);
}
});
Looper.loop();
}
public void release()
{
if (mMediaPlayer != null) {
pause();
mMediaPlayer.release();
mMediaPlayer = null;
}
if (mWakeLock != null && mWakeLock.isHeld())
mWakeLock.release();
}
public void setState(int state)
{
if (mState == state)
return;
int oldState = mState;
mState = state;
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).stateChanged(oldState, mState);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
}
private void retrieveSongs()
{
mSongs = Song.getAllSongs();
if (mSongs == null && mState == STATE_NORMAL)
setState(STATE_NO_MEDIA);
}
private void play()
{
if (mHeadsetOnly && !mPlugged)
return;
mMediaPlayer.start();
Song song = getSong(0);
RemoteViews views = new RemoteViews(mService.getPackageName(), R.layout.statusbar);
views.setImageViewResource(R.id.icon, R.drawable.status_icon);
views.setTextViewText(R.id.title, song.title);
views.setTextViewText(R.id.artist, song.artist);
Notification notification = new Notification();
notification.contentView = views;
notification.icon = R.drawable.status_icon;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
Intent intent = new Intent(mService, NowPlayingActivity.class);
notification.contentIntent = PendingIntent.getActivity(mService, 0, intent, 0);
mService.startForegroundCompat(NOTIFICATION_ID, notification);
setState(STATE_PLAYING);
}
private void pause()
{
mMediaPlayer.pause();
mService.stopForegroundCompat(NOTIFICATION_ID);
setState(STATE_NORMAL);
}
private void setPlaying(boolean play)
{
if (play)
play();
else
pause();
}
private void setCurrentSong(int delta)
{
Song song = getSong(delta);
if (song == null)
return;
mCurrentSong += delta;
Song newSong = getSong(delta);
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
if (delta < 0)
mWatchers.getBroadcastItem(i).previousSong(song, newSong);
else
mWatchers.getBroadcastItem(i).nextSong(song, newSong);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(song.path);
mMediaPlayer.prepare();
if (mState == STATE_PLAYING)
play();
} catch (IOException e) {
Log.e("Tumult", "IOException", e);
}
mediaLengthChanged();
getSong(+2);
while (mCurrentSong > 15) {
mSongTimeline.remove(0);
--mCurrentSong;
}
}
private long getStartTime()
{
int position = mMediaPlayer.getCurrentPosition();
return System.currentTimeMillis() - position;
}
private void mediaLengthChanged()
{
long start = getStartTime();
int duration = mMediaPlayer.getDuration();
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).mediaLengthChanged(start, duration);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
}
public void onCompletion(MediaPlayer player)
{
mWakeLock.acquire();
mHandler.sendEmptyMessage(TRACK_CHANGED);
mHandler.sendEmptyMessage(RELEASE_WAKE_LOCK);
}
private Song randomSong()
{
return new Song(mSongs[mRandom.nextInt(mSongs.length)]);
}
private synchronized Song getSong(int delta)
{
int pos = mCurrentSong + delta;
if (pos < 0)
return null;
int size = mSongTimeline.size();
if (pos > size)
return null;
if (pos == size) {
if (mSongs == null)
return null;
mSongTimeline.add(randomSong());
}
return mSongTimeline.get(pos);
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context content, Intent intent)
{
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG) && mHandler != null) {
int plugged = intent.getIntExtra("state", 0) == 130 ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(HEADSET_PLUGGED, plugged, 0));
}
}
};
public void onSharedPreferenceChanged(SharedPreferences settings, String key)
{
if ("headset_only".equals(key) && mHandler != null) {
int arg = settings.getBoolean(key, false) ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(HEADSET_PREF_CHANGED, arg, 0));
}
}
}
package org.kreed.tumult;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.preference.PreferenceManager;
public class MusicPlayer implements Runnable, MediaPlayer.OnCompletionListener, SharedPreferences.OnSharedPreferenceChangeListener {
private static final int NOTIFICATION_ID = 2;
public static final int STATE_NORMAL = 0;
public static final int STATE_NO_MEDIA = 1;
public static final int STATE_PLAYING = 2;
public IPlaybackService.Stub mBinder = new IPlaybackService.Stub() {
public Song[] getCurrentSongs()
{
return new Song[] { getSong(-1), getSong(0), getSong(1) };
}
public int getState()
{
return mState;
}
public long getStartTime()
{
if (mMediaPlayer == null)
return 0;
return MusicPlayer.this.getStartTime();
}
public int getDuration()
{
if (mMediaPlayer == null)
return 0;
return mMediaPlayer.getDuration();
}
public void nextSong()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(SET_SONG, 1, 0));
}
public void previousSong()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(SET_SONG, -1, 0));
}
public void togglePlayback()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(PLAY_PAUSE, 0, 0));
}
public void registerWatcher(IMusicPlayerWatcher watcher)
{
if (watcher != null)
mWatchers.register(watcher);
}
public void seekToProgress(int progress)
{
if (mMediaPlayer == null || !mMediaPlayer.isPlaying())
return;
long position = (long)mMediaPlayer.getDuration() * progress / 1000;
mMediaPlayer.seekTo((int)position);
mediaLengthChanged();
}
};
public void queueSong(int songId)
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(QUEUE_ITEM, ITEM_SONG, songId));
}
public void stopQueueing()
{
if (mHandler == null)
return;
mHandler.sendMessage(mHandler.obtainMessage(QUEUE_ITEM, ITEM_RESET, 0));
}
private PlaybackService mService;
private RemoteCallbackList<IMusicPlayerWatcher> mWatchers;
private boolean mHeadsetOnly = true;
private Handler mHandler;
private MediaPlayer mMediaPlayer;
private Random mRandom;
private PowerManager.WakeLock mWakeLock;
private int[] mSongs;
private ArrayList<Song> mSongTimeline;
private int mCurrentSong = -1;
private int mQueuePos = 0;
private boolean mPlugged = true;
private int mState = STATE_NORMAL;
public MusicPlayer(PlaybackService service)
{
mService = service;
mWatchers = new RemoteCallbackList<IMusicPlayerWatcher>();
mSongTimeline = new ArrayList<Song>();
new Thread(this).start();
}
private static final int SET_SONG = 0;
private static final int PLAY_PAUSE = 1;
private static final int HEADSET_PLUGGED = 2;
private static final int HEADSET_PREF_CHANGED = 3;
private static final int QUEUE_ITEM = 4;
private static final int TRACK_CHANGED = 5;
private static final int RELEASE_WAKE_LOCK = 6;
private static final int ITEM_SONG = 0;
private static final int ITEM_RESET = 1;
public void run()
{
Looper.prepare();
mMediaPlayer = new MediaPlayer();
mRandom = new Random();
mHandler = new Handler() {
public void handleMessage(Message message)
{
switch (message.what) {
case SET_SONG:
setCurrentSong(message.arg1);
break;
case PLAY_PAUSE:
if (mCurrentSong == -1) {
setCurrentSong(+1);
return;
}
setPlaying(!mMediaPlayer.isPlaying());
break;
case HEADSET_PLUGGED:
boolean plugged = message.arg1 == 1;
if (plugged != mPlugged) {
mPlugged = plugged;
if (mCurrentSong == -1 || mPlugged == mMediaPlayer.isPlaying())
return;
setPlaying(mPlugged);
}
break;
case HEADSET_PREF_CHANGED:
mHeadsetOnly = message.arg1 == 1;
if (mHeadsetOnly && !mPlugged && mMediaPlayer.isPlaying())
pause();
break;
case QUEUE_ITEM:
switch (message.arg1) {
case ITEM_SONG:
int i = mCurrentSong + 1 + mQueuePos++;
Song song = new Song(message.arg2);
Toast.makeText(Tumult.getContext(), "Enqueued " + song.title, Toast.LENGTH_SHORT).show();
if (i < mSongTimeline.size())
mSongTimeline.set(i, song);
else
mSongTimeline.add(song);
break;
case ITEM_RESET:
mQueuePos = 0;
break;
}
break;
case TRACK_CHANGED:
setCurrentSong(+1);
break;
case RELEASE_WAKE_LOCK:
if (mWakeLock.isHeld())
mWakeLock.release();
break;
}
}
};
mService.registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
PowerManager powerManager = (PowerManager)mService.getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TumultSongChangeLock");
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setWakeMode(mService, PowerManager.PARTIAL_WAKE_LOCK);
mMediaPlayer.setOnCompletionListener(this);
retrieveSongs();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mService);
mHeadsetOnly = settings.getBoolean("headset_only", false);
settings.registerOnSharedPreferenceChangeListener(this);
mHandler.post(new Runnable() {
public void run()
{
setCurrentSong(1);
}
});
Looper.loop();
}
public void release()
{
if (mMediaPlayer != null) {
pause();
mMediaPlayer.release();
mMediaPlayer = null;
}
if (mWakeLock != null && mWakeLock.isHeld())
mWakeLock.release();
}
public void setState(int state)
{
if (mState == state)
return;
int oldState = mState;
mState = state;
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).stateChanged(oldState, mState);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
}
private void retrieveSongs()
{
mSongs = Song.getAllSongs();
if (mSongs == null && mState == STATE_NORMAL)
setState(STATE_NO_MEDIA);
}
private void play()
{
if (mHeadsetOnly && !mPlugged)
return;
mMediaPlayer.start();
Song song = getSong(0);
RemoteViews views = new RemoteViews(mService.getPackageName(), R.layout.statusbar);
views.setImageViewResource(R.id.icon, R.drawable.status_icon);
views.setTextViewText(R.id.title, song.title);
views.setTextViewText(R.id.artist, song.artist);
Notification notification = new Notification();
notification.contentView = views;
notification.icon = R.drawable.status_icon;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
Intent intent = new Intent(mService, NowPlayingActivity.class);
notification.contentIntent = PendingIntent.getActivity(mService, 0, intent, 0);
mService.startForegroundCompat(NOTIFICATION_ID, notification);
setState(STATE_PLAYING);
}
private void pause()
{
mMediaPlayer.pause();
mService.stopForegroundCompat(NOTIFICATION_ID);
setState(STATE_NORMAL);
}
private void setPlaying(boolean play)
{
if (play)
play();
else
pause();
}
private void setCurrentSong(int delta)
{
Song song = getSong(delta);
if (song == null)
return;
mCurrentSong += delta;
Song newSong = getSong(delta);
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
if (delta < 0)
mWatchers.getBroadcastItem(i).previousSong(song, newSong);
else
mWatchers.getBroadcastItem(i).nextSong(song, newSong);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(song.path);
mMediaPlayer.prepare();
if (mState == STATE_PLAYING)
play();
} catch (IOException e) {
Log.e("Tumult", "IOException", e);
}
mediaLengthChanged();
getSong(+2);
while (mCurrentSong > 15) {
mSongTimeline.remove(0);
--mCurrentSong;
}
}
private long getStartTime()
{
int position = mMediaPlayer.getCurrentPosition();
return System.currentTimeMillis() - position;
}
private void mediaLengthChanged()
{
long start = getStartTime();
int duration = mMediaPlayer.getDuration();
int i = mWatchers.beginBroadcast();
while (--i != -1) {
try {
mWatchers.getBroadcastItem(i).mediaLengthChanged(start, duration);
} catch (RemoteException e) {
// Null elements will be removed automatically
}
}
mWatchers.finishBroadcast();
}
public void onCompletion(MediaPlayer player)
{
mWakeLock.acquire();
mHandler.sendEmptyMessage(TRACK_CHANGED);
mHandler.sendEmptyMessage(RELEASE_WAKE_LOCK);
}
private Song randomSong()
{
return new Song(mSongs[mRandom.nextInt(mSongs.length)]);
}
private synchronized Song getSong(int delta)
{
int pos = mCurrentSong + delta;
if (pos < 0)
return null;
int size = mSongTimeline.size();
if (pos > size)
return null;
if (pos == size) {
if (mSongs == null)
return null;
mSongTimeline.add(randomSong());
}
return mSongTimeline.get(pos);
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context content, Intent intent)
{
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG) && mHandler != null) {
int plugged = intent.getIntExtra("state", 0) == 130 ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(HEADSET_PLUGGED, plugged, 0));
}
}
};
public void onSharedPreferenceChanged(SharedPreferences settings, String key)
{
if ("headset_only".equals(key) && mHandler != null) {
int arg = settings.getBoolean(key, false) ? 1 : 0;
mHandler.sendMessage(mHandler.obtainMessage(HEADSET_PREF_CHANGED, arg, 0));
}
}
}

@ -1,96 +1,96 @@
package org.kreed.tumult;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class PlaybackService extends Service {
private MusicPlayer mPlayer;
private NotificationManager mNotificationManager;
private Method mStartForeground;
private Method mStopForeground;
@Override
public IBinder onBind(Intent intent)
{
if (mPlayer == null)
return null;
return mPlayer.mBinder;
}
@Override
public void onCreate()
{
mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
try {
mStartForeground = getClass().getMethod("startForeground", new Class[] { int.class, Notification.class });
mStopForeground = getClass().getMethod("stopForeground", new Class[] { boolean.class });
} catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
mPlayer = new MusicPlayer(this);
}
@Override
public void onStart(Intent intent, int flags)
{
int id;
if ((id = intent.getIntExtra("songId", -1)) != -1)
mPlayer.queueSong(id);
else
mPlayer.stopQueueing();
}
@Override
public void onDestroy()
{
super.onDestroy();
if (mPlayer != null) {
mPlayer.release();
mPlayer = null;
}
}
public void startForegroundCompat(int id, Notification notification)
{
if (mStartForeground == null) {
setForeground(true);
mNotificationManager.notify(id, notification);
} else {
Object[] startForegroundArgs = { Integer.valueOf(id), notification };
try {
mStartForeground.invoke(this, startForegroundArgs);
} catch (InvocationTargetException e) {
Log.w("Tumult", "Unable to invoke startForeground", e);
} catch (IllegalAccessException e) {
Log.w("Tumult", "Unable to invoke startForeground", e);
}
}
}
public void stopForegroundCompat(int id)
{
if (mStopForeground == null) {
mNotificationManager.cancel(id);
setForeground(false);
} else {
Object[] topForegroundArgs = { Boolean.TRUE };
try {
mStopForeground.invoke(this, topForegroundArgs);
} catch (InvocationTargetException e) {
Log.w("Tumult", "Unable to invoke stopForeground", e);
} catch (IllegalAccessException e) {
Log.w("Tumult", "Unable to invoke stopForeground", e);
}
}
}
package org.kreed.tumult;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class PlaybackService extends Service {
private MusicPlayer mPlayer;
private NotificationManager mNotificationManager;
private Method mStartForeground;
private Method mStopForeground;
@Override
public IBinder onBind(Intent intent)
{
if (mPlayer == null)
return null;
return mPlayer.mBinder;
}
@Override
public void onCreate()
{
mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
try {
mStartForeground = getClass().getMethod("startForeground", new Class[] { int.class, Notification.class });
mStopForeground = getClass().getMethod("stopForeground", new Class[] { boolean.class });
} catch (NoSuchMethodException e) {
// Running on an older platform.
mStartForeground = mStopForeground = null;
}
mPlayer = new MusicPlayer(this);
}
@Override
public void onStart(Intent intent, int flags)
{
int id;
if ((id = intent.getIntExtra("songId", -1)) != -1)
mPlayer.queueSong(id);
else
mPlayer.stopQueueing();
}
@Override
public void onDestroy()
{
super.onDestroy();
if (mPlayer != null) {
mPlayer.release();
mPlayer = null;
}
}
public void startForegroundCompat(int id, Notification notification)
{
if (mStartForeground == null) {
setForeground(true);
mNotificationManager.notify(id, notification);
} else {
Object[] startForegroundArgs = { Integer.valueOf(id), notification };
try {
mStartForeground.invoke(this, startForegroundArgs);
} catch (InvocationTargetException e) {
Log.w("Tumult", "Unable to invoke startForeground", e);
} catch (IllegalAccessException e) {
Log.w("Tumult", "Unable to invoke startForeground", e);
}
}
}
public void stopForegroundCompat(int id)
{
if (mStopForeground == null) {
mNotificationManager.cancel(id);
setForeground(false);
} else {
Object[] topForegroundArgs = { Boolean.TRUE };
try {
mStopForeground.invoke(this, topForegroundArgs);
} catch (InvocationTargetException e) {
Log.w("Tumult", "Unable to invoke stopForeground", e);
} catch (IllegalAccessException e) {
Log.w("Tumult", "Unable to invoke stopForeground", e);
}
}
}
}

@ -1,13 +1,13 @@
package org.kreed.tumult;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class PreferencesActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
package org.kreed.tumult;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class PreferencesActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}

@ -1,3 +1,3 @@
package org.kreed.tumult;
package org.kreed.tumult;
parcelable Song;

@ -1,113 +1,113 @@
package org.kreed.tumult;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;
public class Song implements Parcelable {
public String path;
public String coverPath;
public String title;
public String album;
public String artist;
public Song(int id)
{
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = {
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM_ID
};
String selection = MediaStore.Audio.Media._ID + "==" + id;;
ContentResolver resolver = Tumult.getContext().getContentResolver();
Cursor cursor = resolver.query(media, projection, selection, null, null);
if (cursor != null && cursor.moveToNext()) {
path = cursor.getString(0);
title = cursor.getString(1);
album = cursor.getString(2);
artist = cursor.getString(3);
String albumId = cursor.getString(4);
cursor.close();
media = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
String[] albumProjection = { MediaStore.Audio.Albums.ALBUM_ART };
String albumSelection = MediaStore.Audio.Albums._ID + "==" + albumId;
cursor = resolver.query(media, albumProjection, albumSelection, null, null);
if (cursor != null && cursor.moveToNext()) {
coverPath = cursor.getString(0);
cursor.close();
}
}
}
public static int[] getAllSongs()
{
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Audio.Media._ID };
String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
ContentResolver resolver = Tumult.getContext().getContentResolver();
Cursor cursor = resolver.query(media, projection, selection, null, null);
if (cursor == null)
return null;
int count = cursor.getCount();
if (count == 0)
return null;
int[] songs = new int[count];
while (--count != -1 && cursor.moveToNext())
songs[count] = cursor.getInt(0);
cursor.close();
cursor = null;
return songs;
}
public static Parcelable.Creator<Song> CREATOR = new Parcelable.Creator<Song>() {
public Song createFromParcel(Parcel in)
{
return new Song(in);
}
public Song[] newArray(int size)
{
return new Song[size];
}
};
public Song(Parcel in)
{
path = in.readString();
coverPath = in.readString();
title = in.readString();
album = in.readString();
artist = in.readString();
}
public void writeToParcel(Parcel out, int flags)
{
out.writeString(path);
out.writeString(coverPath);
out.writeString(title);
out.writeString(album);
out.writeString(artist);
}
public int describeContents()
{
return 0;
}
}
package org.kreed.tumult;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;
public class Song implements Parcelable {
public String path;
public String coverPath;
public String title;
public String album;
public String artist;
public Song(int id)
{
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = {
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM_ID
};
String selection = MediaStore.Audio.Media._ID + "==" + id;;
ContentResolver resolver = Tumult.getContext().getContentResolver();
Cursor cursor = resolver.query(media, projection, selection, null, null);
if (cursor != null && cursor.moveToNext()) {
path = cursor.getString(0);
title = cursor.getString(1);
album = cursor.getString(2);
artist = cursor.getString(3);
String albumId = cursor.getString(4);
cursor.close();
media = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
String[] albumProjection = { MediaStore.Audio.Albums.ALBUM_ART };
String albumSelection = MediaStore.Audio.Albums._ID + "==" + albumId;
cursor = resolver.query(media, albumProjection, albumSelection, null, null);
if (cursor != null && cursor.moveToNext()) {
coverPath = cursor.getString(0);
cursor.close();
}
}
}
public static int[] getAllSongs()
{
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Audio.Media._ID };
String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
ContentResolver resolver = Tumult.getContext().getContentResolver();
Cursor cursor = resolver.query(media, projection, selection, null, null);
if (cursor == null)
return null;
int count = cursor.getCount();
if (count == 0)
return null;
int[] songs = new int[count];
while (--count != -1 && cursor.moveToNext())
songs[count] = cursor.getInt(0);
cursor.close();
cursor = null;
return songs;
}
public static Parcelable.Creator<Song> CREATOR = new Parcelable.Creator<Song>() {
public Song createFromParcel(Parcel in)
{
return new Song(in);
}
public Song[] newArray(int size)
{
return new Song[size];
}
};
public Song(Parcel in)
{
path = in.readString();
coverPath = in.readString();
title = in.readString();
album = in.readString();
artist = in.readString();
}
public void writeToParcel(Parcel out, int flags)
{
out.writeString(path);
out.writeString(coverPath);
out.writeString(title);
out.writeString(album);
out.writeString(artist);
}
public int describeContents()
{
return 0;
}
}

@ -1,109 +1,109 @@
package org.kreed.tumult;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class SongSelector extends Activity implements View.OnClickListener, OnItemClickListener {
private ListView mListView;
private SongAdapter mAdapter;
private LinearLayout mFilterLayout;
private TextView mFilterText;
private Button mBackspaceButton;
private Button mCloseButton;
private View mNumpad;
private Button[] mButtons;
@Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.songselector);
mListView = (ListView)findViewById(R.id.song_list);
mAdapter = new SongAdapter(this);
mListView.setAdapter(mAdapter);
mListView.setTextFilterEnabled(true);
mListView.setOnItemClickListener(this);
mFilterLayout = (LinearLayout)findViewById(R.id.filter_layout);
mFilterText = (TextView)findViewById(R.id.filter_text);
mBackspaceButton = (Button)findViewById(R.id.backspace);
mBackspaceButton.setOnClickListener(this);
mCloseButton = (Button)findViewById(R.id.close);
mCloseButton.setOnClickListener(this);
mNumpad = findViewById(R.id.numpad);
Configuration config = getResources().getConfiguration();
boolean hasKeyboard = config.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO && config.keyboard == Configuration.KEYBOARD_QWERTY;
mNumpad.setVisibility(hasKeyboard ? View.GONE : View.VISIBLE);
mButtons = new Button[] {
(Button)findViewById(R.id.Button1),
(Button)findViewById(R.id.Button2),
(Button)findViewById(R.id.Button3),
(Button)findViewById(R.id.Button4),
(Button)findViewById(R.id.Button5),
(Button)findViewById(R.id.Button6),
(Button)findViewById(R.id.Button7),
(Button)findViewById(R.id.Button8),
(Button)findViewById(R.id.Button9)
};
for (Button button : mButtons)
button.setOnClickListener(this);
}
@Override
public boolean onSearchRequested()
{
mNumpad.setVisibility(mNumpad.getVisibility() == View.GONE ? View.VISIBLE : View.GONE);
return false;
}
public void onClick(View view)
{
int visible = View.VISIBLE;
String text = mFilterText.getText().toString();
if (text.length() == 0)
text = "Filter: ";
if (view == mCloseButton) {
visible = View.GONE;
text = null;
} else if (view == mBackspaceButton) {
if (text.length() > 8)
text = text.substring(0, text.length() - 1);
} else {
int i = -1;
while (++i != mButtons.length)
if (mButtons[i] == view)
break;
text += i + 1;
}
mFilterText.setText(text);
mFilterLayout.setVisibility(visible);
mListView.setTextFilterEnabled(visible == View.VISIBLE);
String filterText = text == null || text.length() <= 8 ? null : text.substring(8);
mAdapter.getFilter().filter(filterText);
}
public void onItemClick(AdapterView<?> list, View view, int pos, long id)
{
Intent intent = new Intent(this, PlaybackService.class);
intent.putExtra("songId", (int)id);
startService(intent);
}
package org.kreed.tumult;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class SongSelector extends Activity implements View.OnClickListener, OnItemClickListener {
private ListView mListView;
private SongAdapter mAdapter;
private LinearLayout mFilterLayout;
private TextView mFilterText;
private Button mBackspaceButton;
private Button mCloseButton;
private View mNumpad;
private Button[] mButtons;
@Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.songselector);
mListView = (ListView)findViewById(R.id.song_list);
mAdapter = new SongAdapter(this);
mListView.setAdapter(mAdapter);
mListView.setTextFilterEnabled(true);
mListView.setOnItemClickListener(this);
mFilterLayout = (LinearLayout)findViewById(R.id.filter_layout);
mFilterText = (TextView)findViewById(R.id.filter_text);
mBackspaceButton = (Button)findViewById(R.id.backspace);
mBackspaceButton.setOnClickListener(this);
mCloseButton = (Button)findViewById(R.id.close);
mCloseButton.setOnClickListener(this);
mNumpad = findViewById(R.id.numpad);
Configuration config = getResources().getConfiguration();
boolean hasKeyboard = config.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO && config.keyboard == Configuration.KEYBOARD_QWERTY;
mNumpad.setVisibility(hasKeyboard ? View.GONE : View.VISIBLE);
mButtons = new Button[] {
(Button)findViewById(R.id.Button1),
(Button)findViewById(R.id.Button2),
(Button)findViewById(R.id.Button3),
(Button)findViewById(R.id.Button4),
(Button)findViewById(R.id.Button5),
(Button)findViewById(R.id.Button6),
(Button)findViewById(R.id.Button7),
(Button)findViewById(R.id.Button8),
(Button)findViewById(R.id.Button9)
};
for (Button button : mButtons)
button.setOnClickListener(this);
}
@Override
public boolean onSearchRequested()
{
mNumpad.setVisibility(mNumpad.getVisibility() == View.GONE ? View.VISIBLE : View.GONE);
return false;
}
public void onClick(View view)
{
int visible = View.VISIBLE;
String text = mFilterText.getText().toString();
if (text.length() == 0)
text = "Filter: ";
if (view == mCloseButton) {
visible = View.GONE;
text = null;
} else if (view == mBackspaceButton) {
if (text.length() > 8)
text = text.substring(0, text.length() - 1);
} else {
int i = -1;
while (++i != mButtons.length)
if (mButtons[i] == view)
break;
text += i + 1;
}
mFilterText.setText(text);
mFilterLayout.setVisibility(visible);
mListView.setTextFilterEnabled(visible == View.VISIBLE);
String filterText = text == null || text.length() <= 8 ? null : text.substring(8);
mAdapter.getFilter().filter(filterText);
}
public void onItemClick(AdapterView<?> list, View view, int pos, long id)
{
Intent intent = new Intent(this, PlaybackService.class);
intent.putExtra("songId", (int)id);
startService(intent);
}
}

@ -1,18 +1,18 @@
package org.kreed.tumult;
import android.app.Application;
import android.content.Context;
public class Tumult extends Application {
private static Tumult instance;
public Tumult()
{
instance = this;
}
public static Context getContext()
{
return instance;
}
}
package org.kreed.tumult;
import android.app.Application;
import android.content.Context;
public class Tumult extends Application {
private static Tumult instance;
public Tumult()
{
instance = this;
}
public static Context getContext()
{
return instance;
}
}