简体   繁体   中英

Mediaplayer not getting start in android

I am trying to make an app which is just like a clone of media players. It is accessing media files from external SD card. I have used recycler view to display song list and thereby I am using adapter class which I have named as MusicAdapter.java to play the song. I have added permissions as well in the Manifest file but still it is showing error. I am getting the following error: 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;
    }
}

}

Here is the MainActivity file code 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));
}

I bet your code will (may, if there is no other bugs) work on Android 9 and below, can you check this with some device or emulator?

Starting Android 11 there is a newScoped Storage feature preventing getting access to files outside your apps scope (dedicated folders especially for your app), BUT app can still use MediaStore API.

And you are using this API for obtaining file path, but due to scoped storage you can't access File directly (path of this file is out of scope of your app), so you have to use MediaStore API for retrieving content of this file. This is possible using ContentResolver and you may get an InputStream or 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

now note that there is a setDataSource method taking FileDescriptor , try that way

all above is just guessing, at first check your code on at most Android 9 (or Android 10 with requestLegacyExternalStorage flag and target at most 29) - no Scoped Storage yet, so you should be able to work with any (existing) File path, even out of scope of your app

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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