簡體   English   中英

如何在Android環球音樂播放器中使用Firebase?

[英]How to use Firebase with the Android universal music player?

是Google示例應用。 它設置為使用JSON從URL中提取元數據。 我想知道如何讓Firebase成為我的來源。

這是我嘗試更改RemoteJSONSource類:

package com.mm.android.uamp.model;

import android.support.v4.media.MediaMetadataCompat;
import android.util.Log;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.mm.android.uamp.utils.LogHelper;

import java.util.ArrayList;
import java.util.Iterator;

public class RemoteJSONSource implements MusicProviderSource {

private static final String TAG = LogHelper.makeLogTag(RemoteJSONSource.class);

DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference mMusic = mRootRef.child("music");

ArrayList<MediaMetadataCompat> tracksFromFB = new ArrayList<>();
public void buildFromFirebase(){

    mMusic.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            for (DataSnapshot music : dataSnapshot.getChildren()){

                String title = music.child("title").getValue(String.class);
                String album = music.child("album").getValue(String.class);
                String artist = music.child("artist").getValue(String.class);
                String genre = music.child("genre").getValue(String.class);
                String source = music.child("source").getValue(String.class);
                String id = String.valueOf(source.hashCode());
                String iconUrl = music.child("image").getValue(String.class);
                int trackNumber = music.child("trackNumber").getValue(Integer.class);
                int totalTrackCount = music.child("totalTrackCount").getValue(Integer.class);
                int duration = music.child("duration").getValue(Integer.class);

                MediaMetadataCompat theMetadataFB = new MediaMetadataCompat.Builder()
                        .putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, id)
                        .putString(MusicProviderSource.CUSTOM_METADATA_TRACK_SOURCE, source)
                        .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, album)
                        .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
                        .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration)
                        .putString(MediaMetadataCompat.METADATA_KEY_GENRE, genre)
                        .putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, iconUrl)
                        .putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
                        .putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, trackNumber)
                        .putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, totalTrackCount)
                        .build();

                tracksFromFB.add(theMetadataFB);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
        }
    });
}

@Override
public Iterator<MediaMetadataCompat> iterator() {
    buildFromFirebase();
    ArrayList<MediaMetadataCompat> tracksFB = tracksFromFB;

    return tracksFB.iterator();
}

}

firebase onDataChange是異步的,所以我認為它還沒有在iterator方法返回tracksFB.iterator之前完成提取數據,因為tracksFB數組為null。 奇怪的是當我在調試模式下運行換行符時

ArrayList tracksFB = tracksFromFB;

有用。 根據我的研究,我認為我需要一個回調或某種類型的暫停任務,但我無法弄明白。

可能的相關代碼連接到迭代器方法

public interface MusicProviderSource {
   String CUSTOM_METADATA_TRACK_SOURCE = "__SOURCE__";
   Iterator<MediaMetadataCompat> iterator();
}

下一個

public class MusicProvider {
private static final String TAG = LogHelper.makeLogTag(MusicProvider.class);
private MusicProviderSource mSource;
private ConcurrentMap<String, List<MediaMetadataCompat>> mMusicListByGenre;
private final ConcurrentMap<String, MutableMediaMetadata> mMusicListById;

private final Set<String> mFavoriteTracks;

enum State {
    NON_INITIALIZED, INITIALIZING, INITIALIZED
}

private volatile State mCurrentState = State.NON_INITIALIZED;

public interface Callback {
    void onMusicCatalogReady(boolean success);
}

public MusicProvider() {
    this(new RemoteJSONSource());
}
public MusicProvider(MusicProviderSource source) {
    mSource = source;
    mMusicListByGenre = new ConcurrentHashMap<>();
    mMusicListById = new ConcurrentHashMap<>();
    mFavoriteTracks = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
}

public Iterable<String> getGenres() {
    if (mCurrentState != State.INITIALIZED) {
        return Collections.emptyList();
    }
    return mMusicListByGenre.keySet();
}

/**
 * Get an iterator over a shuffled collection of all songs
 */
public Iterable<MediaMetadataCompat> getShuffledMusic() {
    if (mCurrentState != State.INITIALIZED) {
        return Collections.emptyList();
    }
    List<MediaMetadataCompat> shuffled = new ArrayList<>(mMusicListById.size());
    for (MutableMediaMetadata mutableMetadata: mMusicListById.values()) {
        shuffled.add(mutableMetadata.metadata);
    }
    Collections.shuffle(shuffled);
    return shuffled;
}

/**
 * Get music tracks of the given genre
 *
 */
public Iterable<MediaMetadataCompat> getMusicsByGenre(String genre) {
    if (mCurrentState != State.INITIALIZED || !mMusicListByGenre.containsKey(genre)) {
        return Collections.emptyList();
    }
    return mMusicListByGenre.get(genre);
}

}

此外,上面鏈接中的musicService.java可能是相關的。 請幫忙!

我有兩種方法可以做到這一點,但我對Firebase不夠熟悉,無法提供有效的代碼。

該示例在AsyncTask執行iterator() ,期望它阻塞直到它可以提供響應。 因此,修復它的第一種也許是最簡單的方法是使iterator()等待正在加載的數據,或者無法加載。 這可能是一個自旋鎖或類似wait / notify的東西。

if (!dataloaded) {
    try {
        wait();
    } catch (InterruptedException e) {}    
}
ArrayList<MediaMetadataCompat> tracksFB = tracksFromFB;

return tracksFB.iterator();

我打電話給buildFromFirebase(); 但是在構造函數中,而不是等待。

第二種選擇是重構UAMP以使其異步加載目錄。 這將是一項更多的工作,但從長遠來看,它可能會帶來更好的設計。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM