Mediaplayer没有在android中启动

Posted

技术标签:

【中文标题】Mediaplayer没有在android中启动【英文标题】:Mediaplayer not getting start in android 【发布时间】: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() 方法中添加投影。基本上在投影中,您定义要检索的字段。这是强制性的。 【参考方案1】:

我敢打赌,您的代码(如果没有其他错误,可能会)在 android 9 及更低版本上运行,您可以使用某些设备或模拟器进行检查吗?

从 Android 11 开始,有一个新的 Scoped Storage 功能可防止访问您的应用范围之外的文件(专用文件夹,尤其是您的应用),但应用仍然可以使用 MediaStore API。

您正在使用此 API 获取文件路径,但由于范围存储,您无法直接访问 File(此文件的路径超出您的应用范围),因此您必须使用 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

现在注意有一个setDataSource方法采用FileDescriptor,试试那个方法

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

【讨论】:

我尝试使用 FileDescriptor 和 Inputstream 但他们给出了错误。我不知道如何解决 contentResolver 错误问题。 请任何人。我需要帮助。 您最多检查过 Android 9 设备吗? 是的,我已经检查过了。我已经解决了这个错误。我会尽快分享我为消除错误所做的工作。 对不起,我回复晚了。因为某个节日,我很忙。我通过在应用程序标记下的 android 清单文件中添加此行 android:requestLegacyExternalStorage="true" 解决了以下错误。

以上是关于Mediaplayer没有在android中启动的主要内容,如果未能解决你的问题,请参考以下文章

Android MediaPlayer 不播放

无法使用 MediaPlayer 对象在 Android 中播放许多音频文件

如何在 android 的 mediaplayer 中停止和播放新歌曲?

Android 音频开发之 MediaPlayer

在 Android 中是不是可以录制 MediaPlayer 播放的内容?

控制 Android MediaPlayer 的播放速度