Я работал над приложением, которое использует песню, выбранную пользователем из внутреннего хранилища устройства.При сохранении URI выбранного аудиофайла в общих настройках звук будет загружаться и воспроизводиться, когда приложение все еще работает (включая переключение между действиями), однако, как только приложение перезапускается, возникает проблема создания медиаплеера с использованиемто же самое неизменное uri.
Я потратил много времени в поисках способа заставить это работать, поэтому любая помощь будет высоко ценится.
Был подобный вопрос, заданный без ответанесколько лет назад ... Сохранение аудиоконтента Uri в sharedpreference для воспроизведения позже
У меня есть код ниже части селектора песен приложения:
JAVA:
package com.example.android.songselector;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
MediaPlayer player;
SharedPreferences sharedPrefs;
SharedPreferences.Editor prefsEditor;
SeekBar seekBar;
ImageButton playBtn;
Button chooseBtn;
Button stopBtn;
Uri selectedSong;
String mySong;
int mProgress;
Runnable runnable;
Handler mainHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPrefs = getSharedPreferences("PREFS", MODE_PRIVATE);
mySong = sharedPrefs.getString("song", "");
if (!mySong.equals("")) {
selectedSong = Uri.parse(mySong);
}
playBtn = findViewById(R.id.play_button);
chooseBtn = findViewById(R.id.choose_song_button);
stopBtn = findViewById(R.id.stop_button);
seekBar = findViewById(R.id.seek_bar);
mainHandler = new Handler();
if (selectedSong != null) {
player = MediaPlayer.create(MainActivity.this, selectedSong);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
seekBar.setMax(player.getDuration());
player.seekTo(0);
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
player.start();
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean input) {
if (input) {
if (player != null) {
player.seekTo(progress);
}
mProgress = progress;
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
else {
chooseSong();
if(selectedSong != null) {
player = MediaPlayer.create(MainActivity.this, selectedSong);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
seekBar.setMax(player.getDuration());
player.seekTo(0);
}
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean input) {
if(input){
if(player != null){
player.seekTo(progress);
}
mProgress = progress;
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
playBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectedSong == null){
chooseSong();
}
else {
if(player == null){
if(selectedSong != null){
player = MediaPlayer.create(MainActivity.this, selectedSong);
seekBar.setMax(player.getDuration());
}
else{
Toast.makeText(MainActivity.this, "Please select a song file to play.", Toast.LENGTH_SHORT).show();
}
}
if(player != null){
seekBar.refreshDrawableState();
if(mProgress > (player.getDuration() - 30)){
player.seekTo(0);
}
else{
player.seekTo(mProgress);
}
if(player.isPlaying()){
player.pause();
setPlayButtonImage();
}
else {
player.start();
playCycle();
setPlayButtonImage();
}
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
//Restarts song from beginning
player.seekTo(0);
seekBar.setProgress(0);
player.start();
playCycle();
}
});
}
}
}
});
chooseBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent audiofile_chooser_intent = new Intent();
audiofile_chooser_intent.setAction(Intent.ACTION_GET_CONTENT);
audiofile_chooser_intent.setType("audio/*");
startActivityForResult(audiofile_chooser_intent, 1);
stopPlaying();
}
});
stopBtn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
stopPlaying();
if(selectedSong != null){
player = MediaPlayer.create(MainActivity.this, selectedSong);
seekBar.setMax(player.getDuration());
seekBar.setProgress(0);
mProgress = 0;
setPlayButtonImage();
}
}
});
}
//Changes the play button depending on whether the song is playing or not
private void setPlayButtonImage(){
if(player.isPlaying()){
playBtn.setImageResource(R.drawable.pause_button);
}
else {
playBtn.setImageResource(R.drawable.play_button);
}
}
public void playCycle() {
seekBar.setProgress(player.getCurrentPosition());
if(player.isPlaying()){
runnable = new Runnable() {
@Override
public void run() {
playCycle();
}
};
mainHandler.postDelayed(runnable, 1000);
}
}
private void stopPlaying(){
if(player != null){
player.stop();
player.reset();
player.release();
player = null;
}
}
//Creates dialog box for user to select an audio file from internal storage
private void chooseSong() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
AlertDialog songDialog = builder.create();
songDialog.setTitle(R.string.select_song);
songDialog.setMessage(getString(R.string.choose_song));
songDialog.setButton(AlertDialog.BUTTON_POSITIVE, getString(R.string.button_browse), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent audiofile_chooser_intent = new Intent();
audiofile_chooser_intent.setAction(Intent.ACTION_GET_CONTENT);
audiofile_chooser_intent.setType("audio/*");
audiofile_chooser_intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(audiofile_chooser_intent, 1);
}
});
songDialog.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.button_cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//Do nothing
}
});
songDialog.show();
}
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
if(requestCode == 1){
if(resultCode == RESULT_OK){
selectedSong = data.getData();
if(selectedSong != null){
mySong = selectedSong.toString();
}
//Save the Song Uri in string format to Shared Preferences
prefsEditor = sharedPrefs.edit();
prefsEditor.putString("song", mySong);
prefsEditor.apply();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onPause() {
super.onPause();
if(player != null){
player.pause();
setPlayButtonImage();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(player != null){
player.release();
}
mainHandler.removeCallbacks(runnable);
}
}
LOGCAT:
10-19 19:49:06.084 32507-32507/com.example.android.songselector E/MediaPlayerNative: Unable to create media player
10-19 19:49:06.085 32507-32507/com.example.android.songselector D/MediaPlayer: create failed:
java.io.IOException: setDataSource failed.: status=0x80000000
at android.media.MediaPlayer.nativeSetDataSource(Native Method)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1235)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1223)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1138)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1080)
at android.media.MediaPlayer.create(MediaPlayer.java:972)
at android.media.MediaPlayer.create(MediaPlayer.java:949)
at android.media.MediaPlayer.create(MediaPlayer.java:928)
at com.example.android.songselector.MainActivity.onCreate(MainActivity.java:84)
at android.app.Activity.performCreate(Activity.java:7174)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2910)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
10-19 19:49:06.086 32507-32507/com.example.android.songselector D/AndroidRuntime: Shutting down VM
10-19 19:49:06.086 32507-32507/com.example.android.songselector E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.songselector, PID: 32507
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.songselector/com.example.android.songselector.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.setAudioStreamType(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2957)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.setAudioStreamType(int)' on a null object reference
at com.example.android.songselector.MainActivity.onCreate(MainActivity.java:85)
at android.app.Activity.performCreate(Activity.java:7174)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2910)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)