繁体   English   中英

媒体播放器无法在 android 中启动

[英]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并且您可以获得InputStreamFileDescriptor

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

现在请注意,有一个采用FileDescriptorsetDataSource方法,请尝试这种方式

以上只是猜测,首先检查你的代码最多 Android 9(或 Android 10 带有requestLegacyExternalStorage标志并且目标最多 29) - 还没有 Scoped Storage,所以你应该能够使用任何(现有的) File路径,甚至超出您应用的 scope

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM