简体   繁体   English

如何在Android环球音乐播放器中使用Firebase?

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

Here is the Google sample app. 是Google示例应用。 It's set up to pull metadata from a URL with a JSON. 它设置为使用JSON从URL中提取元数据。 I would like to know how to have Firebase be my source. 我想知道如何让Firebase成为我的来源。

Here is my attempt in changing the RemoteJSONSource class: 这是我尝试更改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();
}

}

The firebase onDataChange is asynchronous so I think it hasn't finished pulling the data yet before the iterator method returns tracksFB.iterator cause tracksFB array is null. firebase onDataChange是异步的,所以我认为它还没有在iterator方法返回tracksFB.iterator之前完成提取数据,因为tracksFB数组为null。 Weird thing is when I run in debug mode with a line break on 奇怪的是当我在调试模式下运行换行符时

ArrayList tracksFB = tracksFromFB; ArrayList tracksFB = tracksFromFB;

It works. 有用。 From my research I think I need a callback or some type of pausing task, but I just cant figure it out. 根据我的研究,我认为我需要一个回调或某种类型的暂停任务,但我无法弄明白。

Possible relevant code connected to the iterator method 可能的相关代码连接到迭代器方法

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

next 下一个

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);
}

}

Also the musicService.java in the link above might be relevant. 此外,上面链接中的musicService.java可能是相关的。 PLEASE help! 请帮忙!

There are two ways I can think to do this, but I'm not familiar enough with Firebase to provide working code. 我有两种方法可以做到这一点,但我对Firebase不够熟悉,无法提供有效的代码。

The sample executes iterator() in an AsyncTask , expecting it to block until it can provide a response. 该示例在AsyncTask执行iterator() ,期望它阻塞直到它可以提供响应。 So the first, and probably easiest, way to fix it would be to cause iterator() to wait on the data being loaded, or it failing to load. 因此,修复它的第一种也许是最简单的方法是使iterator()等待正在加载的数据,或者无法加载。 This could be a spinlock or something like wait/notify. 这可能是一个自旋锁或类似wait / notify的东西。

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

return tracksFB.iterator();

I'd call buildFromFirebase(); 我打电话给buildFromFirebase(); in the constructor though, rather than waiting. 但是在构造函数中,而不是等待。

The second option would be to refactor UAMP to have it load the catalog asynchronously. 第二种选择是重构UAMP以使其异步加载目录。 This would be a lot more work, but it may result in a better design in the long run. 这将是一项更多的工作,但从长远来看,它可能会带来更好的设计。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何让通用音乐播放器在设备音乐上进行检测? - How to get the universal music player to detect on device music? getItem()在Android开发人员的示例通用音乐播放器应用程序中如何真正起作用? - How does getItem() really work in android developer's sample universal music player app? 在android studio(通用音乐播放器应用程序)中按升序排序列表 - Sort list in ascending order in android studio (universal music player app) 未显示Android Universal音乐播放器ic_by_genre - Android Universal Music Player ic_by_genre is not displayed Android 通用音乐播放器在 MediaItemViewHolder 中添加专辑封面 - Android universal music player add album cover in the MediaItemViewHolder Android:如何创建音乐播放器? - Android: How to create music player? 在Android中控制音乐播放器的音乐 - Control music of music player in Android Android如何从媒体播放器录制音乐 - Android how to record music from media player 如何在Android中为音乐播放器创建缩略图播放列表? - How to create a thumbnail playlist for a music player in android? 如何获得活跃的音乐播放器-android - How to get active music player — android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM