手把手教你做音乐播放器(五)音乐列表的存储(下)

5.2 MusicService的配合

MusicService对外提供添加播放列表的接口,对内要管理PlayListContentProvider。它提供了下面的接口,

  • addPlayList():添加播放列表。这里添加列表应该有两种形式,一种是一次性添加多首音乐,一种是一次就添加一首音乐。

  • getPlayList():获取播放列表

播放列表要保存到一个数组里面,所以我们要创建一个mPlayList实现列表的保存,

public class MusicService extends Service {

    private List<MusicItem> mPlayList;
    private ContentResolver mResolver;

    @Override
    public void onCreate() {
        super.onCreate();

        //获取ContentProvider的解析器,避免以后每次使用的时候都要重新获取
        mResolver = getContentResolver();
        //保存播放列表
        mPlayList = new ArrayList<MusicItem>();
    }

}

5.2.1 添加播放列表

addPlayList()应该有两种形式,一次添加一首音乐和一次添加多首音乐。

public class MusicService extends Service {
    public class MusicServiceIBinder extends Binder {
        ......

        //一次添加多首音乐
       public void addPlayList(List<MusicItem> items) {
           addPlayListInner(items);
       }

        //一次添加一首音乐
       public void addPlayList(MusicItem item) {
           addPlayListInner(item);
       }
    }

    //一次添加多首音乐具体实现
    private void addPlayListInner(List<MusicItem> items) {

    }

    //一次添加一首音乐具体实现
    private void addPlayListInner(MusicItem item) {

    }

}
5.2.1.1 添加一首音乐
private void addPlayListInner(MusicItem item) {

    //判断列表中是否已经存储过该音乐,如果存储过就不管它
    if(mPlayList.contains(item)) {
      return;
    }

    //添加到播放列表的第一个位置
    mPlayList.add(0, item);
    //将音乐信息保存到ContentProvider中
    insertMusicItemToContentProvider(item);
}

//访问ContentProvider,保存一条数据
private void insertMusicItemToContentProvider(MusicItem item) {

    ContentValues cv = new ContentValues();
    cv.put(DBHelper.NAME, item.name);
    cv.put(DBHelper.DURATION, item.duration);
    cv.put(DBHelper.LAST_PLAY_TIME, item.playedTime);
    cv.put(DBHelper.SONG_URI, item.songUri.toString());
    cv.put(DBHelper.ALBUM_URI, item.albumUri.toString());
    Uri uri = mResolver.insert(PlayListContentProvider.CONTENT_SONGS_URI, cv);
}

判断mPlayList是否保存了音乐,需要对MusicItem做特别的处理:给它定义一个比较的准则–什么情况下两个相比较的内容是相同的。我们这个例子当中,应该是音乐的Uri相同,则认为两者相同。重写MusicItemequals()方法,当使用mPlayList.contains(item)判断的时候,会调用到这个重写的方法进行比较,

public class MusicItem {

    ......
    //重写MusicItem的equals()方法
    @Override
    public boolean equals(Object o) {
        MusicItem another = (MusicItem) o;

        //音乐的Uri相同,则说明两者相同
        return another.songUri.equals(this.songUri);
    }
}
5.2.1.2 添加多首音乐
private void addPlayListInner(List<MusicItem> items) {

    //清空数据库中的playlist_table
    mResolver.delete(PlayListContentProvider.CONTENT_SONGS_URI, null, null);
    //清空缓存的播放列表
    mPlayList.clear();

    //将每首音乐添加到播放列表的缓存和数据库中
    for (MusicItem item : items) {
        //利用现成的代码,便于代码的维护
        addPlayListInner(item);
    }
}

5.2.2 获取播放列表

为了获取播放列表在ContentProvider启动的时候,需要它将数据库中现有的列表,加载到mPlayList当中,

public class MusicService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();

        ......
        initPlayList();
        ......
    }

    private void initPlayList() {
        mPlayList.clear();

        Cursor cursor = mResolver.query(
                PlayListContentProvider.CONTENT_SONGS_URI,
                null,
                null,
                null,
                null);

        while(cursor.moveToNext()) {
            String songUri = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.SONG_URI));
            String albumUri = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.ALBUM_URI));
            String name = cursor.getString(cursor.getColumnIndex(DBHelper.NAME));
            long playedTime = cursor.getLong(cursor.getColumnIndexOrThrow(DBHelper.LAST_PLAY_TIME));
            long duration = cursor.getLong(cursor.getColumnIndexOrThrow(DBHelper.DURATION));
            MusicItem item = new MusicItem(Uri.parse(songUri), Uri.parse(albumUri), name, duration, playedTime);
            mPlayList.add(item);
        }

        cursor.close();
    }
}

之后在需要的时候,直接将mPlayList返回就可以了,

public class MusicService extends Service {
    public class MusicServiceIBinder extends Binder {
        ......

       public List<MusicItem> getPlayList() {
            return mPlayList;
        }
    }

}

5.3 主界面播放列表的添加

