大二下学期的时候做的一个项目,一个在线音乐播放器
UI素材和布局都参考了网易云音乐,客户端使用的是Android编写的,而服务器方面则是自己使用Java Socket,并自定义服务器与客户端之间的通讯协议~(安全方面就比较残念) 完成的功能也比较少~ 本人也只是个小菜鸡(:з)∠)
效果截图如下:
1. 运行app进入登陆注册界面。
2.进入注册界面,输入用户名和密码
3.注册成功,再看看服务器那边的信息,和数据库
效果截图如下:
1. 点击主界面右上角的搜索按钮,进入搜索栏,在搜索栏输入要查找的歌曲,或者歌手,或者专辑。
示例 输入专辑3L,点击搜索,得到结果
2. 再看看服务器方面的信息
服务器接受到了请求,在数据库中去寻找歌曲。(歌曲数据库,在每次启动数据库的时候进行导入)
效果截图:
1.点击搜索的结果返回主界面进行播放,及播放完成状态
A) 在下载的时候,先检测文件是否存在于本地,若存在则不做任何操作,并Toast提示用户,文件以及存在。
B) 若文件不存在,则先从本地数据库中的表cacheFIle中查找是否存在该文件的缓存文件,如果存在,则把该文件copy到默认下载目录中,从表中删除该歌曲的信息
C) 若没有缓存,则直接向服务器请求文件,向服务器发送Download请求,服务器返回文件,客户端对文件进行读写,保存在默认目录下
D) BC操作之后,把下载好的歌曲保存在本地数据库中的表dldFile中,以便之后播放本地音乐的时候使用。
效果截图:
1. 再次进入搜索界面输入3l得到查询结果,点击更多详细信息按钮(选项最右边),会得到一个popupWindow弹窗(里面只实现了下载功能,其余的没有实现);点击下载
可以看到,提示信息已经添加到下载队列,因为刚才已经进行了缓存,所以这次下载是直接从缓存目录中去读取文件,转到默认下载目录中。
再检索一首没有缓存的歌曲 示例ao,点击下载
在logcat中显示文件来自服务器。
2.查看默认下载目录文件夹,和数据库文件LocalDatabase
效果截图:
点击主界面目录里面的本地音乐,进入本地音乐节目,可以看到显示了刚才下载的2首歌曲。
跟着点击歌曲,返回主界面,可以看到主界面的播放器已经在播放选中的歌曲。
首先介绍自定义的协议:Test, Login, Register, Download, Search, 后四种已经介绍过,第一个是用来测试网络是否通畅的,若无法连同网络,则提示用户当前网络不可用。
服务器自定义了一些错误代码:000,001,002,003; 100,101,102.等等。也可以不用理会,客户端和服务器端彼此都知道的东西。
先从简单的登陆和注册界面开始,用到的都是简单的UI,没什么好说。除了记住密码的功能比较有技巧,记录密码就是根据checkBox的状态,判定是否把账户密码写到本地的sharePreference文件中,再根据里面记录的内容,判定应用开启的时候是否装载进来。还有的是,登陆和注册都涉及到了socket编程,Android里面是不允许在主线程中去运行网络连接的,所以要用到多线程。
然后是主界面,主界面要用到ListView,关于ListView就不得不吐槽了,这是一个用得最多,也是最难的一个UI,在做这个APP的时候,经常用到,吃了不少苦。使用ListView首先要有一个context,用于承载ListView的内容,还有一个ListView里面每个选项的布局,还有一个List数组,装了选项布局里面需要的内容。仿照云音乐的界面,做出类一个listView,不过下面的收藏歌单,实在是没有精力和能力去实现,所以也没多加考虑。先为本地音乐,创建一个activity,稍后再去实现它。目前优先解决搜索功能。实现标题导航,要用到actionbar,一个在平时用的很多的标题栏。创建一个搜索按钮searchView,为其注册监听器,当输入内容的时候启用另一个活动 SearchActivity显示查询的结果。
上面的那些都还是比较简单的,不过ListView以及布局等等问题,在做项目的过程中确实占用了很多的时间。搜索做完了,就轮到播放了,一个最为头疼了问题,在这个播放问题上,耗费了将近1个星期的时间,真的很不容易。
播放要怎么播放?翻了翻书,哦,用MediaPlayer,这只是简单的提供了一些方法和介绍了它的生命周期而已,并没有给予我什么启发。
首先要实现在线播放,在线播放究竟是个什么原理,起初是想直接把它下下来,然后播放,敷衍一下就算了,但是一想到,你点一首歌,用户要等半天才放,这是不是不太合理,于是就在茫茫代码中去寻找办法,网上的在线播放,很多都是直接丢一个uri然后通过调用MediaPlayer自带的serDataSourece方法进行播放,毫无技术性可言。不过终于让我发现了一份差不多符合自己想法的资料,自己好像发现了些什么。首先在线播放其实也是下载,不过它是下一点,播放一点,思路大概如下:
downloadingFile为正在下载的文件,playingFile为正在播放的文件,bufferFile为缓存文件
downloadCom为下载完成。播放要求为:文件大小>512k
getCurPos()为获取当前播放进度,getDuration()为当前MP3时长 –>为复制操作
看得出来,这里涉及到访问网络操作,所以把它丢到多线程中,但是播放要更新progressbar进度条,这又迎来了一个难题,再查资料,在子线程更新UI要用到异步机制,使用handler就可以解决这个问题。其实,这个播放条本该显示在所有活动之上的,但是当初决定了用activity,要改成fragment就要全改,也试过全改了,但是还是失败了,换成碎片以后标题栏又成了一个问题,之前在fragment和activity之间折腾了2-3天,还是改回activity,改回activity后又想着让播放条作为一个baseactivity让所有activity继承它,但是这种办法又遇到各种问题,又改了回来。跟着无意间看到Service,本身音乐播放应该是一个Service才对了,这才是一个正确的方向!!于是又接着去尝试Service,Service可以与很多活动通信,而Service始终还是一个,这就很好的解决了一个activity和另一个activity之间线程的管理问题。但是神奇的事情发生了,在Service中更新UI失败了,不过按照网上的说法应该是可以的,不过时间已经不允许我去纠结了,所以还是打回原形。到处碰壁那种辛酸真的很难受。最终发现了一个很强的东西,广播!!广播机制实现了非activity类和activity的通信,只需要一个广播就可以调用activity里面的方法, 例如更新UI!!可惜已经到了deadline了,也由于这个项目,落下了很多东西,半个月来几乎每天都在做这个项目,真的不容易。不过对Android的了解更近一层了。因为亲身实践了,亲身去跳坑,爬坑,虽然满身伤痕,不过每当实现一个功能的时候,心里是欣喜不已的,还兴冲冲的分享给身边的舍友。这种喜悦感是难以言喻的。
在做项目的时候,有查bug的痛苦,也有取得成就的喜悦,悲欢参半,收获颇丰。不过还是有很多的遗憾,如果当初知道fragment,当初知道Service,当初知道broadcast
没有人指导跳进了很多坑,不过跌跌撞撞让我明白,有很多东西不亲身去经历是不知道那是多么的难。我们平时用的那么顺手的app开发起来是那么的难。如果有下次,我可能会做得更好。
Android客户端
Java服务器