【发布时间】:2021-10-21 04:52:11
【问题描述】:
我正在尝试制作一个类似于媒体播放器克隆的应用程序。它正在从外部 SD 卡访问媒体文件。我已经使用回收器视图来显示歌曲列表,因此我正在使用我命名为 MusicAdapter.java 的适配器类来播放歌曲。我也在 Manifest 文件中添加了权限,但它仍然显示错误。我收到以下错误: java.io.FileNotFoundException:/storage/emulated/0/Download/Naruto - Main Theme.mp3:打开失败:EACCES(权限被拒绝)
public class MusicAdapter extends RecyclerView.Adapter<MusicAdapter.MusicHolder> {
ArrayList<Song> songs;
MediaPlayer mediaPlayer;
Context context;
public MusicAdapter(ArrayList<Song> songs,Context context) {
this.songs = songs;
this.context = context;
}
@NonNull
@Override
public MusicHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.music_item_design,parent,false);
return new MusicHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MusicHolder holder, int position) {
holder.song.setText(songs.get(position).title);
}
@Override
public int getItemCount() {
return songs.size();
}
class MusicHolder extends RecyclerView.ViewHolder{
ImageButton play,pause,stop;
TextView song;
public MusicHolder(@NonNull View itemView) {
super(itemView);
play = (ImageButton) itemView.findViewById(R.id.play_music);
pause = (ImageButton) itemView.findViewById(R.id.pause_music);
stop = (ImageButton) itemView.findViewById(R.id.stop_music);
song = (TextView) itemView.findViewById(R.id.song_name);
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Integer pos = getAbsoluteAdapterPosition();
startMusic(pos);
}
});
}
}
private boolean checkPermission(){
int result = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
private void startMusic(Integer pos) {
if(mediaPlayer==null){
mediaPlayer = new MediaPlayer();
}
try {
mediaPlayer.setDataSource(songs.get(pos).song_Url);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
private void pause(){
if(mediaPlayer!=null){
mediaPlayer.pause();
}
}
private void stop(){
stopPlayer();
}
private void stopPlayer(){
if(mediaPlayer!=null){
mediaPlayer.release();
mediaPlayer = null;
}
}
}
这是 MainActivity 文件代码 公共类 MainActivity 扩展 AppCompatActivity {
ArrayList<Song> songs = new ArrayList<>();
RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},111);
}else {
loadSongs();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==111&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
loadSongs();
}
}
private void loadSongs() {
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String select = MediaStore.Audio.Media.IS_MUSIC + "!=0";
Cursor cursor = getApplicationContext().getContentResolver().query(uri, null, select, null, null);
if(cursor!=null){
while (cursor.moveToNext()){
String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
String author = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
songs.add(new Song(title,author,url));
}
}
recyclerView.setAdapter(new MusicAdapter(songs,this));
}
【问题讨论】:
-
您没有在 ContentResolver.query() 方法中添加投影。基本上在投影中,您定义要检索的字段。这是强制性的。
标签: java android local-storage android-mediaplayer local