Android毕设音乐播放器实现

基于MediaPlayer技术实现在线音乐播放器,播放在线音乐,后端使用SpringBoot将音乐存放在Tomcat服务器。app通过网络请求获取音乐,从而实现在线音乐播放。该项目分为用户端和管理员端


一、核心技术Service组件介绍

Service它可以在后台执行长时间运行操作而没有用户界面的应用组件,不依赖任何用户界面,例如后台播放音乐,后台下载文件等。

虽然服务是在后台运行的,但是Service和Activity都是运行在当前APP所在的main thread(UI主线程)中的,而耗时操作(如网络请求、拷贝数据、大文件)会阻塞主线程,给用户带来不好的体验。如果需要在服务中进行耗时操作,可以选择 IntentService,IntentService是Service的子类,用来处理异步请求。

二、如何使用SerVice

创建Service直接在Android Studio中右键选择Service创建即可。默认我们所创建的Service是继承Service的。同时我们为了实现后台音乐播放的功能,所以我们还要实MediaPlayer.OnCompletionListener的接口。

同时还要在AndroidManifest.xml文件中对已经创建的Service进行注册,这一点Android Studio已经帮我们自动创建好了

三、Service启动的两种方式

(1)在Acitivity界面通过显式意图(或隐式意图)的方式来启动服务和关闭服务。

Intent intentService = new Intent(MainActivity.this, AudioService.class);startService(intentService);

(2)bindService()绑定服务

当应用组件通过调用 bindService() 绑定到服务时,服务即处于“绑定”状态。绑定服务提供了一个客户端-服务器接口,允许组件与服务进行交互、发送请求、获取结果。 仅当与另一个应用组件绑定时,绑定服务才会运行。 多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。


1. 用户端功能模块:登录,注册,音乐推荐,音乐分类,个人中心,音乐浏览记录,我的下载,上一曲,下一曲,音乐下载



2.管理员模块:登录,注册,用户管理,音乐分类管理(添加分类,删除分类,编辑分类),音乐管理(修改歌名,移动音乐分类,删除音乐)



3.部分核心代码实现

欢迎页

/*** 欢迎页*/
@SuppressLint("CustomSplashScreen")
public class SplashActivity extends BaseActivity<ActivitySplashBinding> {@Overrideprotected ActivitySplashBinding getViewBinding() {return ActivitySplashBinding.inflate(getLayoutInflater());}@Overrideprotected void setListener() {}@Overrideprotected void initData() {new Handler(Looper.myLooper()).postDelayed(new Runnable() {@Overridepublic void run() {startActivity(new Intent(mContext,LoginActivity.class));finish();}},800);}
}

用户主页面

/*** 用户主页面*/
public class MainActivity extends BaseActivity<ActivityMainBinding> {private String[] titles = {"音乐推荐", "音乐分类"};private List<Fragment> fragmentList = new ArrayList<>();@Overrideprotected ActivityMainBinding getViewBinding() {return ActivityMainBinding.inflate(getLayoutInflater());}@Overrideprotected void setListener() {mBinding.avatar.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {startActivityForResult(new Intent(MainActivity.this, MineActivity.class), 20002);}});}@Overrideprotected void initData() {if (ApiConstants.getUserInfo() != null) {mBinding.username.setText(ApiConstants.getUserInfo().getUsername());}//造数据fragmentList.add(new HomeFragment());fragmentList.add(new TypeFragment());
//        fragmentList.add(new RecordFragment());//如果处理成懒加载的话,其实很简单,只要是这个方法setOffscreenPageLimit不去设置,就可以了。
//        mBinding.viewPager.setOffscreenPageLimit(fragmentList.size());mBinding.viewPager.setUserInputEnabled(false);mBinding.viewPager.setAdapter(new FragmentStateAdapter(this) {@NonNull@Overridepublic Fragment createFragment(int position) {return fragmentList.get(position);}@Overridepublic int getItemCount() {return fragmentList.size();}});mBinding.tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {@Overridepublic void onTabSelected(TabLayout.Tab tab) {mBinding.viewPager.setCurrentItem(tab.getPosition(), false);}@Overridepublic void onTabUnselected(TabLayout.Tab tab) {}@Overridepublic void onTabReselected(TabLayout.Tab tab) {}});TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(mBinding.tabs, mBinding.viewPager, new TabLayoutMediator.TabConfigurationStrategy() {@Overridepublic void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {tab.setText(titles[position]);}});//这句话很重要tabLayoutMediator.attach();}@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == 20002) {finish();}}
}

