我是靠谱客的博主 尊敬钻石,最近开发中收集的这篇文章主要介绍HarmongOS音乐播放器开发示例教程前言1. 所需知识和最终效果2. 资源获取3. UI布局4. 播放逻辑,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
HarmongOS音乐播放器开发示例教程
- 前言
- 完整项目代码链接[GMusic-HarmongOS-Samples](https://github.com/SakurajimaMaii/GMusic-HarmongOS-Samples)欢迎⭐和fork
- 对应BiliBili视频[鸿蒙开发教程之音乐软件](https://www.bilibili.com/video/BV1z5411M7WU)
- 1. 所需知识和最终效果
- 2. 资源获取
- 2.1 权限申请
- 2.1.1 在config.json文件中的“reqPermissions”字段中声明所需要的权限。
- 2.1.2 在Ability中动态申请
- 2.2 数据模型
- 2.3 数据读取
- 2.3.1 通过外部存储的Uri来获取对应的ResultSet
- 2.3.2 通过ResultSet获取对应的音频对象
- 3. UI布局
- 3.1 主页面布局
- 3.2 音乐布局
- 4. 播放逻辑
- 4.1 列表点击事件的设置
- 4.2 底部播放控件的设置
- 4.2.1 playMusic()函数
- 4.2.2 lastMusic()函数
- 4.2.3 nextMusic()函数
- 4.2.4 play()函数
前言
完整项目代码链接GMusic-HarmongOS-Samples欢迎⭐和fork
对应BiliBili视频鸿蒙开发教程之音乐软件
1. 所需知识和最终效果
2. 资源获取
2.1 权限申请
2.1.1 在config.json文件中的“reqPermissions”字段中声明所需要的权限。
2.1.2 在Ability中动态申请
- 申请对应权限
@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();
}
}
}
2.2 数据模型
声明对应的音乐对象
public class MusicBean {
private int id;
private String title;
private String song;
private String data;
private String duration;
private String artist;
private String album;
public MusicBean() {
}
/**
* @param id music_id
* @param title music_name
* @param song
* @param data music_path
* @param duration music_duration
* @param artist music_artist
*/
public MusicBean(int id, String title, String song, String data, String duration,String artist,String album) {
this.id = id;
this.title = title;
this.song = song;
this.data = data;
this.duration = duration;
this.artist = artist;
this.album = album;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSong() {
return song;
}
public void setSong(String song) {
this.song = song;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getDuration() {
return duration;
}
public void setDuration(String duration) {
this.duration = duration;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
}
2.3 数据读取
2.3.1 通过外部存储的Uri来获取对应的ResultSet
/**
* @param context Context
* @return
* If you want to get information about AVStorage.Audio.Media, please refer to:
* https://developer.harmonyos.com/cn/docs/documentation/doc-references/avstorage_audio_media-0000001054678942
* If you want to get information about this function, please refer to:
* https://developer.harmonyos.com/cn/docs/documentation/doc-guides/tv-media-playback-0000001050714866
*/
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.3.2 通过ResultSet获取对应的音频对象
关于 artist 和 album 字段的获取可以参考文章HarmongOS音频开发之音频信息获取(以获取艺术家为例)
/**
* @param context Context
* @return
* get playlist
* If you want to get information about AVStorage.AVBaseColumns.ID or others, please refer to:
* https://developer.harmonyos.com/cn/docs/documentation/doc-references/avstorage_avbasecolumns-0000001054358919#ZH-CN_TOPIC_0000001054358919__DATA
*/
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;
}
3. UI布局
3.1 主页面布局
主页面布局主要采用了DirectionalLayout布局,如果你想获取对应的布局信息,可以参考链接DirectionalLayout布局,以下是ability_main.xml布局
<?xml version="1.0" encoding="utf-8"?>
<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>
3.2 音乐布局
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_content"
ohos:width="match_parent"
ohos:padding="10vp"
ohos:orientation="horizontal">
<DirectionalLayout
ohos:height="match_content"
ohos:width="0vp"
ohos:weight="3"
ohos:orientation="vertical">
<Text
ohos:id="$+id: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: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>
<Text
ohos:id="$+id:music_duration_tv"
ohos:height="match_content"
ohos:width="match_content"
ohos:text="$string:music_duration"
ohos:text_size="10fp"
ohos:layout_alignment="right|bottom"
ohos:text_color="$color:color_white"/>
</DirectionalLayout>
4. 播放逻辑
4.1 列表点击事件的设置
listContainer.setItemClickedListener((listContainer1, component, i, l) -> {
//get music object
MusicBean item = (MusicBean) listContainer1.getItemProvider().getItem(i);
//update some information
currentPlayMusicPos = i;
musicNameTv.setText(item.getTitle());
musicArtistTv.setText(item.getArtist()+"-"+item.getAlbum());
//update the button image
//Regarding this execution statement, I hope you refer to the link below
//https://blog.csdn.net/weixin_43699716/article/details/117448709?spm=1001.2014.3001.5501
playBtn.setBackground(new VectorElement(this,ResourceTable.Graphic_ic_pause));
//play the music
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, "播放失败");
}
});
4.2 底部播放控件的设置
在这里用到的PlayManager() 类你可以在链接音乐播放器开发指导
中获取详情
playBtn.setClickedListener(component -> playMusic(component.getContext()));
lastBtn.setClickedListener(component -> lastMusic(component.getContext()));
nextBtn.setClickedListener(component -> nextMusic(component.getContext()));
4.2.1 playMusic()函数
private void playMusic(Context context){
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());
}
}
}
4.2.2 lastMusic()函数
private void lastMusic(Context context){
currentPlayMusicPos--;
if (currentPlayMusicPos < 0) {
currentPlayMusicPos = list.size() - 1;
}
MusicBean item = list.get(currentPlayMusicPos);
play(item,context,0);
}
4.2.3 nextMusic()函数
private void lastMusic(Context context){
currentPlayMusicPos--;
if (currentPlayMusicPos < 0) {
currentPlayMusicPos = list.size() - 1;
}
MusicBean item = list.get(currentPlayMusicPos);
play(item,context,0);
}
4.2.4 play()函数
private void play(MusicBean musicBean,Context context,int time){
musicNameTv.setText(musicBean.getTitle());
musicArtistTv.setText(musicBean.getArtist()+"-"+musicBean.getAlbum());
try {
if (PlayManager.getInstance().play(new Source(DataAbilityHelper
.creator(context)
.openFile(Uri.appendEncodedPathToUri(AVStorage.Audio.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(musicBean.getId())),"r")),time)) {
HiLog.info(hiLogLabel, "播放成功");
playBtn.setBackground(new VectorElement(this,ResourceTable.Graphic_ic_pause));
} else {
HiLog.info(hiLogLabel, "播放失败");
}
} catch (DataAbilityRemoteException | FileNotFoundException e) {
e.printStackTrace();
HiLog.info(hiLogLabel, "播放失败");
}
}
最后
以上就是尊敬钻石为你收集整理的HarmongOS音乐播放器开发示例教程前言1. 所需知识和最终效果2. 资源获取3. UI布局4. 播放逻辑的全部内容,希望文章能够帮你解决HarmongOS音乐播放器开发示例教程前言1. 所需知识和最终效果2. 资源获取3. UI布局4. 播放逻辑所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复