Android MediaPlayer 本地音乐播放器
运行截图
项目请在真机(自己的手机)上测试运行,因为我不喜欢用虚拟机。
为了不浪费您的时间,先看一下运行的效果图,
一进去先进行音乐扫描,然后列表展示出来,点击即可播放。
源码地址
这个给不想浪费时间往下看的朋友,只因你的时间很宝贵。
前言
至于为什么写一个这样的Demo呢,因为有很多人学习Android就是对于手机应用感兴趣,而网络上的很多源码,一些开源项目的代码小白看不懂,小白能看懂的,有些博主又要用积分下载,痛定思痛,索性自己写一个,当然在写的过程中查阅了网络的资料,也加入了自己的想法,希望能帮到对手机音乐播放器这方面有想法的朋友,好了,话不多说,进入正题.:
代码解释
项目配置
1.权限配置:
打开AndroidManifest.xml
<!--文件读写权限 Android6.0 以后需要动态获取 10.0之后对文件的处理更复杂了--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2.依赖引入:
先打开工程的build.gradle,
加入如下图中的代码
maven { url "https://jitpack.io" } mavenCentral()
然后打开项目的build.gradle,在dependencies闭包中加入以下代码依赖:
//butterknife 绑定视图依赖BindView,告别findById,不过你还得安装一个butterknife插件才行 implementation 'com.jakewharton:butterknife:10.1.0' annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0' //Google Material控件,以及迁移到AndroidX下一些控件的依赖 implementation 'com.google.android.material:material:1.0.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' implementation 'androidx.annotation:annotation:1.1.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' //RecyclerView最好的适配器,让你的适配器一目了然,告别代码冗余 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30' //权限请求框架 implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar' implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' implementation "io.reactivex.rxjava2:rxjava:2.0.0" //状态栏 implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3'
在android闭包中加入
compileOptions { sourceCompatibility = 1.8 targetCompatibility = 1.8 }
指定你的JDK版本,我的项目中用的是AndroidX,如果你没有用过的,建议你先去了解一下:
好了,下面看布局文件,这次是做的一个完成的项目,所以新建了一个工程,里面有一些样式和图片、图标,工程目录如下图,这里就不在做解释了:
布局文件只有两个,activity_main.xml和item_music_rv_list.xml,activity_main这个是项目创建的时候赠送的,item_music_rv_list是为了显示歌曲信息而创建的
activity_main.xml代码:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/img_main_bg_1" android:fitsSystemWindows="true" android:orientation="vertical" tools:context=".MainActivity"> <!--Toolbar--> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:contentInsetLeft="@dimen/activity_horizontal_margin" app:popupTheme="@style/AppTheme.PopupOverlay"> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="聆听音乐" android:textColor="@color/common_black" android:textSize="18sp" /> <TextView android:visibility="gone" android:id="@+id/tv_clear_list" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:foreground="@drawable/bg_white" android:layout_marginRight="@dimen/dp_16" android:padding="@dimen/dp_15" android:text="清空" android:textColor="@color/common_black" /> </androidx.appcompat.widget.Toolbar> <!--扫描歌曲的布局--> <LinearLayout android:id="@+id/scan_lay" android:background="@color/white" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/img_scan_logo" /> <Button android:id="@+id/btn_scan" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/dp_20" android:background="@drawable/selector_scan_btn" android:text="开始扫描" android:textColor="#FFF" android:textSize="22sp" /> </LinearLayout> <!--扫描之后,歌曲的展示和播放布局--> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!--播放歌曲时,显示你播放的是哪一首歌,跑马灯效果--> <LinearLayout android:visibility="gone" android:id="@+id/play_state_lay" android:layout_marginTop="@dimen/dp_1" android:gravity="center" android:background="@color/half_transparent" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/play_state_img" android:background="@mipmap/list_pause_state" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:gravity="center" android:text="歌曲信息" android:ellipsize="marquee" android:focusableInTouchMode="true" android:focusable="true" android:marqueeRepeatLimit="marquee_forever" android:singleLine="true" android:textColor="@color/white" android:id="@+id/tv_play_song_info" android:orientation="vertical" android:layout_width="@dimen/dp_150" android:layout_height="wrap_content"/> </LinearLayout> <!--歌曲的展示列表,都什么年代了,你还在用ListView吗?--> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_music" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <!--底部歌曲播放控制布局--> <LinearLayout android:layout_marginTop="@dimen/dp_4" android:orientation="vertical" android:background="@color/half_transparent" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:gravity="center_vertical" android:layout_alignParentBottom="true" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <!--播放时间--> <TextView android:id="@+id/tv_play_time" android:text="00:00" android:layout_marginLeft="@dimen/dp_4" android:textSize="@dimen/sp_14" android:textColor="@color/white" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <!--歌曲播放进度条 ,样式是自定义,因为原生的太丑了--> <SeekBar android:layout_marginLeft="@dimen/dp_10" android:layout_marginRight="@dimen/dp_10" android:id="@+id/time_seekBar" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:max="100" android:maxHeight="2dp" android:minHeight="2dp" android:progress="0" android:progressDrawable="@drawable/seekbar_style" android:thumb="@drawable/thumb" /> <!--总时间--> <TextView android:id="@+id/tv_total_time" android:layout_marginRight="@dimen/dp_4" android:text="00:00" android:textSize="@dimen/sp_14" android:textColor="@color/white" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> <LinearLayout android:padding="@dimen/dp_10" android:gravity="center" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <!--上一曲--> <ImageView android:id="@+id/btn_previous" android:background="@mipmap/icon_previous" android:layout_width="@dimen/dp_40" android:layout_height="@dimen/dp_40" /> <!--播放或暂停--> <ImageView android:layout_marginLeft="@dimen/dp_20" android:layout_marginRight="@dimen/dp_20" android:id="@+id/btn_play_or_pause" android:background="@mipmap/icon_pause" android:layout_width="@dimen/dp_44" android:layout_height="@dimen/dp_44" /> <!--下一曲--> <ImageView android:id="@+id/btn_next" android:background="@mipmap/icon_next" android:layout_width="@dimen/dp_40" android:layout_height="@dimen/dp_40"/> </LinearLayout> </LinearLayout> </LinearLayout> </LinearLayout>
item_music_rv_list.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/item_music" android:background="@color/color_transparent_10" android:foreground="@drawable/bg_white" android:orientation="vertical" android:layout_marginBottom="@dimen/dp_1" android:gravity="center_vertical"> <LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:gravity="center_vertical" android:padding="10dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_position" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="2dp" android:text="1" android:textColor="@color/white" android:textSize="16sp" /> <LinearLayout android:layout_marginLeft="@dimen/dp_10" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:gravity="center_vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_song_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="歌曲名" android:maxLines="1" android:textColor="@color/white" android:textSize="@dimen/sp_18" /> </LinearLayout> <LinearLayout android:layout_marginTop="@dimen/dp_4" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_singer" android:layout_width="0dp" android:layout_weight="1" android:text="歌手" android:ellipsize="end" android:maxLines="1" android:layout_height="wrap_content" android:textColor="@color/white" android:textSize="14sp" /> <TextView android:id="@+id/tv_duration_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="12dp" android:textColor="@color/white" android:text="时间" android:textSize="14sp" /> </LinearLayout> </LinearLayout> </LinearLayout> </LinearLayout> </LinearLayout>
布局其实没有什么好讲解的,就是显示和隐藏的控制。