android音乐播放器开发 SweetMusicPlayer 实现思路

简介:

 一,实现效果

眼下还不是特别完好,主要有下面几个功能,
1,载入歌曲列表(实现a-z字母检索)
2,播放本地音乐
3。智能匹配本地歌词
4。智能载入在线歌词(事实上不算智能。发现歌词迷api提供的歌词好多难以解析) 
5。摇一摇换歌功能


先上几张截图吧




另外,素材来自天天动听和百度音乐。。。毕竟作为一个码农,p图什么的太累。

楼主也是一介菜鸟。想记录一下做过的东西。做一个总结。



二。实现思路

1。主要界面设计

1)用tabs实现歌曲,近期。艺术家,专辑等分类,眼下楼主仅仅实现了歌曲部分。
2)主界面底部有个bottomactionbar用来操作歌曲状态,点击后弹出歌词播放界面。(这里必需要吐槽下,我眼下的实现方案不是非常好,用的最外层包裹的一层ScrollView,把歌词界面和歌曲界面放进去,操作时滚动到需要的界面位置,本想模仿天天动听能够把歌词界面拖拽出来,技术有限。弄了三四种方案,成了现在蹩脚的样子)
3)歌词界面,实现歌词部分,歌词调整进度。

2,主要实现思路

用一个MusicManager类控制播放器的主要事件及操作。然后广播通知ui控件更新。

在MusicManager设置一个ListView成员变量作为当前播放的控件。

由于可能用户不通过歌曲列表播放,可能通过近期播放列表。艺术家列表等等。

MusicManager包括各种状态以及操作,比方播放音乐。随机一个音乐。下一曲等等。

然后去通知播放音乐的service。先简介一下吧,然后再总结详细实现。
package com.huwei.sweetmusicplayer.datamanager;

 
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

 
import android.content.Context;
import android.content.Intent;
 
import android.provider.MediaStore;
 
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.ListView;

import com.huwei.sweetmusicplayer.enums.MusicState;
import com.huwei.sweetmusicplayer.models.Song;
import com.huwei.sweetmusicplayer.ui.fragments.PlayingFragment;
 

 

public class MusicManager {
	private  int nowplaying_index=-1;
	public static boolean isPlaying=false;
	public static final String BOTTOMACTIONBAR_UPDATE="BOTTOMACTIONBAR_UPDATE";
	public static final String BOTTOMACTIONBAR_CHECKED="BOTTOMACTIONBAR_CHECKED";
	public static final String BOTTOMACTIONBAR_UNCHECKED="BOTTOMACTIONBAR_UNCHECKED";
	
	public static final String PLAY_BTN_CHECKED="PLAY_BTN_CHECKED";
	public static final String PLAY_BTN_UNCHECKED="PLAY_BTN_UNCHECKED";
	
	private static MusicManager instance;
	private Context context;
	private List<Song> songLists=new ArrayList<Song>();	//启动应用从数据库都进来时候的列表
	private ListView nowPlayingListView;		//正在播放音乐的列表控件
 
 
	
	
		/**
	 * 定义查找音乐信息数组。0.标题,1音乐时间,2.艺术家,3.音乐id,4.显示名字,5.全路径,6,专辑ID,7最后加入时间。
	 */
	public static  String[] media_info = new String[] { MediaStore.Audio.Media.TITLE,
			MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ARTIST,
			MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME,
			MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID ,MediaStore.MediaColumns.DATE_ADDED};
	
	

	
	public static MusicManager getInstance(){
		if(null==instance){
			instance=new MusicManager();
		}
		return instance;
	}
	
	//加入song到songLists
	public void addSong(Song song){
		songLists.add(song);
	}
	
 
	
	public void bind(Context context){
		this.context=context;
	}
	
	public void play(){
 
		
		Intent intent=new Intent();
		Song song=(Song) nowPlayingListView.getAdapter().getItem(nowplaying_index); 
		intent.setAction("com.huwei.sweetmusicplayer.services.LocalMusicService");
		intent.putExtra("song", song);
		intent.putExtra("op", MusicState.PLAYING.ordinal());	//播放选项
		context.startService(intent);
		
 
		
		//通知playButton
		Intent intent3=new Intent(PLAY_BTN_CHECKED);
		context.sendBroadcast(intent3);
		
		
		isPlaying=true;
	}
	
	//先停止,再播放
	public void restartPlay(){
		stopUnNotifyView();
		play();
	}
	