音乐播放界面

/*** 音乐播放界面*/
public class PlayMusicActivity extends BaseActivity<ActivityPlayMusicBinding> implements OnPlayerEventListener {private static final String TAG = "============";private MusicInfo musicInfo;private int mLastProgress;@Overrideprotected ActivityPlayMusicBinding getViewBinding() {return ActivityPlayMusicBinding.inflate(getLayoutInflater());}@Overrideprotected void setListener() {Aria.download(this).register();mBinding.sbProgress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean b) {if (Math.abs(progress - mLastProgress) >= DateUtils.SECOND_IN_MILLIS) {mBinding.tvCurrentTime.setText(formatTime("mm:ss", progress));mLastProgress = progress;}}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {if (AudioPlayer.get().isPlaying() || AudioPlayer.get().isPausing()) {int progress = seekBar.getProgress();AudioPlayer.get().seekTo(progress);} else {seekBar.setProgress(0);}}});mBinding.ivMusicPlay.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {AudioPlayer.get().playPause();}});mBinding.ivMusicPrevious.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {AudioPlayer.get().prev();}});mBinding.ivMusicNext.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {AudioPlayer.get().next();}});//下载mBinding.download.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (XXPermissions.isGranted(mContext, Permission.Group.STORAGE)) {download();} else {checkPermission();}}});}@Overrideprotected void initData() {initSystemBar();musicInfo = (MusicInfo) getIntent().getSerializableExtra("musicInfo");//监听AudioPlayer.get().addOnPlayEventListener(this);if (null != musicInfo) {AudioPlayer.get().addAndPlay(musicInfo);//添加到浏览记录addRecord(musicInfo);//获取单个任务实体DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(musicInfo.getMusic_url());if (null != entity) {mBinding.download.setClickable(false);mBinding.download.setImageResource(R.mipmap.ic_download_complete);} else {mBinding.download.setClickable(true);mBinding.download.setImageResource(R.mipmap.iv_download);}}}/*** 沉浸式状态栏*/private void initSystemBar() {ImmersionBar.with(this).init();}public String formatTime(String pattern, long milli) {int m = (int) (milli / DateUtils.MINUTE_IN_MILLIS);int s = (int) ((milli / DateUtils.SECOND_IN_MILLIS) % 60);String mm = String.format(Locale.getDefault(), "%02d", m);String ss = String.format(Locale.getDefault(), "%02d", s);return pattern.replace("mm", mm).replace("ss", ss);}@SuppressLint("SetTextI18n")private void onChangeImpl(MusicInfo music) {if (music == null) {return;}mBinding.sbProgress.setProgress((int) AudioPlayer.get().getAudioPosition());mBinding.sbProgress.setSecondaryProgress(0);mLastProgress = 0;mBinding.tvCurrentTime.setText("00:00");if (AudioPlayer.get().isPlaying() || AudioPlayer.get().isPreparing()) {mBinding.ivMusicPlay.setSelected(true);} else {mBinding.ivMusicPlay.setSelected(false);}mBinding.toolbar.setTitle(music.getMusic_title());mBinding.tvMusicTitle.setText(music.getMusic_title());mBinding.tvMusicSongType.setText(music.getMusic_type());startAnim();}@Overridepublic void onChange(MusicInfo music) {onChangeImpl(music);}@Overridepublic void onPlayerStart(long duration) {//一定要设置最大值mBinding.sbProgress.setMax((int) duration);mBinding.tvTotalTime.setText(formatTime("mm:ss", duration));mBinding.ivMusicPlay.setSelected(true);startAnim();}@Overridepublic void onPlayerPause() {mBinding.ivMusicPlay.setSelected(false);stopAnim();}@Overridepublic void onPublish(int progress) {mBinding.sbProgress.setProgress(progress);}@Overridepublic void onBufferingUpdate(int percent) {mBinding.sbProgress.setSecondaryProgress(mBinding.sbProgress.getMax() * 100 / percent);}private Animation animation;private void startAnim() {animation = AnimationUtils.loadAnimation(this, R.anim.rotation_animation);LinearInterpolator lin = new LinearInterpolator();//设置动画匀速运动animation.setInterpolator(lin);mBinding.imgCd.startAnimation(animation);}private void stopAnim() {if (mBinding.imgCd.getAnimation() != null) {mBinding.imgCd.clearAnimation();}}private void addRecord(MusicInfo musicInfo) {OkGo.<String>get(ApiConstants.ADD_RECORD_MUSIC_URL).params("username", ApiConstants.getUserInfo().getUsername()).params("music_title", musicInfo.getMusic_title()).params("music_url", musicInfo.getMusic_url()).params("music_type", musicInfo.getMusic_type()).execute(new HttpStringCallback(null) {@Overrideprotected void onSuccess(String msg, String response) {}@Overrideprotected void onError(String response) {}});}private void checkPermission() {XXPermissions.with(this)// 申请单个权限// 申请多个权限.permission(Permission.Group.STORAGE)// 设置权限请求拦截器(局部设置)//.interceptor(new PermissionInterceptor())// 设置不触发错误检测机制(局部设置)//.unchecked().request(new OnPermissionCallback() {@Overridepublic void onGranted(List<String> permissions, boolean all) {if (!all) {showToast("获取部分权限成功,但部分权限未正常授予");return;}//这里做操作}@Overridepublic void onDenied(List<String> permissions, boolean never) {if (never) {showToast("被永久拒绝授权,请手动授予录音和日历权限");// 如果是被永久拒绝就跳转到应用权限系统设置页面XXPermissions.startPermissionActivity(mContext, permissions);} else {showToast("获取录音和日历权限失败");}}});}@Download.onWaitpublic void onWait(DownloadTask task) {Log.d(TAG, "onWait: ");}@Download.onPrepublic void onPre(DownloadTask task) {Log.d(TAG, "onPre: ");}@Download.onTaskStartpublic void onTaskStart(DownloadTask task) {Log.d(TAG, "onTaskStart: ");showToast("开始下载~~~~~");}@Download.onTaskRunningpublic void onTaskRunning(DownloadTask task) {Log.d(TAG, "onTaskRunning: ");}@Download.onTaskResumepublic void onTaskResume(DownloadTask task) {Log.d(TAG, "onTaskResume: ");}@Download.onTaskStoppublic void onTaskStop(DownloadTask task) {Log.d(TAG, "onTaskStop: ");}@Download.onTaskCancelpublic void onTaskCancel(DownloadTask task) {Log.d(TAG, "onTaskCancel: ");}@Download.onTaskFailpublic void onTaskFail(DownloadTask task, Exception e) {Log.d(TAG, "onTaskFail: ");}@Download.onTaskCompletepublic void onTaskComplete(DownloadTask task) {Log.d(TAG, "onTaskComplete: ");mBinding.download.setClickable(false);mBinding.download.setImageResource(R.mipmap.ic_download_complete);showToast("下载完成~~~~~");}private void download() {if (null != musicInfo) {Aria.download(PlayMusicActivity.this).load(musicInfo.getMusic_url()) // 下载地址.setFilePath(getExternalCacheDir().getPath() + musicInfo.getMusic_title() + ".mp3") // 设置文件保存路径.setExtendField(GsonUtils.toJson(musicInfo)).create();}}}

