选择要使用 MediaPlayer 播放的音乐文件

Posted

技术标签:

【中文标题】选择要使用 MediaPlayer 播放的音乐文件【英文标题】:Select a music file to play with MediaPlayer 【发布时间】:2013-06-07 04:42:59 【问题描述】:

我是 android 编程新手,现在我的应用程序出现问题。我打算编写具有以下功能的 MediaPlayer 应用程序:使用意图从存储中选择一个文件,然后开始播放该文件。我使用“MediaPlayer.create(context, uri)”方法,但目前出现错误

protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //openFile();
    Button openFile = (Button) this.findViewById(R.id.ButtonOpen);
    openFile.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v) 
            Intent chooseFile;
            Intent intent;
            chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
            chooseFile.setType("file/*");
            intent = Intent.createChooser(chooseFile, "Choose a file");
            startActivityForResult(intent, ACTIVITY_CHOOSE_FILE);

            Uri uri = intent.getData();
            initViews(uri);
        
    ); 



private void initViews(Uri uri) 
    mButtonPlayStop = (Button) findViewById(R.id.ButtonPlayStop);
    mButtonPlayStop.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v) 
            buttonClick();
        
    );

    mMediaPlayer = MediaPlayer.create(this, uri);



private void starPlayProgressUpdater() 
    mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());

    if (mMediaPlayer.isPlaying()) 
        Runnable notification = new Runnable() 

            @Override
            public void run() 
                starPlayProgressUpdater();
            
        ;
        mHandler.postDelayed(notification, 1000);
     else 
        mMediaPlayer.pause();
        mButtonPlayStop.setText(getString(R.string.play_str));
        mSeekBar.setProgress(0);
    


private void buttonClick() 
    if (mButtonPlayStop.getText() == getString(R.string.play_str)) 
        mButtonPlayStop.setText(getString(R.string.pause_str));
        try 
            mMediaPlayer.start();
            starPlayProgressUpdater();              
         catch (IllegalStateException e) 
            mMediaPlayer.pause();
        
     else 
        mButtonPlayStop.setText(getString(R.string.play_str));
        mMediaPlayer.pause();
    

它会在“mMediaPlayer = MediaPlayer.create(this, uri);”中抛出 NullPointerException。 uri有问题。谁能给我指路?


感谢 Ilango j,我修改了代码,现在我可以选择并播放音乐文件。但我的期望是选择文件然后仅在单击播放/暂停按钮(带进度条)后播放,但我的 buttonClick 得到了新的 NullPointerException

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mContext = (Context) getApplicationContext();

    Button openFile = (Button) this.findViewById(R.id.ButtonOpen);
    openFile.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v)        
            initView();
        
    ); 



private void initView() 
    mButtonPlayStop = (Button) findViewById(R.id.ButtonPlayStop);
    mButtonPlayStop.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v) 
            buttonClick();
        
    );

    Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(intent, 10);


    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 

    if (requestCode == RESULT_OK && requestCode == 10) 
        Uri uri = data.getData();

        mMediaPlayer = MediaPlayer.create(mContext, uri);

        mSeekBar = (SeekBar) findViewById(R.id.SeekBar01);
        mSeekBar.setMax(mMediaPlayer.getDuration());
        mSeekBar.setOnTouchListener(new OnTouchListener() 

            @Override
            public boolean onTouch(View v, MotionEvent event) 
                seekChange(v);
                return false;
            
        );         
    
   

private void starPlayProgressUpdater() 
    mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());

    if (mMediaPlayer.isPlaying()) 
        Runnable notification = new Runnable() 

            @Override
            public void run() 
                starPlayProgressUpdater();
            
        ;
        mHandler.postDelayed(notification, 1000);
     else 
        mMediaPlayer.pause();
        mButtonPlayStop.setText(getString(R.string.play_str));
        mSeekBar.setProgress(0);
    


private void seekChange(View v) 
    if (mMediaPlayer.isPlaying()) 
        SeekBar sb = (SeekBar) v;
        mMediaPlayer.seekTo(sb.getProgress());
    


private void buttonClick() 
    if (mButtonPlayStop.getText().equals(getString(R.string.play_str))) 
        mButtonPlayStop.setText(getString(R.string.pause_str));
        try 
            mMediaPlayer.start();
            starPlayProgressUpdater();              
         catch (IllegalStateException e) 
            mMediaPlayer.pause();
        
     else 
        mButtonPlayStop.setText(getString(R.string.play_str));
        mMediaPlayer.pause();
    