	public void previousSong(){
		setNowplaying_index(nowplaying_index-1);
 		restartPlay();
	}
	
	public void nextSong(){
		//都要用set方法。便于通知更新视图
		setNowplaying_index(nowplaying_index+1);
 		restartPlay();
	}
	
	//随机播放一首歌
	public void random_a_song(){
		getRandom_song();
		restartPlay();
	}
	
	public void pause(){
		Intent intent=new Intent();
		intent.setAction("com.huwei.sweetmusicplayer.services.LocalMusicService");
		intent.putExtra("op", MusicState.PAUSE.ordinal());	//播放选项
		context.startService(intent);
		
 
		
		isPlaying=false;
		
		//通知playButton
		Intent intent3=new Intent(PLAY_BTN_UNCHECKED);
		context.sendBroadcast(intent3);
	}
	
	
	//发送停止音乐广播,可是不更新视图
	public void stopUnNotifyView(){
		Intent intent=new Intent();
		intent.setAction("com.huwei.sweetmusicplayer.services.LocalMusicService");
		intent.putExtra("op", MusicState.STOP.ordinal());	//播放选项
		context.startService(intent);
	}
	
	
	//停止音乐
	public void stop(){
		stopUnNotifyView();
		
 
	}
	
	
	//设置音乐进度
	public void setProgress(int progress){
	 
		Intent intent=new Intent("com.huwei.sweetmusicplayer.services.LocalMusicService");
		intent.putExtra("progress", progress);
		intent.putExtra("op", MusicState.PROGRESS_CHANGE.ordinal());
		context.startService(intent);
	}
	
	//随机得到一首歌
	public int getRandom_song(){
		int random=new Random().nextInt(nowPlayingListView.getAdapter().getCount());
		setNowplaying_index(random);
		return nowplaying_index ;
	}

	public List<Song> getSongLists() {
		return songLists;
	}


	public int getNowplaying_index() {
		return nowplaying_index;
	}

	public void setNowplaying_index(int i) {
		int count=nowPlayingListView.getCount();
		nowplaying_index=(i+count)%count;
	 
	 
		
		//通知ListView控件刷新
		 BaseAdapter adapter=(BaseAdapter) nowPlayingListView.getAdapter();
		 adapter.notifyDataSetChanged();
 
		 
		 //通知bottomActionBar更新
		 Intent intent=new Intent(BOTTOMACTIONBAR_UPDATE);
		 context.sendBroadcast(intent);
		 
		 //通知PlaySong界面更新
		 Intent intent2=new Intent(PlayingFragment.PLAYSONG_UPDATE);
		 context.sendBroadcast(intent2);
	}

	public ListView getNowPlayingListView() {
		return nowPlayingListView;
	}

	public void setNowPlayingListView(ListView nowPlayingListView) {
		
		this.nowPlayingListView = nowPlayingListView;
	
	}

	public Song getNowPlayingSong(){
		return (Song) nowPlayingListView.getAdapter().getItem(nowplaying_index);
	}
	
	
	//歌词界面操作状态
	public  static  class OperateState{
		public static String READLRC_SUCCESS="READLRC_SUCCESS";
		public static String READLRC_LISTNULL="READLRC_LISTNULL";
		public static String READLRC_ONLINE="READLRC_ONLINE";
		public static String READLRCFILE_FAIL="READLRCFILE_FAIL";
		public static String READLRCONLINE_FAIL="READLRCONLINE_FAIL";
	}
		
	public Song getSongByIndex(int index){
		return (Song) nowPlayingListView.getAdapter().getItem(index);
	}
}






本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5265129.html,如需转载请自行联系原作者
相关文章
|
29天前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
187 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
1月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
230 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
1月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
490 3
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
2月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
467 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
1月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
113 0
|
2月前
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
188 6
|
4月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
339 11
|
4月前
|
移动开发 Java 编译器
Kotlin与Jetpack Compose:Android开发生态的演进与架构思考
本文从资深Android工程师视角深入分析Kotlin与Jetpack Compose在Android系统中的技术定位。Kotlin通过空安全、协程等特性解决了Java在移动开发中的痛点,成为Android官方首选语言。Jetpack Compose则引入声明式UI范式,通过重组机制实现高效UI更新。两者结合不仅提升开发效率,更为跨平台战略和现代架构模式提供技术基础,代表了Android开发生态的根本性演进。
172 0
|
8月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
1928 77
|
5月前
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
260 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡

热门文章

最新文章