Select a music file to play with MediaPlayer

☆樱花仙子☆ 提交于 2019-11-30 19:09:54

问题


I'm new in android programming and now i get a problem with my app. I intend to code a MediaPlayer application with feature: select a file from storage using intent then start playing that file. I use "MediaPlayer.create(context, uri)" method but currently i got error

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();
    }
}

And it throws NullPointerException in "mMediaPlayer = MediaPlayer.create(this, uri);". It has problem with the uri. Could anyone guild me the way?


Thanks Ilango j, i revised my code then now i could select and play a music file. But my expecteation is select file then only play after click on Play/Pause button (with progress bar) but i got new NullPointerException with my buttonClick

@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();
    }
}

Could you please give an advice?


回答1:


First start activity to pic media file from sd card. Replace the following code

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);
        }
    }); 

Then in add the following code in onActivityResult

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

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

And call the below method to create media player and play selected audio file.

   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();
          }
    }



回答2:


Looking at the source code of the creation of the MediaPlayer, it looks like this :

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;
    }

So in your case the error may be that the URI you pass in parameter is wrong or malformed, so the create method returns null. Check if the URI is correct when you create your mediaPlayer object.

Also I saw this line :

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

Don't use == to compare content of Strings. Use .equals() instead :

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



回答3:


If someone have difficulties with this question as I had, I did some fixes to the answers above, and this snippet should work:

private  final int SELECT_PICTURE = 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);
}


来源:https://stackoverflow.com/questions/17042308/select-a-music-file-to-play-with-mediaplayer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!