鸿蒙开发小应用-音乐播放器
话不多说,展示。
第一次进去会申请访问权限,点击“始终允许”
点击“始终允许”后退出一下,再次点击进入该应用会看到一首音乐Dream it Possible,因为模拟器上只有这一首主题曲,可以点击播放。
播放器内容包括:播放器名称,音乐名,音乐作曲家,背景图,三个控制播放/暂停,上一曲/下一曲的按钮。
开发导图
一:资源获取
权限申请
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
if (verifySelfPermission("ohos.permission.READ_MEDIA") != IBundleManager.PERMISSION_GRANTED) {
if (canRequestPermission("ohos.permission.READ_MEDIA")) {
// 是否可以申请弹框授权(首次申请或者用户未选择禁止且不再提示)
requestPermissionsFromUser(
new String[]{"ohos.permission.READ_MEDIA"}, MY_PERMISSIONS_REQUEST_RW);
} else {
new ToastDialog(this).setText("需要授予应用读取存储权限").setAlignment(LayoutAlignment.CENTER).show();
}
}
}
当权限可以申请时需要重写下面的方法,获取权限申请的结果
@Override
public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == MY_PERMISSIONS_REQUEST_RW) {// 匹配requestPermissions的requestCode
if (grantResults.length > 0
&& grantResults[0] == IBundleManager.PERMISSION_GRANTED) {
new ToastDialog(this).setText("所有权限已经被授予").setAlignment(LayoutAlignment.CENTER).show();
} else {
new ToastDialog(this).setText("所有权限已经被拒绝").setAlignment(LayoutAlignment.CENTER).show();
}
}
}
数据模型
一个音乐的实体类
public class MusicBean {
private int id;
private String title;
private String song;
private String data;
private String duration;
private String artist;
private String album;
构造方法,get,set方法省略
}
数据读取
数据读取需要做两件事1.通过访问外部存储的URL获取ResultSet
private ResultSet queryAvStore(Context context) {
ResultSet resultSet = null;
DataAbilityHelper helper = DataAbilityHelper.creator(context);
try {
resultSet = helper.query(AVStorage.Audio.Media.EXTERNAL_DATA_ABILITY_URI, null, null);
} catch (DataAbilityRemoteException e) {
e.printStackTrace();
}
return resultSet;
}
2.通过ResultSet获取到数据
private List<MusicBean> getMusicBeanList(Context context) {
ResultSet resultSet = queryAvStore(context);
List<MusicBean> musicBeans = new ArrayList<>();
while (resultSet.goToNextRow()) {
MusicBean musicBean = new MusicBean();
musicBean.setId(resultSet.getInt(resultSet.getColumnIndexForName(AVStorage.AVBaseColumns.ID)));
musicBean.setData(resultSet.getString(resultSet.getColumnIndexForName(AVStorage.AVBaseColumns.DATA)));
musicBean.setTitle(resultSet.getString(resultSet.getColumnIndexForName(AVStorage.AVBaseColumns.TITLE)));
musicBean.setDuration(new SimpleDateFormat("mm:ss").format(new Date(resultSet.getLong(resultSet.getColumnIndexForName(AVStorage.AVBaseColumns.DURATION)))));
musicBean.setSong(resultSet.getString(resultSet.getColumnIndexForName(AVStorage.AVBaseColumns.DISPLAY_NAME)));
musicBean.setArtist(resultSet.getString(resultSet.getColumnIndexForName("artist")));
musicBean.setAlbum(resultSet.getString(resultSet.getColumnIndexForName("album")));
musicBeans.add(musicBean);
}
return musicBeans;
}
二:UI界面
布局
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_parent"
ohos:orientation="vertical">
<ListContainer
ohos:id="$+id:music_bean_lc"
ohos:height="0vp"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:weight="1"
ohos:background_element="$media:background"/>
<DirectionalLayout
ohos:height="match_content"
ohos:width="match_parent"
ohos:background_element="#E6000000"
ohos:orientation="horizontal"
ohos:padding="5vp">
<DirectionalLayout
ohos:height="match_content"
ohos:width="0vp"
ohos:weight="1"
ohos:orientation="vertical"
ohos:layout_alignment="vertical_center">
<Text
ohos:id="$+id:bottom_music_name_tv"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="$string:music_name"
ohos:text_size="20fp"
ohos:text_color="$color:color_white"/>
<Text
ohos:id="$+id:bottom_music_artists_tv"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="$string:music_artist"
ohos:text_size="10fp"
ohos:text_color="$color:color_white"/>
</DirectionalLayout>
<Button
ohos:id="$+id:bottom_last_btn"
ohos:height="50vp"
ohos:width="50vp"
ohos:margin="10vp"
ohos:background_element="$graphic:ic_last"/>
<Button
ohos:id="$+id:bottom_play_btn"
ohos:height="50vp"
ohos:width="50vp"
ohos:margin="10vp"
ohos:background_element="$graphic:ic_play"/>
<Button
ohos:id="$+id:bottom_next_btn"
ohos:height="50vp"
ohos:width="50vp"
ohos:margin="10vp"
ohos:background_element="$graphic:ic_next"/>
</DirectionalLayout>
</DirectionalLayout>
ListContainer
@Override
public int getCount() {
return list == null ? 0 : list.size();
}
@Override
public Object getItem(int position) {
if (list != null && position >= 0 && position < list.size()) {
return list.get(position);
}
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
final Component cpt;
if (component == null) {
cpt = LayoutScatter.getInstance(abilitySlice).parse(ResourceTable.Layout_item_music_bean, null, false);
} else {
cpt = component;
}
MusicBean musicBean = list.get(i);
Text nameTv = (Text) cpt.findComponentById(ResourceTable.Id_music_name_tv);
nameTv.setText(musicBean.getTitle());
// Text dataTv = (Text) cpt.findComponentById(ResourceTable.Id_music_data_tv);
// dataTv.setText(musicBean.getSong());
Text durationTv = (Text) cpt.findComponentById(ResourceTable.Id_music_duration_tv);
durationTv.setText(musicBean.getDuration());
Text artistTv = (Text) cpt.findComponentById(ResourceTable.Id_music_artists_tv);
artistTv.setText(musicBean.getArtist() + "-" + musicBean.getAlbum());
return cpt;
}
}
三: 播放逻辑
List Item点击事件
private void initListContainer() {
ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_music_bean_lc);
list = getMusicBeanList(this);
MusicBeanProvider musicBeanProvider = new MusicBeanProvider(list, this);
listContainer.setItemProvider(musicBeanProvider);
listContainer.setItemClickedListener((listContainer1, component, i, l) -> {
MusicBean item = (MusicBean) listContainer1.getItemProvider().getItem(i);
currentPlayMusicPos = i;
musicNameTv.setText(item.getTitle());
musicArtistTv.setText(item.getArtist()+"-"+item.getAlbum());
playBtn.setBackground(new VectorElement(this,ResourceTable.Graphic_ic_pause));
try {
if (PlayManager.getInstance().play(new Source(DataAbilityHelper
.creator(component.getContext())
.openFile(Uri.appendEncodedPathToUri(AVStorage.Audio.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(item.getId())), "r")),0)) {
HiLog.info(hiLogLabel, "播放成功");
} else {
HiLog.info(hiLogLabel, "播放失败");
}
} catch (DataAbilityRemoteException | FileNotFoundException e) {
e.printStackTrace();
HiLog.info(hiLogLabel, "播放失败");
}
});
}
更新底部播放栏的信息,依据音频播成开发指导创建播放服务管埋PlayManager方法类,并在其内部音乐播放、香停、饮复等功能,以便在
Abilityslice中的调用。
底部控制栏
private int currentPlayMusicPos = -1;
当前播放索引为-1表示没有音乐在播放
private void playMusic(Context context){标签:播放器,牛角,鸿蒙,list,resultSet,musicBean,private,ohos,new From: https://blog.51cto.com/u_15244322/5950836
if(currentPlayMusicPos == -1){
new ToastDialog(context).setText("请从播放列表中选择歌曲").setAlignment(LayoutAlignment.CENTER).show();
}else{
if(PlayManager.getInstance().isPlaying()){
PlayManager.getInstance().pause();
playBtn.setBackground(new VectorElement(this,ResourceTable.Graphic_ic_play));
}else{
MusicBean item = list.get(currentPlayMusicPos);
play(item,context,PlayManager.getInstance().getAudioCurrentPosition());
}
}
}
private void nextMusic(Context context){
currentPlayMusicPos++;
if (currentPlayMusicPos >= list.size()) {
currentPlayMusicPos = 0;
}
MusicBean item = list.get(currentPlayMusicPos);
play(item,context,0);
}
private void lastMusic(Context context){
currentPlayMusicPos--;
if (currentPlayMusicPos < 0) {
currentPlayMusicPos = list.size() - 1;
}
MusicBean item = list.get(currentPlayMusicPos);
play(item,context,0);
}