Music app框架设计及总结

作者 Chaoqian.chen总体上Music App分为UI界面、服务两个模块,其中关于音乐文件的播放都由服务负责,服务配合AIDL使用的,界面绑定服务后可以拿到服务里所有参数及状态进行UI刷新。A. 界面模块:1、主界面MusicMainActivity:主界面主要负责分类显示音乐文件,以及对音乐文件的各类操作。MusciAllFragment:显示所
摘要由CSDN通过智能技术生成

作者 Chaoqian.chen


总体上Music App分为UI界面、服务两个模块,其中关于音乐文件的播放都由服务负责,服务配合AIDL使用的,界面绑定服务后可以拿到服务里所有参数及状态进行UI刷新。

A. 界面模块:
1、主界面MusicMainActivity:


主界面主要负责分类显示音乐文件,以及对音乐文件的各类操作。

MusciAllFragment:显示所有单曲。


SingerFragment:根据歌手分类显示。


AlbumFragment:根据专辑分类显示。

RrecentlyPlayFragment:显示最近播放的歌曲

PlayListFragment:显示用户收藏、录音以及自己创建的播放列表。

2、音乐播放界面MusicPlayingActivity

主要负责展示具体某一首歌曲的详细信息以及播放操作等。


3、音乐搜索界面SearchMusicActivity

输入内容后自动从本地的音乐文件的音乐名,专辑名,歌手名去匹配,匹配后显示到搜索列表里。

4、音乐列表界面MusicListActivity

负责显示播放列表里的歌曲,跟单曲差不多。

5、编辑界面EditMusicActivity

批量编辑音乐文件,包括删除和批量添加到播放列表。

6、PlayingFromUriActivity

负责接收外来资源的播放界面,逻辑跟播放界面一样。


B. 服务模块:


启动主界面后绑定服务,所有界面在onResume里根据服务是否存在判断是否进行绑定,在onStop里根据通知栏是否存在判断是否进行解绑(因为很多时候写在onDestroy里执行不到解绑服务的,导致服务永生不死,不符合谷歌规范)。由于服务绑定的都是单个Activity,若结束当前绑定的Activity,服务则会自动解绑执行onUnbind方法。

为了让服务能一直播放音乐…所以调用服务播放音乐时,就会调用startService为当前服务进行续命,并显示通知栏。所以就算杀掉APP,服务也会继续后台播放,若关闭通知栏则调用stopSelf杀掉服务。若此时点击通知栏调出UI播放界面后(此时的服务是之前续命的服务,并没有绑定任何Activity),再关闭通知栏,则会先stopSelf再发送一个广播通知当前Activity进行重新绑定服务。


C. 具体实现:

进入界面后首先要做的就是扫描本地所有音乐文件:

String[] paths = new String[] {Environment.getExternalStoragePublicDirectory(

                         Environment.DIRECTORY_MUSIC).toString()};

                  // String[] paths = new

                  // String[]{Environment.getExternalStorageDirectory().toString()};

                  MediaScannerConnection.scanFile(c,paths, null, new OnScanCompletedListener() {

                                     @Override

                                     publicvoid onScanCompleted(String path, Uri uri) {

                                               ObservableManager.getInstance().setData(Constants.DATA_CHANGE_DELETE_SONGS);

                                              

                                     }

                            });

 

接着从媒体库拿各个Fragment的数据,如单曲:

Stringwhere = MediaStore.Audio.Media.IS_MUSIC + "=1";

       Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, where,

              null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);

 

拿到Cursor后转成你所需要的对象即可展示了:

List<MusicInfo>infos = new ArrayList<MusicInfo>();

       if (cursor == null) {

           return infos;

       }

       while (cursor.moveToNext()) {

           MusicInfo info = new MusicInfo();

           // 歌曲IDMediaStore.Audio.Media._ID

           long id;

           if (type == Constants.TYPE_PLAYLIST) {

              id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Playlists.Members.AUDIO_ID));

           } else {

              id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));

           }

 

           String title, artist;

           // 歌曲文件的路径MediaStore.Audio.Media.DATA

           String url = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));

           String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));

           // 歌曲的名称MediaStore.Audio.Media.TITLE

           title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));

           // 歌曲的歌手名: MediaStore.Audio.Media.ARTIST

           artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));

           String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));

           // 歌曲的总播放时长MediaStore.Audio.Media.DURATION

           long duration = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));

           // 歌曲文件的大小MediaStore.Audio.Media.SIZE

           long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));

           long artistsId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST_ID));

           long alb

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值