详情可私信哦~~~~~~

Android程序设计之音乐播放器实现相关推荐

  1. android音乐播放器案例,Android MediaPlayer实现音乐播放器实例代码

    Android MediaPlayer实现音乐播放器 1.布局文件 android:layout_width="fill_parent" android:layout_height ...

  2. 安卓java自实现mp3播放器,Android MediaPlayer实现音乐播放器实例代码

    Android MediaPlayer实现音乐播放器 1.布局文件 android:layout_width="fill_parent" android:layout_height ...

  3. [内附完整源码和文档] 基于Android的手机音乐播放器的设计与实现

    摘 要 随着Android系统和移动互联网的快速崛起,手机已经成为人们生活不可缺的一部分,在现代人的生活中,人们生活节奏的加快,生活压力越来越大,碎片化的时间越来越多,那么一个可以在碎片化的时间内调节 ...

  4. Android Studio简易音乐播放器设计作业

    Android Studio简易音乐播放器设计作业 实验成功展示 实验代码 MainActivity.java XML文件 class文件 利用BroadcastReceiver模拟音乐播放器,实现播 ...

  5. android音乐播放器实现,Android实现简单音乐播放器(MediaPlayer)

    Android实现简单音乐播放器(MediaPlayer),供大家参考,具体内容如下 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 实现一个 ...

  6. 计算机毕业设计android的在线音乐播放器app设计(源码+系统+mysql数据库+Lw文档)

    项目介绍 Android是Google公司公布的基于Linux内核的手机操作系统,其代码属于完全开放,为开源软件开发人员提供使用方便的框架和平台.,本文以Android开发平台为基础,介绍了音乐播放器 ...

  7. 基于android的在线音乐播放器app设计

    Android是Google公司公布的基于Linux内核的手机操作系统,其代码属于完全开放,为开源软件开发人员提供使用方便的框架和平台.,本文以Android开发平台为基础,介绍了音乐播放器的开发.首 ...

  8. Android端本地音乐播放器(一)---前言

    前言: 2018时的记录:大概一周多以前(现在是2018.11.26   15:24)android平台开发的课程结束了,要写大作业,最后决定写这个音乐播放器,因为老师在课堂上讲的例子也是这个,前面的 ...

  9. 张利国,龚海平,王植萌.android移动开发入门与进阶,开题报告-基于Android的手机音乐播放器的设计与实现.doc...

    盐城师范学院 毕业设计开题报告 题 目: 基于android的手机音乐播放器 的设计与实现 姓 名: 二级学院: 信息工程学院 专 业: 软件工程 班 级: 12(1) 学 号: 指导教师: 职称: ...

