无法从保存的内部存储音频文件创建媒体播放器

时间:2018-10-19 07:18:21

标签: java android sharedpreferences android-mediaplayer

我一直在开发一个使用用户从内部设备存储中选择的歌曲的应用程序。将所选音频文件的uri保存为共享首选项时,音频将在应用程序仍在运行(包括在活动之间进行更改)时加载并播放,但是,一旦应用程序重新启动,就会出现使用不变的uri。

我已经花了很多时间寻找使它起作用的方法,因此我们将不胜感激。

几年前,有一个类似的问题问了却没有答案... Saving audio content Uri in sharedpreference to play later

我在应用程序的歌曲选择器部分下面有一些代码:

  

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) 

0 个答案:

没有答案