2 package com.cyngn.eleven.loaders;
4 import static com.cyngn.eleven.utils.MusicUtils.mService;
6 import android.annotation.SuppressLint;
7 import android.content.Context;
8 import android.database.AbstractCursor;
9 import android.database.Cursor;
10 import android.os.RemoteException;
11 import android.provider.BaseColumns;
12 import android.provider.MediaStore;
13 import android.provider.MediaStore.Audio.AudioColumns;
15 import com.cyngn.eleven.utils.ApolloUtils;
16 import com.cyngn.eleven.utils.MusicUtils;
18 import java.util.Arrays;
21 * A custom {@link Cursor} used to return the queue and allow for easy dragging
22 * and dropping of the items in it.
24 @SuppressLint("NewApi")
25 public class NowPlayingCursor extends AbstractCursor {
27 private static final String[] PROJECTION = new String[] {
35 AudioColumns.ALBUM_ID,
39 AudioColumns.DURATION,
44 private final Context mContext;
46 private long[] mNowPlaying;
48 private long[] mCursorIndexes;
54 private Cursor mQueueCursor;
57 * Constructor of <code>NowPlayingCursor</code>
59 * @param context The {@link Context} to use
61 public NowPlayingCursor(final Context context) {
63 makeNowPlayingCursor();
70 public int getCount() {
78 public boolean onMove(final int oldPosition, final int newPosition) {
79 if (oldPosition == newPosition) {
83 if (mNowPlaying == null || mCursorIndexes == null || newPosition >= mNowPlaying.length) {
87 final long id = mNowPlaying[newPosition];
88 final int cursorIndex = Arrays.binarySearch(mCursorIndexes, id);
89 mQueueCursor.moveToPosition(cursorIndex);
90 mCurPos = newPosition;
98 public String getString(final int column) {
100 return mQueueCursor.getString(column);
101 } catch (final Exception ignored) {
111 public short getShort(final int column) {
112 return mQueueCursor.getShort(column);
119 public int getInt(final int column) {
121 return mQueueCursor.getInt(column);
122 } catch (final Exception ignored) {
132 public long getLong(final int column) {
134 return mQueueCursor.getLong(column);
135 } catch (final Exception ignored) {
145 public float getFloat(final int column) {
146 return mQueueCursor.getFloat(column);
153 public double getDouble(final int column) {
154 return mQueueCursor.getDouble(column);
161 public int getType(final int column) {
162 return mQueueCursor.getType(column);
169 public boolean isNull(final int column) {
170 return mQueueCursor.isNull(column);
177 public String[] getColumnNames() {
184 @SuppressWarnings("deprecation")
186 public void deactivate() {
187 if (mQueueCursor != null) {
188 mQueueCursor.deactivate();
196 public boolean requery() {
197 makeNowPlayingCursor();
205 public void close() {
207 if (mQueueCursor != null) {
208 mQueueCursor.close();
211 } catch (final Exception close) {
217 * Actually makes the queue
219 private void makeNowPlayingCursor() {
221 mNowPlaying = MusicUtils.getQueue();
222 mSize = mNowPlaying.length;
227 final StringBuilder selection = new StringBuilder();
228 selection.append(MediaStore.Audio.Media._ID + " IN (");
229 for (int i = 0; i < mSize; i++) {
230 selection.append(mNowPlaying[i]);
232 selection.append(",");
235 selection.append(")");
237 mQueueCursor = mContext.getContentResolver().query(
238 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, PROJECTION, selection.toString(),
239 null, MediaStore.Audio.Media._ID);
241 if (mQueueCursor == null) {
246 final int playlistSize = mQueueCursor.getCount();
247 mCursorIndexes = new long[playlistSize];
248 mQueueCursor.moveToFirst();
249 final int columnIndex = mQueueCursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID);
250 for (int i = 0; i < playlistSize; i++) {
251 mCursorIndexes[i] = mQueueCursor.getLong(columnIndex);
252 mQueueCursor.moveToNext();
254 mQueueCursor.moveToFirst();
258 for (int i = mNowPlaying.length - 1; i >= 0; i--) {
259 final long trackId = mNowPlaying[i];
260 final int cursorIndex = Arrays.binarySearch(mCursorIndexes, trackId);
261 if (cursorIndex < 0) {
262 removed += MusicUtils.removeTrack(trackId);
266 mNowPlaying = MusicUtils.getQueue();
267 mSize = mNowPlaying.length;
269 mCursorIndexes = null;
276 * @param which The position to remove
277 * @return True if sucessfull, false othersise
279 public boolean removeItem(final int which) {
281 if (mService.removeTracks(which, which) == 0) {
287 mNowPlaying[i] = mNowPlaying[i + 1];
291 } catch (final RemoteException ignored) {