Android MediaPlayer 音乐播放器扫描 本地音乐、上一曲、下一曲切歌、播放本地音乐(上)

简介: Android MediaPlayer 音乐播放器扫描 本地音乐、上一曲、下一曲切歌、播放本地音乐(上)

Android MediaPlayer 本地音乐播放器


运行截图


项目请在真机(自己的手机)上测试运行,因为我不喜欢用虚拟机。

为了不浪费您的时间,先看一下运行的效果图,

一进去先进行音乐扫描,然后列表展示出来,点击即可播放。


20200319171049255.png

20200319171129159.png


源码地址


这个给不想浪费时间往下看的朋友,只因你的时间很宝贵。


前言


至于为什么写一个这样的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,


加入如下图中的代码

20200319173613856.png


    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,如果你没有用过的,建议你先去了解一下:


好了,下面看布局文件,这次是做的一个完成的项目,所以新建了一个工程,里面有一些样式和图片、图标,工程目录如下图,这里就不在做解释了:


20200319172721224.png


布局文件只有两个,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>


布局其实没有什么好讲解的,就是显示和隐藏的控制。



相关文章
|
4月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
125 15
Android 系统缓存扫描与清理方法分析
|
4月前
|
Java 程序员 开发工具
Android|修复阿里云播放器下载不回调的问题
虽然 GC 带来了很多便利,但在实际编码时,我们也需要注意对象的生命周期管理,该存活的存活,该释放的释放,避免因为 GC 导致的问题。
58 2
|
8月前
|
XML 存储 数据库
如何使用Android Studio创建一个基本的音乐播放器应用
如何使用Android Studio创建一个基本的音乐播放器应用
352 0
|
6月前
|
Android开发
Android 利用MediaPlayer实现音乐播放
本文提供了一个简单的Android MediaPlayer音乐播放示例,包括创建PlayerActivity、配置AndroidManifest.xml和activity_player.xml布局,以及实现播放和暂停功能的代码。
61 0
Android 利用MediaPlayer实现音乐播放
|
6月前
|
编解码 开发工具 Android开发
Android平台RTSP|RTMP播放器如何实现TextureView渲染
本文介绍了在Android平台上使用TextureView进行RTSP和RTMP视频流渲染的技术背景和实现方法。TextureView相较于SurfaceView具备更高性能、更强功能性和更灵活的绘制方式等优势,但也有必须在硬件加速环境下运行和较高内存占用等局限。文中详细展示了如何在SmartPlayerV2工程中创建和配置TextureView,并通过代码示例解释了如何根据视频分辨率信息调整显示比例,以及处理TextureView的各种生命周期回调。此外,还列举了该播放器SDK支持的多项高级功能,如多实例播放、多种编码格式支持、硬解码能力等,旨在帮助开发者更好地理解和实现高性能的直播播放器。
105 3
|
6月前
|
算法 数据处理 开发工具
Android平台RTSP|RTMP播放器如何回调YUV或RGB数据
在开发Android平台上的RTSP或RTMP播放器时,开发者不仅追求低延迟播放,还希望获取解码后的视频数据(如YUV或RGB格式),以便进行视觉算法分析。使用大牛直播SDK中的SmartPlayer,可在确保播放流畅的同时,通过设置外部渲染器(`SmartPlayerSetExternalRender`)来高效地回调原始视频数据。例如,对于RGBA数据,需实现`NTExternalRender`接口,并重写相关方法以处理数据和尺寸变化。同样地,对于I420(YUV)数据,也需要相应地实现接口以满足需求。这种方式使得开发者能在不影响常规播放功能的情况下,进行定制化的视频处理任务。
|
6月前
|
编解码 网络协议 开发工具
Android平台RTSP|RTMP直播播放器技术接入说明
大牛直播SDK自2015年发布RTSP、RTMP直播播放模块,迭代从未停止,SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述,全自研内核,行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以Android平台为例,介绍下如何集成RTSP、RTMP播放模块。
224 0
|
8月前
|
存储 Android开发 Kotlin
开发安卓app OKhttp下载后使用MediaPlayer播放
在Android Jetpack Compose应用程序中,要使用OkHttp下载远程音频文件并在本地播放,你需要完成以下几个步骤: 1. **添加依赖**:确保`build.gradle`文件包含OkHttp和Jetpack Compose的相关依赖。 2. **下载逻辑**:创建一个`suspend`函数,使用OkHttp发起网络请求下载音频文件到本地。 3. **播放逻辑**:利用`MediaPlayer`管理音频播放状态。 4. **Compose UI**:构建用户界面,包含下载和播放音频的按钮。
|
8月前
|
存储 Android开发
安卓app,MediaPlayer播放本地音频 | 按钮控制播放和停止
在Jetpack Compose中,不直接操作原生Android组件如`Button`和`MediaPlayer`,而是使用Compose UI构建器定义界面并结合ViewModel管理音频播放逻辑。以下示例展示如何播放本地音频并用按钮控制播放/停止:创建一个`AudioPlayerViewModel`管理`MediaPlayer`实例和播放状态,然后在Compose UI中使用`Button`根据`isPlaying`状态控制播放。记得在`MainActivity`设置Compose UI,并处理相关依赖和权限。
|
8月前
|
存储 Android开发 Kotlin
Kotlin开发安卓app,在使用 MediaPlayer 播放 res/raw 中的音乐时遇到突然中断的问题,而 onErrorListener 没有接收到任何报错
在使用 Android MediaPlayer 播放 res/raw 中的音乐时遇到中断问题,可能的原因包括资源问题、媒体文件编码格式、生命周期管理和设备资源配置。要排查问题,检查音频文件是否正确包含,格式编码是否支持,MediaPlayer 是否正确管理及释放,以及设备是否有足够存储和配置。通过设置 onErrorListener 日志和确保在 onDestroy 中释放资源来调试。如果文件过大,考虑使用 AssetManager。遵循这些步骤可帮助诊断并解决播放中断的问题。

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 6
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 10
    Android 13 SystemUI 启动流程
  • 1
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    24
  • 2
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    21
  • 3
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
    52
  • 4
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    35
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    70
  • 6
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    112
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
    29
  • 8
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
    265
  • 9
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
    76
  • 10
    【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    36