From 3220ee32be9d9aa0afefb31dd0b7ff1e26ded84e Mon Sep 17 00:00:00 2001 From: Christopher Eby Date: Fri, 19 Feb 2010 19:37:33 -0600 Subject: [PATCH] Remove windows line-endings --- .classpath | 14 +- .project | 66 +- .settings/org.eclipse.jdt.core.prefs | 10 +- src/org/kreed/tumult/CoverView.java | 614 ++++++------- src/org/kreed/tumult/IMusicPlayerWatcher.aidl | 18 +- src/org/kreed/tumult/IPlaybackService.aidl | 34 +- src/org/kreed/tumult/MusicPlayer.java | 860 +++++++++--------- src/org/kreed/tumult/PlaybackService.java | 190 ++-- src/org/kreed/tumult/PreferencesActivity.java | 24 +- src/org/kreed/tumult/Song.aidl | 4 +- src/org/kreed/tumult/Song.java | 226 ++--- src/org/kreed/tumult/SongSelector.java | 216 ++--- src/org/kreed/tumult/Tumult.java | 36 +- 13 files changed, 1156 insertions(+), 1156 deletions(-) diff --git a/.classpath b/.classpath index 6e9239ff..609aa00e 100644 --- a/.classpath +++ b/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/.project b/.project index 967ed449..45c24627 100644 --- a/.project +++ b/.project @@ -1,33 +1,33 @@ - - - Tumult - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - + + + Tumult + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 4149f6d5..50f96085 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/src/org/kreed/tumult/CoverView.java b/src/org/kreed/tumult/CoverView.java index 5276db3f..e9fd8a25 100755 --- a/src/org/kreed/tumult/CoverView.java +++ b/src/org/kreed/tumult/CoverView.java @@ -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; + } + } +} diff --git a/src/org/kreed/tumult/IMusicPlayerWatcher.aidl b/src/org/kreed/tumult/IMusicPlayerWatcher.aidl index 0a060931..6cefdcfc 100644 --- a/src/org/kreed/tumult/IMusicPlayerWatcher.aidl +++ b/src/org/kreed/tumult/IMusicPlayerWatcher.aidl @@ -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); } \ No newline at end of file diff --git a/src/org/kreed/tumult/IPlaybackService.aidl b/src/org/kreed/tumult/IPlaybackService.aidl index 89fcee56..a29f1687 100644 --- a/src/org/kreed/tumult/IPlaybackService.aidl +++ b/src/org/kreed/tumult/IPlaybackService.aidl @@ -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); } \ No newline at end of file diff --git a/src/org/kreed/tumult/MusicPlayer.java b/src/org/kreed/tumult/MusicPlayer.java index 8198209f..685f0440 100644 --- a/src/org/kreed/tumult/MusicPlayer.java +++ b/src/org/kreed/tumult/MusicPlayer.java @@ -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 mWatchers; - - private boolean mHeadsetOnly = true; - - private Handler mHandler; - private MediaPlayer mMediaPlayer; - private Random mRandom; - private PowerManager.WakeLock mWakeLock; - - private int[] mSongs; - private ArrayList 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(); - mSongTimeline = new ArrayList(); - - 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 mWatchers; + + private boolean mHeadsetOnly = true; + + private Handler mHandler; + private MediaPlayer mMediaPlayer; + private Random mRandom; + private PowerManager.WakeLock mWakeLock; + + private int[] mSongs; + private ArrayList 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(); + mSongTimeline = new ArrayList(); + + 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)); + } + } +} diff --git a/src/org/kreed/tumult/PlaybackService.java b/src/org/kreed/tumult/PlaybackService.java index 13ed71f1..ba615e26 100644 --- a/src/org/kreed/tumult/PlaybackService.java +++ b/src/org/kreed/tumult/PlaybackService.java @@ -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); + } + } + } } \ No newline at end of file diff --git a/src/org/kreed/tumult/PreferencesActivity.java b/src/org/kreed/tumult/PreferencesActivity.java index e3712eda..b4347338 100644 --- a/src/org/kreed/tumult/PreferencesActivity.java +++ b/src/org/kreed/tumult/PreferencesActivity.java @@ -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); + } } \ No newline at end of file diff --git a/src/org/kreed/tumult/Song.aidl b/src/org/kreed/tumult/Song.aidl index 5be7db2f..c1465efa 100644 --- a/src/org/kreed/tumult/Song.aidl +++ b/src/org/kreed/tumult/Song.aidl @@ -1,3 +1,3 @@ -package org.kreed.tumult; - +package org.kreed.tumult; + parcelable Song; \ No newline at end of file diff --git a/src/org/kreed/tumult/Song.java b/src/org/kreed/tumult/Song.java index 33f9d5a4..8e451417 100644 --- a/src/org/kreed/tumult/Song.java +++ b/src/org/kreed/tumult/Song.java @@ -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 CREATOR = new Parcelable.Creator() { - 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 CREATOR = new Parcelable.Creator() { + 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; + } +} diff --git a/src/org/kreed/tumult/SongSelector.java b/src/org/kreed/tumult/SongSelector.java index 48dd7765..dfe513e1 100644 --- a/src/org/kreed/tumult/SongSelector.java +++ b/src/org/kreed/tumult/SongSelector.java @@ -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); + } } \ No newline at end of file diff --git a/src/org/kreed/tumult/Tumult.java b/src/org/kreed/tumult/Tumult.java index eb602025..5702f604 100644 --- a/src/org/kreed/tumult/Tumult.java +++ b/src/org/kreed/tumult/Tumult.java @@ -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; + } +}