你能给个建议吗?

【问题讨论】:

【参考方案1】:

首先开始活动以从 sd 卡中获取 pic 媒体文件。替换以下代码

Button openFile = (Button) this.findViewById(R.id.ButtonOpen);
    openFile.setOnClickListener(new OnClickListener() 

        @Override
        public void onClick(View v) 
           Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, 10);
        
    ); 

然后在onActivityResult

中添加如下代码
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) 

          if(resultCode == RESULT_OK && requestCode == 10)
                Uri uriSound=data.getData();
                play(this, uriSound); 
          
      

并调用以下方法创建媒体播放器并播放选定的音频文件。

   private void play(Context context, Uri uri) 

        try 
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(context, uri);         
            mp.start();
           catch (IllegalArgumentException e) 
          // TODO Auto-generated catch block
             e.printStackTrace();
           catch (SecurityException e) 
          // TODO Auto-generated catch block
             e.printStackTrace();
           catch (IllegalStateException e) 
          // TODO Auto-generated catch block
             e.printStackTrace();
           catch (IOException e) 
          // TODO Auto-generated catch block
             e.printStackTrace();
          
    

【讨论】:

感谢您的指导,我根据您的评论修改了我的代码。但我的期望是“从存储中选择音乐文件,然后使用播放按钮开始/暂停解码”。现在我的 buttonClick 面临新错误 这里的错字...应该是... if(resultCode == RESULT_OK 如果我想选择多个文件怎么办,他们的多选对话框有什么方式吗?【参考方案2】:

如果有人像我一样在这个问题上遇到困难,我对上面的答案做了一些修复,这个 sn-p 应该可以工作:

private  final int SELECT_MUSIC = 1;

public void pickMusic() 
    Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(i,SELECT_MUSIC);


public void onActivityResult(int requestCode, int resultCode, Intent data) 
    if (resultCode == RESULT_OK) 
        if (requestCode == SELECT_MUSIC)
            Uri selectedMusicUri = data.getData();
            if (selectedMusicUri != null)
                String pathFromUri = getRealPathFromURI(this, selectedMusicUri);
                MediaPlayer mp = new MediaPlayer();
                try 
                    mp.setDataSource(this, Uri.parse(pathFromUri));
                    mp.prepare();
                    mp.start();

                 catch (IOException e) 
                    e.printStackTrace();
                
            
        
    



private String getRealPathFromURI(Context context, Uri contentUri) 
    String[] projection =  MediaStore.Audio.Media.DATA ;
    CursorLoader loader = new CursorLoader(context, contentUri, projection, null, null, null);
    Cursor cursor = loader.loadInBackground();
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);

【讨论】:

【参考方案3】:

看MediaPlayer的创建源码,是这样的:

public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder) 

        try 
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(context, uri);
            if (holder != null) 
                mp.setDisplay(holder);
            
            mp.prepare();
            return mp;
         catch (IOException ex) 
            Log.d(TAG, "create failed:", ex);
            // fall through
         catch (IllegalArgumentException ex) 
            Log.d(TAG, "create failed:", ex);
            // fall through
         catch (SecurityException ex) 
            Log.d(TAG, "create failed:", ex);
            // fall through
        

        return null;
    

因此,在您的情况下,错误可能是您传入参数的 URI 错误或格式错误,因此 create 方法返回 null。在创建 mediaPlayer 对象时检查 URI 是否正确。

我也看到了这一行:

if (mButtonPlayStop.getText() == getString(R.string.play_str))

不要使用== 来比较字符串的内容。请改用.equals()

if (mButtonPlayStop.getText().equals(getString(R.string.play_str)))

【讨论】:

感谢您的评论,我知道了

以上是关于选择要使用 MediaPlayer 播放的音乐文件的主要内容,如果未能解决你的问题,请参考以下文章

android 使用MediaPlayer播放音乐要添加的权限是啥?

MediaPlayer音乐播放器上一首下一首播放停止自动下一首进度条

多媒体(音乐视频播放器,相机)

MediaPlayer 仅在调试模式下播放音乐文件(Android)

封装MediaPlayer实现网易云音乐播放器

Qt Quick 多媒体 - 播放音乐和视频