MusicListActivity有两种方式添加播放列表:

  1. 单击音乐项,将单首音乐添加到播放列表中;

  2. 长按音乐项,界面切换成ListView的多选模式,将多首音乐用替换掉方式添加到播放器当中;

这里我们先来实现单击音乐项的添加,多选模式我们放到后面单独的章节来介绍。

修改点击列表的监听器,通过MusicService提供的接口,把要添加的音乐交给MusicService处理,

//修改监听器
private AdapterView.OnItemClickListener mOnMusicItemClickListener = new AdapterView.OnItemClickListener() {

   @Override
   public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        MusicItem item = mMusicList.get(position);
        if(mMusicService != null) {
                //通过MusicService提供的接口,把要添加的音乐交给MusicService处理
                mMusicService.addPlayList(mMusicList.get(position));
        }
   }
};

接下来开始实现显示播放列表的功能,给MusicListActivity做一个Menu菜单,定义菜单的xml文件main_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:apps="http://schemas.android.com/apk/res-auto">
    <item
        android:title="@string/play_list"
        apps:showAsAction="always"
        android:icon="@mipmap/ic_playlist"
        android:id="@+id/play_list_menu"/>

</menu>

将菜单添加到MusicListActivity当中,

public class MusicListActivity extends AppCompatActivity {
    ......
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }
}

当用户点击该菜单的时候,弹出一个自带列表的对话框,将播放列表显示出来,

public class MusicListActivity extends AppCompatActivity {

    ......
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case R.id.play_list_menu: {
                //响应用户对菜单的点击,显示播放列表
                showPlayList();
            }
            break;

        }

        return true;
    }

    private void showPlayList() {

        final AlertDialog.Builder builder=new AlertDialog.Builder(this);
        //设置对话框的图标
        builder.setIcon(R.mipmap.ic_playlist);
        //设计对话框的显示标题
        builder.setTitle(R.string.play_list);

        //获取播放列表,把播放列表中歌曲的名字取出组成新的列表
        List<MusicItem> playList = mMusicService.getPlayList();
        ArrayList<String> data = new ArrayList<String>();
        for(MusicItem music : playList) {
            data.add(music.name);
        }
        if(data.size() > 0) {
            //播放列表有曲目,显示音乐的名称
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data);
            builder.setAdapter(adapter, null);
        }
        else {
            //播放列表没有曲目,显示没有音乐
            builder.setMessage(getString(R.string.no_song));
        }

        //设置该对话框是可以自动取消的,例如当用户在空白处随便点击一下,对话框就会关闭消失
        builder.setCancelable(true);

        //创建并显示对话框
        builder.create().show();
    }
}

/*******************************************************************/
* 版权声明
* 本教程只在CSDN安豆网发布,其他网站出现本教程均属侵权。

*另外,我们还推出了Arduino智能硬件相关的教程,您可以在我们的网店跟我学Arduino编程中购买相关硬件。同时也感谢大家对我们这些码农的支持。

*最后再次感谢各位读者对安豆的支持,谢谢:)
/*******************************************************************/

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
当然!我很乐意手把手教你如何设置 RAID 1。RAID 1是一种数据冗余技术,可以将数据同时写入两个或多个硬盘驱动器,以提供数据的备份和冗余。 以下是设置 RAID 1 的步骤: 1. 确保你有两个相同容量的硬盘驱动器。RAID 1需要至少两个硬盘驱动器才能工作。 2. 将两个硬盘驱动器连接到计算机。可以使用SATA或者SAS接口连接硬盘驱动器。确保硬盘驱动器正常工作且被计算机识别。 3. 开机并进入计算机的 BIOS 设置。通常,在计算机启动时按下 DEL、F2、F10 或者 ESC 键可以进入 BIOS 设置。 4. 在 BIOS 设置中,找到存储设备或者硬盘驱动器设置选项。不同的计算机厂商和型号有所不同,因此具体名称可能会有所不同。 5. 在存储设备设置中,找到 RAID 设置选项。选择 RAID 1 或者镜像模式。 6. 创建一个新的 RAID 数组。选择两个硬盘驱动器作为 RAID 1 数组的成员。 7. 配置 RAID 1 数组的设置。可以选择使用整个硬盘驱动器容量,或者选择一部分容量作为 RAID 1 数组。 8. 保存设置并退出 BIOS 设置。计算机将重新启动。 9. 在操作系统中配置 RAID 1 数组。具体的操作方式取决于你使用的操作系统。在大多数操作系统中,可以在磁盘管理工具中找到 RAID 1 数组,并将其格式化为文件系统(如NTFS或者EXT4)。 10. 现在,你已经成功设置了 RAID 1!计算机会将数据同时写入两个硬盘驱动器,以提供数据冗余和备份。 请注意,设置 RAID 1 可能会使一部分硬盘容量无法使用,因为其中一个硬盘驱动器用于存储冗余数据。另外,RAID 1 只提供了数据冗余和备份的功能,并不能提高读写性能。 希望这些步骤对你有帮助!如果你还有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值