[英]Mediaplayer not getting start in android
我正在尝试制作一个类似于媒体播放器克隆的应用程序。 它正在从外部 SD 卡访问媒体文件。 我使用回收器视图显示歌曲列表,因此我使用适配器 class,我将其命名为 MusicAdapter.java 来播放歌曲。 我也在清单文件中添加了权限,但它仍然显示错误。 我收到以下错误:java.io.FileNotFoundException: /storage/emulated/0/Download/Naruto - Main Theme.mp3: open failed: EACCES (Permission denied)
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 文件代码 public class MainActivity extends 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));
}
我打赌你的代码将(可能,如果没有其他错误)在 Android 9 及以下版本上工作,你能用一些设备或模拟器检查一下吗?
从 Android 11 开始,有一个新的Scoped Storage功能可以防止访问应用程序外部的文件 scope(专门为您的应用程序准备的文件夹),但应用程序仍然可以使用 MediaStore API。
并且您正在使用此 API 获取文件路径,但由于范围存储,您无法直接访问File
(此文件的路径不在您应用程序的 scope 中),因此您必须使用MediaStore
API 来检索此文件的内容. 这可以使用ContentResolver
并且您可以获得InputStream
或FileDescriptor
InputStream is = contentResolver.openInputStream(uri); // uri got from `MediaStore`
// or
FileDescriptor fd = contentResolver.openFileDescriptor(uri, "r").getFileDescriptor();
// above "r" means you only want to read this file
现在请注意,有一个采用FileDescriptor
的setDataSource
方法,请尝试这种方式
以上只是猜测,首先检查你的代码最多 Android 9(或 Android 10 带有requestLegacyExternalStorage标志并且目标最多 29) - 还没有 Scoped Storage,所以你应该能够使用任何(现有的) File
路径,甚至超出您应用的 scope
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.