/app/src/main/java/com/music/player/haige/mvp/ui/music/service/MusicDataManager.java
Java | 1186 lines | 1036 code | 137 blank | 13 comment | 319 complexity | c6499bc0874d9bbc887481bd4235c7af MD5 | raw file
- package com.music.player.haige.mvp.ui.music.service;
- import android.Manifest;
- import android.content.ContentResolver;
- import android.content.Context;
- import android.content.SharedPreferences;
- import android.database.Cursor;
- import android.database.MatrixCursor;
- import android.net.Uri;
- import android.os.SystemClock;
- import android.provider.MediaStore;
- import android.support.v4.content.PermissionChecker;
- import android.text.TextUtils;
- import com.google.gson.Gson;
- import com.google.gson.reflect.TypeToken;
- import com.music.player.haige.mvp.model.entity.music.MusicPlaybackTrack;
- import com.music.player.haige.mvp.model.entity.music.Song;
- import com.music.player.haige.mvp.model.respository.provider.MusicPlaybackState;
- import com.music.player.haige.mvp.model.utils.CommonUtils;
- import com.music.player.haige.mvp.model.utils.HaigeUtil;
- import com.music.player.haige.mvp.ui.utils.Utils;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.RandomAccessFile;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.LinkedList;
- import java.util.ListIterator;
- import java.util.Random;
- import java.util.TreeSet;
- import timber.log.Timber;
- /**
- * ================================================
- * Created by huangcong on 2018/4/3.
- * <p>
- * 音乐数据管理
- * ================================================
- */
- public class MusicDataManager {
- private static final String TAG = MusicDataManager.class.getName();
- private static final String[] PROJECTION = new String[]{
- "audio._id AS _id", MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM,
- MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA,
- MediaStore.Audio.Media.MIME_TYPE, MediaStore.Audio.Media.ALBUM_ID,
- MediaStore.Audio.Media.ARTIST_ID
- };
- private static final String[] PROJECTION_MATRIX = new String[]{
- "_id", MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM,
- MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA,
- MediaStore.Audio.Media.MIME_TYPE, MediaStore.Audio.Media.ALBUM_ID,
- MediaStore.Audio.Media.ARTIST_ID
- };
- private static final int ID_COLIDX = 0;
- public static final int MAX_HISTORY_SIZE = 1000;
- public static final int SHUFFLE_NONE = 0;
- public static final int SHUFFLE_NORMAL = 1;
- public static final int SHUFFLE_AUTO = 2;
- public static final int REPEAT_NONE = 2;
- public static final int REPEAT_CURRENT = 1;
- public static final int REPEAT_ALL = 2;
- private MusicService musicService;
- private Gson mGson;
- private HashMap<Long, Song> mPlaylistInfo = new HashMap<>();
- private ArrayList<MusicPlaybackTrack> mPlaylist = new ArrayList<>(100);
- private static LinkedList<Integer> mHistory = new LinkedList<>();
- private Cursor mCursor;
- private int mPlayPos = -1;
- private int mNextPlayPos = -1;
- private static final Shuffler mShuffler = new Shuffler();
- private int mShuffleMode = SHUFFLE_NONE;
- private int mRepeatMode = REPEAT_ALL;
- private long[] mAutoShuffleList = null;
- private int mCardId;
- private SharedPreferences mPreferences;
- private boolean mQueueIsSaveable = true;
- private MusicPlaybackState mPlaybackStateStore;
- public long mLastSeekPos = 0;
- public MusicDataManager(MusicService musicService, Gson gson) {
- this.musicService = musicService;
- this.mGson = gson;
- this.mPreferences = musicService.getSharedPreferences("Haige_Music_Service", Context.MODE_PRIVATE);
- this.mPlaybackStateStore = MusicPlaybackState.getInstance(musicService);
- }
- public HashMap<Long, Song> getPlaylistInfo() {
- return mPlaylistInfo;
- }
- public void putPlayinfos(final HashMap<Long, Song> songHashMap) {
- mPlaylistInfo = songHashMap;
- }
- public ArrayList<MusicPlaybackTrack> getPlaylist() {
- return mPlaylist;
- }
- public int getPlayPos() {
- return mPlayPos;
- }
- public void setPlayPos(int pos) {
- this.mPlayPos = pos;
- }
- public LinkedList<Integer> getHistory() {
- return mHistory;
- }
- public int getQueueHistoryPosition(int position) {
- if (position >= 0 && position < mHistory.size()) {
- return mHistory.get(position);
- }
- return -1;
- }
- public int[] getQueueHistoryList() {
- int[] history = new int[mHistory.size()];
- for (int i = 0; i < mHistory.size(); i++) {
- history[i] = mHistory.get(i);
- }
- return history;
- }
- public Cursor getCursor() {
- return mCursor;
- }
- public String getContentUriPath() {
- return MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "/" + mCursor.getLong(ID_COLIDX);
- }
- public void updateCardId() {
- mCardId = getCardId();
- }
- public int getShuffleMode() {
- return mShuffleMode;
- }
- public int getRepeatMode() {
- return mRepeatMode;
- }
- public void setQueueIsSaveable(boolean mQueueIsSaveable) {
- this.mQueueIsSaveable = mQueueIsSaveable;
- }
- public void setRepeatMode(final int repeatmode) {
- mRepeatMode = repeatmode;
- setNextTrack();
- saveQueue(false);
- musicService.notifyChange(musicService.REPEATMODE_CHANGED);
- }
- public String getPath() {
- if (mCursor == null) {
- return null;
- }
- return mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.DATA));
- }
- public String getAlbumName() {
- if (mCursor == null) {
- return null;
- }
- return mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ALBUM));
- }
- public String getAlbumPath() {
- if (mCursor == null) {
- return null;
- }
- return mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.MIME_TYPE));
- }
- public String[] getAlbumPathAll() {
- try {
- int len = mPlaylistInfo.size();
- String[] albums = new String[len];
- long[] queue = getQueue();
- for (int i = 0; i < len; i++) {
- albums[i] = mPlaylistInfo.get(queue[i]).albumData;
- }
- return albums;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return new String[]{};
- }
- public String getTrackName() {
- if (mCursor == null) {
- return null;
- }
- return mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.TITLE));
- }
- public boolean isTrackLocal() {
- Song info = mPlaylistInfo.get(getAudioId());
- if (info == null) {
- return true;
- }
- return info.isLocal;
- }
- public String getMusicName() {
- Song info = mPlaylistInfo.get(getAudioId());
- if (info == null) {
- return null;
- }
- return info.musicName;
- }
- public String getMusicCover() {
- Song info = mPlaylistInfo.get(getAudioId());
- if (info == null) {
- return null;
- }
- return info.musicCover;
- }
- public String getMusicUrl() {
- Song info = mPlaylistInfo.get(getAudioId());
- if (info == null) {
- return null;
- }
- return info.musicPath;
- }
- public int getMusicLikeCount() {
- Song info = mPlaylistInfo.get(getAudioId());
- if (info == null) {
- return 0;
- }
- return info.likeCount;
- }
- public int getMusicShareCount() {
- Song info = mPlaylistInfo.get(getAudioId());
- if (info == null) {
- return 0;
- }
- return info.shareCount;
- }
- public int getMusicDownloadCount() {
- Song info = mPlaylistInfo.get(getAudioId());
- if (info == null) {
- return 0;
- }
- return info.downloadCount;
- }
- public boolean isFavorite() {
- Song info = mPlaylistInfo.get(getAudioId());
- if (info == null) {
- return true;
- }
- return info.isFavorite();
- }
- public String getAlbumPath(long id) {
- try {
- String str = mPlaylistInfo.get(id).albumData;
- return str;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- public String getGenreName() {
- if (mCursor == null || mPlayPos < 0 || mPlayPos >= mPlaylist.size()) {
- return null;
- }
- try {
- String[] genreProjection = {MediaStore.Audio.Genres.NAME};
- Uri genreUri = MediaStore.Audio.Genres.getContentUriForAudioId("external",
- (int) mPlaylist.get(mPlayPos).mId);
- Cursor genreCursor = musicService.getContentResolver().query(genreUri, genreProjection,
- null, null, null);
- if (genreCursor != null) {
- try {
- if (genreCursor.moveToFirst()) {
- return genreCursor.getString(
- genreCursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME));
- }
- } finally {
- genreCursor.close();
- }
- }
- } catch (Exception e) {
- }
- return null;
- }
- public String getArtistName() {
- if (mCursor == null) {
- return null;
- }
- return mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ARTIST));
- }
- public long getAlbumId() {
- if (mCursor == null) {
- return -1;
- }
- return mCursor.getLong(mCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ALBUM_ID));
- }
- public long getArtistId() {
- if (mCursor == null) {
- return -1;
- }
- return mCursor.getLong(mCursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ARTIST_ID));
- }
- public long getAudioId() {
- MusicPlaybackTrack track = getCurrentTrack();
- if (track != null) {
- return track.mId;
- }
- return -1;
- }
- public long getLastSeekPos() {
- return mLastSeekPos;
- }
- public MusicPlaybackTrack getCurrentTrack() {
- return getTrack(mPlayPos);
- }
- public synchronized MusicPlaybackTrack getTrack(int index) {
- if (index >= 0 && index < mPlaylist.size()) {
- return mPlaylist.get(index);
- }
- return null;
- }
- public long getNextAudioId() {
- if (mNextPlayPos >= 0 && mNextPlayPos < mPlaylist.size() && musicService.mPlayer.isInitialized()) {
- return mPlaylist.get(mNextPlayPos).mId;
- }
- return -1;
- }
- public long getPreviousAudioId() {
- if (musicService.mPlayer.isInitialized()) {
- int pos = getPreviousPlayPosition(false);
- if (pos >= 0 && pos < mPlaylist.size()) {
- return mPlaylist.get(pos).mId;
- }
- }
- return -1;
- }
- public long[] getQueue() {
- final int len = mPlaylist.size();
- final long[] list = new long[len];
- for (int i = 0; i < len; i++) {
- list[i] = mPlaylist.get(i).mId;
- }
- return list;
- }
- public long getQueueItemAtPosition(int position) {
- if (position >= 0 && position < mPlaylist.size()) {
- return mPlaylist.get(position).mId;
- }
- return -1;
- }
- public int removeTrack(final long id) {
- int numRemoved = 0;
- synchronized (this) {
- for (int i = 0; i < mPlaylist.size(); i++) {
- if (mPlaylist.get(i).mId == id) {
- numRemoved += removeTracksInternal(i, i);
- i--;
- }
- }
- mPlaylistInfo.remove(id);
- }
- if (numRemoved > 0) {
- musicService.notifyChange(musicService.QUEUE_CHANGED);
- }
- return numRemoved;
- }
- public void open(final HashMap<Long, Song> songHashMap, final long[] list, final int position) {
- mPlaylistInfo = songHashMap;
- Timber.d(mPlaylistInfo.toString());
- if (mShuffleMode == SHUFFLE_AUTO) {
- mShuffleMode = SHUFFLE_NORMAL;
- }
- final long oldId = getAudioId();
- final int listLength = list.length;
- boolean newList = true;
- Timber.e(TAG + " the old playlist : " + mPlaylist);
- if (mPlaylist.size() == listLength) {
- newList = false;
- for (int i = 0; i < listLength; i++) {
- if (list[i] != mPlaylist.get(i).mId) {
- newList = true;
- break;
- }
- }
- }
- if (newList) {
- addToPlayList(list, -1);
- musicService.notifyChange(musicService.QUEUE_CHANGED);
- }
- if (position >= 0) {
- mPlayPos = position;
- } else {
- mPlayPos = mShuffler.nextInt(mPlaylist.size());
- }
- mHistory.clear();
- musicService.openCurrentAndNextPlay(true);
- if (oldId != getAudioId()) {
- musicService.notifyChange(musicService.META_CHANGED);
- }
- }
- public void setAndRecordPlayPos(int nextPos) {
- if (mShuffleMode != SHUFFLE_NONE) {
- mHistory.add(mPlayPos);
- if (mHistory.size() > MAX_HISTORY_SIZE) {
- mHistory.remove(0);
- }
- }
- mPlayPos = nextPos;
- }
- public void moveQueueItem(int index1, int index2) {
- if (index1 >= mPlaylist.size()) {
- index1 = mPlaylist.size() - 1;
- }
- if (index2 >= mPlaylist.size()) {
- index2 = mPlaylist.size() - 1;
- }
- if (index1 == index2) {
- return;
- }
- mPlaylistInfo.remove(mPlaylist.get(index1).mId);
- final MusicPlaybackTrack track = mPlaylist.remove(index1);
- if (index1 < index2) {
- mPlaylist.add(index2, track);
- if (mPlayPos == index1) {
- mPlayPos = index2;
- } else if (mPlayPos >= index1 && mPlayPos <= index2) {
- mPlayPos--;
- }
- } else if (index2 < index1) {
- mPlaylist.add(index2, track);
- if (mPlayPos == index1) {
- mPlayPos = index2;
- } else if (mPlayPos >= index2 && mPlayPos <= index1) {
- mPlayPos++;
- }
- }
- }
- public void cycleRepeat() {
- if (mRepeatMode == REPEAT_NONE) {
- setRepeatMode(REPEAT_CURRENT);
- if (mShuffleMode != SHUFFLE_NONE) {
- setShuffleMode(SHUFFLE_NONE);
- }
- } else {
- setRepeatMode(REPEAT_NONE);
- }
- }
- public void cycleShuffle() {
- if (mShuffleMode == SHUFFLE_NONE) {
- setShuffleMode(SHUFFLE_NORMAL);
- if (mRepeatMode == REPEAT_CURRENT) {
- setRepeatMode(REPEAT_ALL);
- }
- } else if (mShuffleMode == SHUFFLE_NORMAL || mShuffleMode == SHUFFLE_AUTO) {
- setShuffleMode(SHUFFLE_NONE);
- }
- }
- public String openFile(String path) {
- if (mCursor == null) {
- Uri uri = Uri.parse(path);
- boolean shouldAddToPlaylist = true;
- long id = -1;
- try {
- id = Long.valueOf(uri.getLastPathSegment());
- } catch (NumberFormatException ex) {
- // Ignore
- }
- if (id != -1 && path.startsWith(
- MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.toString())) {
- updateCursor(uri);
- } else if (id != -1 && path.startsWith(
- MediaStore.Files.getContentUri("external").toString())) {
- updateCursor(id);
- } else if (path.startsWith("content://downloads/")) {
- String mpUri = getValueForDownloadedFile(musicService, uri, "mediaprovider_uri");
- Timber.d(TAG + "Downloaded file's MP uri : " + mpUri);
- if (!TextUtils.isEmpty(mpUri)) {
- return mpUri;
- } else {
- updateCursorForDownloadedFile(musicService, uri);
- shouldAddToPlaylist = false;
- }
- } else {
- String where = MediaStore.Audio.Media.DATA + "=?";
- String[] selectionArgs = new String[]{path};
- updateCursor(where, selectionArgs);
- }
- try {
- if (mCursor != null && shouldAddToPlaylist) {
- mPlaylist.clear();
- mPlaylist.add(new MusicPlaybackTrack(mCursor.getLong(ID_COLIDX), -1, HaigeUtil.IdType.NA, -1));
- musicService.notifyChange(musicService.QUEUE_CHANGED);
- mPlayPos = 0;
- mHistory.clear();
- }
- } catch (final UnsupportedOperationException ex) {
- // Ignore
- }
- }
- return null;
- }
- public boolean notifyMetaChanged(String mpUri) {
- if (musicService.openFile(mpUri)) {
- musicService.notifyChange(MusicService.META_CHANGED);
- return true;
- } else {
- return false;
- }
- }
- public void updateCursor(final long musicId) {
- Song info = mPlaylistInfo.get(musicId);
- if (info != null) {
- MatrixCursor cursor = new MatrixCursor(PROJECTION);
- cursor.addRow(new Object[]{info.songId, info.artistName, info.albumName, info.musicName
- , info.musicPath, info.albumData, info.albumId, info.artistId});
- cursor.moveToFirst();
- mCursor = cursor;
- cursor.close();
- }
- }
- private void updateCursor(final String selection, final String[] selectionArgs) {
- synchronized (this) {
- closeCursor();
- mCursor = openCursorAndGoToFirst(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
- PROJECTION, selection, selectionArgs);
- }
- }
- private void updateCursor(final Uri uri) {
- synchronized (this) {
- closeCursor();
- mCursor = openCursorAndGoToFirst(uri, PROJECTION, null, null);
- }
- }
- private void updateCursorForDownloadedFile(Context context, Uri uri) {
- synchronized (this) {
- closeCursor();
- MatrixCursor cursor = new MatrixCursor(PROJECTION_MATRIX);
- String title = getValueForDownloadedFile(context, uri, "title");
- cursor.addRow(new Object[]{
- null,
- null,
- null,
- title,
- null,
- null,
- null,
- null
- });
- mCursor = cursor;
- mCursor.moveToFirst();
- }
- }
- private String getValueForDownloadedFile(Context context, Uri uri, String column) {
- Cursor cursor = null;
- final String[] projection = {
- column
- };
- try {
- cursor = context.getContentResolver().query(uri, projection, null, null, null);
- if (cursor != null && cursor.moveToFirst()) {
- return cursor.getString(0);
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- return null;
- }
- public synchronized void closeCursor() {
- if (mCursor != null) {
- mCursor.close();
- mCursor = null;
- }
- }
- private Cursor openCursorAndGoToFirst(Uri uri, String[] projection,
- String selection, String[] selectionArgs) {
- Cursor c = musicService.getContentResolver().query(uri, projection,
- selection, selectionArgs, null);
- if (c == null) {
- return null;
- }
- if (!c.moveToFirst()) {
- c.close();
- return null;
- }
- return c;
- }
- public void addToPlayList(final long[] list, int position) {
- final int addLen = list.length;
- if (position < 0) {
- mPlaylist.clear();
- position = 0;
- }
- mPlaylist.ensureCapacity(mPlaylist.size() + addLen);
- if (position > mPlaylist.size()) {
- position = mPlaylist.size();
- }
- final ArrayList<MusicPlaybackTrack> arrayList = new ArrayList<MusicPlaybackTrack>(addLen);
- for (int i = 0; i < list.length; i++) {
- arrayList.add(new MusicPlaybackTrack(list[i], i, HaigeUtil.IdType.NA, -1));
- }
- mPlaylist.addAll(position, arrayList);
- if (mPlaylist.size() == 0) {
- closeCursor();
- musicService.notifyChange(musicService.META_CHANGED);
- }
- }
- public int removeTracksInternal(int first, int last) {
- if (last < first) {
- return 0;
- } else if (first < 0) {
- first = 0;
- } else if (last >= mPlaylist.size()) {
- last = mPlaylist.size() - 1;
- }
- boolean gotonext = false;
- if (first <= mPlayPos && mPlayPos <= last) {
- mPlayPos = first;
- gotonext = true;
- } else if (mPlayPos > last) {
- mPlayPos -= last - first + 1;
- }
- final int numToRemove = last - first + 1;
- if (first == 0 && last == mPlaylist.size() - 1) {
- mPlayPos = -1;
- mNextPlayPos = -1;
- mPlaylist.clear();
- mHistory.clear();
- } else {
- for (int i = 0; i < numToRemove; i++) {
- mPlaylistInfo.remove(mPlaylist.get(first).mId);
- mPlaylist.remove(first);
- }
- ListIterator<Integer> positionIterator = mHistory.listIterator();
- while (positionIterator.hasNext()) {
- int pos = positionIterator.next();
- if (pos >= first && pos <= last) {
- positionIterator.remove();
- } else if (pos > last) {
- positionIterator.set(pos - numToRemove);
- }
- }
- }
- if (gotonext) {
- if (mPlaylist.size() == 0) {
- musicService.stop(true);
- mPlayPos = -1;
- closeCursor();
- } else {
- if (mShuffleMode != SHUFFLE_NONE) {
- mPlayPos = getNextPosition(true);
- } else if (mPlayPos >= mPlaylist.size()) {
- mPlayPos = 0;
- }
- final boolean wasPlaying = musicService.isPlaying();
- musicService.stop(false);
- musicService.openCurrentAndNext();
- if (wasPlaying) {
- musicService.play();
- }
- }
- musicService.notifyChange(musicService.META_CHANGED);
- }
- return last - first + 1;
- }
- public void setNextPosition(int nextPosition) {
- this.mNextPlayPos = nextPosition;
- }
- public int getNextPosition() {
- return mNextPlayPos;
- }
- public int getNextPosition(final boolean force) {
- if (mPlaylist == null || mPlaylist.isEmpty()) {
- return -1;
- }
- if (!force && mRepeatMode == REPEAT_CURRENT) {
- if (mPlayPos < 0) {
- return 0;
- }
- return mPlayPos;
- } else if (mShuffleMode == SHUFFLE_NORMAL) {
- final int numTracks = mPlaylist.size();
- final int[] trackNumPlays = new int[numTracks];
- for (int i = 0; i < numTracks; i++) {
- trackNumPlays[i] = 0;
- }
- final int numHistory = mHistory.size();
- for (int i = 0; i < numHistory; i++) {
- final int idx = mHistory.get(i).intValue();
- if (idx >= 0 && idx < numTracks) {
- trackNumPlays[idx]++;
- }
- }
- if (mPlayPos >= 0 && mPlayPos < numTracks) {
- trackNumPlays[mPlayPos]++;
- }
- int minNumPlays = Integer.MAX_VALUE;
- int numTracksWithMinNumPlays = 0;
- for (int i = 0; i < trackNumPlays.length; i++) {
- if (trackNumPlays[i] < minNumPlays) {
- minNumPlays = trackNumPlays[i];
- numTracksWithMinNumPlays = 1;
- } else if (trackNumPlays[i] == minNumPlays) {
- numTracksWithMinNumPlays++;
- }
- }
- if (minNumPlays > 0 && numTracksWithMinNumPlays == numTracks
- && mRepeatMode != REPEAT_ALL && !force) {
- return -1;
- }
- int skip = mShuffler.nextInt(numTracksWithMinNumPlays);
- for (int i = 0; i < trackNumPlays.length; i++) {
- if (trackNumPlays[i] == minNumPlays) {
- if (skip == 0) {
- return i;
- } else {
- skip--;
- }
- }
- }
- Timber.d(TAG + " Getting the next position resulted did not get a result when it should have");
- return -1;
- } else if (mShuffleMode == SHUFFLE_AUTO) {
- doAutoShuffleUpdate();
- return mPlayPos + 1;
- } else {
- if (mPlayPos >= mPlaylist.size() - 1) {
- if (mRepeatMode == REPEAT_NONE && !force) {
- return -1;
- } else if (mRepeatMode == REPEAT_ALL || force) {
- return 0;
- }
- return -1;
- } else {
- return mPlayPos + 1;
- }
- }
- }
- public void doAutoShuffleUpdate() {
- boolean notify = false;
- if (mPlayPos > 10) {
- removeTracks(0, mPlayPos - 9);
- notify = true;
- }
- final int toAdd = 7 - (mPlaylist.size() - (mPlayPos < 0 ? -1 : mPlayPos));
- for (int i = 0; i < toAdd; i++) {
- int lookback = mHistory.size();
- int idx = -1;
- while (true) {
- idx = mShuffler.nextInt(mAutoShuffleList.length);
- if (!wasRecentlyUsed(idx, lookback)) {
- break;
- }
- lookback /= 2;
- }
- mHistory.add(idx);
- if (mHistory.size() > MAX_HISTORY_SIZE) {
- mHistory.remove(0);
- }
- mPlaylist.add(new MusicPlaybackTrack(mAutoShuffleList[idx], -1, HaigeUtil.IdType.NA, -1));
- notify = true;
- }
- if (notify) {
- musicService.notifyChange(musicService.QUEUE_CHANGED);
- }
- }
- public void reloadQueue() {
- int id = mCardId;
- if (mPreferences.contains("cardid")) {
- id = mPreferences.getInt("cardid", ~mCardId);
- }
- if (id == mCardId) {
- mPlaylist = mPlaybackStateStore.getQueue();
- try {
- FileInputStream in = new FileInputStream(new File(musicService.getCacheDir().getAbsolutePath() + "playlist"));
- String c = readTextFromSDcard(in);
- HashMap<Long, Song> play = mGson.fromJson(c, new TypeToken<HashMap<Long, Song>>() {
- }.getType());
- if (play != null && play.size() > 0) {
- mPlaylistInfo = play;
- Timber.d(TAG + " " + mPlaylistInfo.keySet().toString());
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- if ((mPlaylist.size() == mPlaylistInfo.size()) && mPlaylist.size() > 0) {
- final int pos = mPreferences.getInt("curpos", 0);
- if (pos < 0 || pos >= mPlaylist.size()) {
- mPlaylist.clear();
- return;
- }
- mPlayPos = pos;
- updateCursor(mPlaylist.get(mPlayPos).mId);
- if (mCursor == null) {
- SystemClock.sleep(3000);
- updateCursor(mPlaylist.get(mPlayPos).mId);
- }
- synchronized (this) {
- closeCursor();
- musicService.setOpenFailedCounter(20);
- musicService.openCurrentAndNext();
- }
- // if (!mPlayer.isInitialized() && isTrackLocal()) {
- // mPlaylist.clear();
- // return;
- // }
- final long seekpos = mPreferences.getLong("seekpos", 0);
- mLastSeekPos = seekpos;
- musicService.seek(seekpos >= 0 && seekpos < musicService.duration() ? seekpos : 0);
- Timber.d(TAG + " restored queue, currently at position "
- + musicService.position() + "/" + musicService.duration()
- + " (requested " + seekpos + ")");
- int repMode = mPreferences.getInt("repeatmode", REPEAT_ALL);
- if (repMode != REPEAT_ALL && repMode != REPEAT_CURRENT) {
- repMode = REPEAT_NONE;
- }
- mRepeatMode = repMode;
- int shuffleMode = mPreferences.getInt("shufflemode", SHUFFLE_NONE);
- if (shuffleMode != SHUFFLE_AUTO && shuffleMode != SHUFFLE_NORMAL) {
- shuffleMode = SHUFFLE_NONE;
- }
- if (shuffleMode != SHUFFLE_NONE) {
- mHistory = mPlaybackStateStore.getHistory(mPlaylist.size());
- }
- if (shuffleMode == SHUFFLE_AUTO) {
- if (!makeAutoShuffleList()) {
- shuffleMode = SHUFFLE_NONE;
- }
- }
- mShuffleMode = shuffleMode;
- } else {
- clearPlayInfo();
- }
- musicService.notifyChange(musicService.MUSIC_CHANGED);
- }
- public boolean removeTrackAtPosition(final long id, final int position) {
- synchronized (this) {
- if (position >= 0 &&
- position < mPlaylist.size() &&
- mPlaylist.get(position).mId == id) {
- mPlaylistInfo.remove(id);
- return removeTracks(position, position) > 0;
- }
- }
- return false;
- }
- public int removeTracks(final int first, final int last) {
- final int numremoved = removeTracksInternal(first, last);
- if (numremoved > 0) {
- musicService.notifyChange(musicService.QUEUE_CHANGED);
- }
- return numremoved;
- }
- public void clearPlayInfo() {
- File file = new File(musicService.getCacheDir().getAbsolutePath() + "playlist");
- if (file.exists()) {
- file.delete();
- }
- MusicPlaybackState.getInstance(musicService).clearQueue();
- }
- private int getCardId() {
- if (CommonUtils.isMarshmallow()) {
- if (PermissionChecker.PERMISSION_GRANTED == PermissionChecker.checkSelfPermission(musicService.getBaseContext(), Manifest.permission.READ_EXTERNAL_STORAGE)) {
- return getmCardId();
- } else return 0;
- } else {
- return getmCardId();
- }
- }
- private int getmCardId() {
- final ContentResolver resolver = musicService.getContentResolver();
- Cursor cursor = resolver.query(Uri.parse("content://media/external/fs_id"), null, null,
- null, null);
- int mCardId = -1;
- if (cursor != null && cursor.moveToFirst()) {
- mCardId = cursor.getInt(0);
- cursor.close();
- }
- return mCardId;
- }
- public void updateNextTrack() {
- if (mNextPlayPos >= 0 && mNextPlayPos < mPlaylist.size()
- && getShuffleMode() != SHUFFLE_NONE) {
- setNextTrack(mNextPlayPos);
- } else {
- setNextTrack();
- }
- }
- public void setNextTrack() {
- setNextTrack(getNextPosition(false));
- }
- public void setNextTrack(int position) {
- mNextPlayPos = position;
- Timber.e(TAG + " setNextTrack: next play position = " + mNextPlayPos);
- if (mNextPlayPos >= 0 && mPlaylist != null && mNextPlayPos < mPlaylist.size()) {
- final long id = mPlaylist.get(mNextPlayPos).mId;
- Song song = mPlaylistInfo.get(id);
- if (song != null) {
- if (mPlaylistInfo.get(id).isLocal) {
- musicService.setNextDataSource(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "/" + id);
- } else {
- musicService.setNextDataSource(null);
- }
- }
- } else {
- musicService.setNextDataSource(null);
- }
- }
- private boolean wasRecentlyUsed(final int idx, int lookbacksize) {
- if (lookbacksize == 0) {
- return false;
- }
- final int histsize = mHistory.size();
- if (histsize < lookbacksize) {
- lookbacksize = histsize;
- }
- final int maxidx = histsize - 1;
- for (int i = 0; i < lookbacksize; i++) {
- final long entry = mHistory.get(maxidx - i);
- if (entry == idx) {
- return true;
- }
- }
- return false;
- }
- private boolean makeAutoShuffleList() {
- Cursor cursor = null;
- try {
- cursor = musicService.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
- new String[]{
- MediaStore.Audio.Media._ID
- }, MediaStore.Audio.Media.IS_MUSIC + "=1", null, null);
- if (cursor == null || cursor.getCount() == 0) {
- return false;
- }
- final int len = cursor.getCount();
- final long[] list = new long[len];
- for (int i = 0; i < len; i++) {
- cursor.moveToNext();
- list[i] = cursor.getLong(0);
- }
- mAutoShuffleList = list;
- return true;
- } catch (final RuntimeException e) {
- } finally {
- if (cursor != null) {
- cursor.close();
- cursor = null;
- }
- }
- return false;
- }
- public void saveQueue(final boolean full) {
- if (!mQueueIsSaveable) {
- return;
- }
- final SharedPreferences.Editor editor = mPreferences.edit();
- if (full) {
- try {
- mPlaybackStateStore.saveState(mPlaylist, mShuffleMode != SHUFFLE_NONE ? mHistory : null);
- if (mPlaylistInfo.size() > 0) {
- String temp = mGson.toJson(mPlaylistInfo);
- File file = new File(musicService.getCacheDir().getAbsolutePath() + "playlist");
- RandomAccessFile ra = new RandomAccessFile(file, "rws");
- ra.write(temp.getBytes());
- ra.close();
- }
- editor.putInt("cardid", mCardId);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- editor.putInt("curpos", mPlayPos);
- if (Utils.isNotNull(musicService.mPlayer) && musicService.mPlayer.isInitialized()) {
- editor.putLong("seekpos", musicService.mPlayer.position());
- }
- editor.putInt("repeatmode", mRepeatMode);
- editor.putInt("shufflemode", mShuffleMode);
- editor.apply();
- }
- public void setShuffleMode(final int shufflemode) {
- if (mShuffleMode == shufflemode && mPlaylist.size() > 0) {
- return;
- }
- mShuffleMode = shufflemode;
- if (mShuffleMode == SHUFFLE_AUTO) {
- if (makeAutoShuffleList()) {
- mPlaylist.clear();
- doAutoShuffleUpdate();
- mPlayPos = 0;
- musicService.openCurrentAndNext();
- musicService.play();
- musicService.notifyChange(musicService.META_CHANGED);
- return;
- } else {
- mShuffleMode = SHUFFLE_NONE;
- }
- } else {
- setNextTrack();
- }
- saveQueue(false);
- musicService.notifyChange(musicService.SHUFFLEMODE_CHANGED);
- }
- private String readTextFromSDcard(InputStream is) throws Exception {
- InputStreamReader reader = new InputStreamReader(is);
- BufferedReader bufferedReader = new BufferedReader(reader);
- StringBuffer buffer = new StringBuffer();
- String str;
- while ((str = bufferedReader.readLine()) != null) {
- buffer.append(str);
- buffer.append("\n");
- }
- return buffer.toString();
- }
- public int getPreviousPlayPosition(boolean removeFromHistory) {
- synchronized (this) {
- if (mShuffleMode == SHUFFLE_NORMAL) {
- final int histsize = mHistory.size();
- if (histsize == 0) {
- return -1;
- }
- final Integer pos = mHistory.get(histsize - 1);
- if (removeFromHistory) {
- mHistory.remove(histsize - 1);
- }
- return pos.intValue();
- } else {
- if (mPlayPos > 0) {
- return mPlayPos - 1;
- } else {
- return mPlaylist.size() - 1;
- }
- }
- }
- }
- private static final class Shuffler {
- private final LinkedList<Integer> mHistoryOfNumbers = new LinkedList<Integer>();
- private final TreeSet<Integer> mPreviousNumbers = new TreeSet<Integer>();
- private final Random mRandom = new Random();
- private int mPrevious;
- public Shuffler() {
- super();
- }
- public int nextInt(final int interval) {
- int next;
- do {
- next = mRandom.nextInt(interval);
- } while (next == mPrevious && interval > 1
- && !mPreviousNumbers.contains(Integer.valueOf(next)));
- mPrevious = next;
- mHistoryOfNumbers.add(mPrevious);
- mPreviousNumbers.add(mPrevious);
- cleanUpHistory();
- return next;
- }
- private void cleanUpHistory() {
- if (!mHistoryOfNumbers.isEmpty() && mHistoryOfNumbers.size() >= MAX_HISTORY_SIZE) {
- for (int i = 0; i < Math.max(1, MAX_HISTORY_SIZE / 2); i++) {
- mPreviousNumbers.remove(mHistoryOfNumbers.removeFirst());
- }
- }
- }
- }
- }