最新文章

  1. 六、使用数组模拟栈的思路及代码实现
  2. matlab2018无法使用qcat,解决Matlab 2018a源代码的中文支持问题
  3. python随机排列图片_python 随机打乱 图片和对应的标签方法
  4. 天底下最大的“骗子”——年龄
  5. 技术实践 | 如何基于 Flink 实现通用的聚合指标计算框架
  6. vector和deque的区别?
  7. 2021最新Python量化A股投资必赚策略
  8. 容器操作系统虚拟化_为什么操作系统在容器化世界中很重要
  9. 【华为云技术分享】万万没想到,我在夜市地摊解决了MySQL临时表空间难题~~
  10. 临时设置mysql数据库最大连接数,重启后需重新设置
  11. window10运行python弹出商店_Python上架Windows 10应用商店,但主要用于学习,正式项目还...
  12. 7000字爆肝!我把14个自学编程的压箱底网站全部分享给你们啦
  13. 有3种水果(苹果、香蕉、橘子),每位同学只能选1种最爱吃的(共5位同学),要求编一个统计水果票数的程序,先输入水果种类,最后输出各水果得票结果。
  14. 派对屋3000效果器怎样调试_音响效果器的调试和使用技巧
  15. 区块链游戏:何为虚拟?何为现实?
  16. 计算机管理哪个是主板驱动,请问一下这里面哪个是主板驱动?
  17. 2022年节约用水倡议书
  18. R统计计算--差异性检验
  19. css 调用外部字体、自定义字体
  20. 研发效能度量框架解读

热门文章

  1. 74HC595驱动2位数码管代码实现和注意事项
  2. 继续啃书,包,触发器
  3. Windows之使用批处理创建快捷方式到桌面(符号链接)
  4. pandas列是否为空_如果列值不为空,Python pandas将应用函数
  5. 互联网学习记录:三件套_Javascript
  6. 危险化学品事故爬虫解析
  7. oracle 数据跟踪软件,oracle数据库跟踪工具
  8. [Java]分布式自平衡多文件云传输
  9. [转]详细解释数据挖掘中的 10 大算法
  10. python office转pdf linux_python 如何将office文件转换为PDF