Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Listenermusicplayer | 2,269 | 6 years ago | 18 | Java | ||||||
A Grace Material Design Music Player | ||||||||||
Boring | 248 | 6 years ago | 7 | Java | ||||||
Android毕业设计; Android, Music Player, for graduation | ||||||||||
Musicplayer Smartisan | 208 | 2 months ago | Java | |||||||
锤子音乐播放器,仿照锤子系统音乐播放器写的一个本地播放器,具有常用的基本功能。 | ||||||||||
Moemusic | 140 | 6 years ago | 2 | Java | ||||||
一款基于萌否网站api的音乐管理软件 | ||||||||||
Dmusic | 130 | a year ago | 3 | apache-2.0 | Java | |||||
DMusic Player for Android - An online music player based on Component + MVP Base + MVP Customization + greenDAO + OkHttp3 + Retrofit + RxJava2; supports local and network music playback; can play Baidu music, Netease cloud music; support online music list , radio, MV, music online, download, local and online lyrics; Lyrics, music cache; self-built song list, song management, collection, sorting, sorting, skinning, sleep timing, mode switching, more settings, etc. 基于 Component + MVP Base + MVP Customization + greenDAO + OkHttp3 + Retrofit + RxJava2 的在线音乐播放器; 支持本地及网络音乐播放; 可播放百度音乐,网易云音乐; 支持在线音乐榜单, 电台, MV, 音乐在线播放,下载, 本地及在线歌词; 歌词, 音乐缓存; 自建歌单, 歌曲管理, 收藏, 排序, 分类, 换肤, 睡眠定时, 模式切换, 更多设置等 | ||||||||||
Neteasemusic | 57 | 3 years ago | n,ull | Java | ||||||
Material Design NetEase Music Player In MVP Pattern Design 网易云音乐 | ||||||||||
Androidopensourceproject | 55 | 4 years ago | Python | |||||||
Android完整的开源项目汇总 | ||||||||||
Android Music App | 53 | 5 years ago | apache-2.0 | Kotlin | ||||||
Simplified version of Melophile. | ||||||||||
Goonj | 9 | 3 years ago | n,ull | mit | Kotlin | |||||
A music player library that supports stream playback with download feature, remote playback, and analytics. It is build on Exo-Player and Google Cast framework. | ||||||||||
Emilia | 7 | 4 years ago | 1 | Java | ||||||
Material Design Music Player (neteasy api) |
RxJava is a Functional Reactive Paradigm. It is essentially the Observer pattern, but taken to the extreme. In the simplest of cases you have standard observables and observers. The real power of Reactive Extensions comes from chaining observables in a functional paradigm. This requires a bit of a mind shift from standard Object oriented programming so do not expect to fully grok it today. The goal of this codelab is to play with RxJava a bit using a fun project. Hopefully by the end you will see a little bit of the power that RxJava provides to Android Development. Some of the things that we will touch on briefly include:
Subject
The Codelab starts intentionally slow. Everyone leaving should have a finished app that plays music only while the user is dancing within an hour or so. For those more advanced or wanting to explore more there are open ended further steps at the end. Feel free to move ahead at your own pace. If you get stuck don't worry. There is a corresponding branch for each checkpoint in this repo. Feel free to checkout the code and look through the commit history. I tried to keep them super small and targeted.
<activity android:name=".MainActivity"
android:screenOrientation="portrait" >
MusicPlayer
that wraps and android MediaPlayer
instance. Give it lifecycle methods for create, destroy, play and pause.MusicPlayer
should not interact with the MediaPlayer
if it is currently playing or paused respectively. (This will be important later)MusicPlayer
on the activity's onCreate()
method and release it onDestroy()
.View.OnClickListener()
to each of the buttons that performs the play and pause functionality on the music player.buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'me.tatarka:gradle-retrolambda:3.2.4'
}
}
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
In this step we will be taking a callback provided by an external dependency and turn it into a stream of events using a PublishSubject
. While not necessary we will be creating an Observable for the emmited x, y , and z values. This will allow us to demonstrate one of the most useful Operators for Android Development.
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
final Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(sensorEventListener, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
sensorEventListener = new SensorEventListener() {
@Override
public void onSensorChanged(final SensorEvent event) {
}
@Override
public void onAccuracyChanged(final Sensor sensor, final int accuracy) {
}
};
PublishSubject
's in your activity using the PublishSubject.create()
method.onSensorChanged
method publish the events to your PublishSubject
using the onNext()
method with each of your sensor values.PublishSubject
's like soDisposable disposable = xValue.subscribe(new Consumer<Float>() {
@Override
public void accept(Float aFloat) throws Exception {
Log.i(MainActivity.class.getSimpleName(), "Received xValue " + aFloat);
}
});`
disposable = xValue.subscribe(aFloat -> Log.i(TAG, "Received xValue " + aFloat));
In this step we will use a functional reactive paradigm to do the following while holding no state in our activity.
So instead of a guided walkthrough let's just look at the code. Take a few minutes and try to grasp what is going on here, and ponder the power of using RxJava over doing the same work in a callback.
//Combine the latest x, y, and z sensor values and emit the combination as a list of Floats.
disposable = Observable.combineLatest(xValue, yValue, zValue, (x, y, z) -> Arrays.asList(x, y, z))
//Sample the latest event every 20 seconds to limit backpressure
.sample(20, TimeUnit.MILLISECONDS)
//From here on go to the computation thread
.subscribeOn(Schedulers.computation())
//Turn the list of Floats into a Magnitude
.map(floats -> {
float magnitude = 0;
for(Float aFloat : floats){
magnitude += aFloat * aFloat;
}
return magnitude;
})
//Accumulate the last 10 magnitude events in an Evicting Queue (you can write one if you are against Guava)
.scan(EvictingQueue.create(EVENT_COUNT), (BiFunction<EvictingQueue<Float>, Float, EvictingQueue<Float>>) (objects, aFloat) -> {
objects.add(aFloat);
return objects;
})
//Take the last accumulated events and calculate an average
.map(floats -> {
float sum = 0;
for(Float foo : floats){
sum += foo;
}
return sum/ EVENT_COUNT;
})
//Move onto a new thread to interact with the music player
.observeOn(Schedulers.newThread())
.subscribe(weightedMagnitude -> {
Log.e("Music", "weighted magnitude was " + weightedMagnitude);
if (weightedMagnitude != null && weightedMagnitude > MUSIC_THRESHOLD) {
audioPlayer.play();
} else {
audioPlayer.pause();
}
});