Error when playing shared sound with shared preferences

1

with an intent I select an mp3 file and I save with URI the location in shared preferences as I found in Google; in another activity a media player element is launched that rescues the uri. But ...

  • I give play to play it and it works
  • I close and open the app
  • I hit the play button and the app thunders
  • I re-select an audio and it works

The problem seems to be when closing and opening. Why?

This is the code:

public class MainActivity extends AppCompatActivity {

    public SharedPreferences prefs;
    Button mp3,play;
    int u;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        prefs=getSharedPreferences("MisPreferencias",this.MODE_PRIVATE);
        mp3=findViewById(R.id.mp3);
        play=findViewById(R.id.play);
        mp3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                elijemp3(v);
            }
        });
        play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i=new Intent(MainActivity.this,musica.class);
                startActivity(i);
            }
        });
    }
    public void elijemp3(View view){

        Intent intent = new Intent();
        intent.setAction(android.content.Intent.ACTION_VIEW);
        File file = new File("audio");
        intent.setDataAndType(Uri.fromFile(file), "audio/*");
        startActivity(intent);
        Toast.makeText(this,file.getPath(),Toast.LENGTH_LONG).show();
        Toast.makeText(this,file.toString(),Toast.LENGTH_LONG).show();*/
        Intent intent = new Intent();
        intent.setType("audio/mp3");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Open Audio (mp3) file"), 1);
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && resultCode == Activity.RESULT_OK){
            if ((data != null) && (data.getData() != null)){
               Uri audioFileUri = data.getData();
                ***String s=getRealPathFromUri(this,audioFileUri);***
                SharedPreferences.Editor editor = prefs.edit();
                ***editor.putString("urime", s);***
                editor.apply();
                Toast.makeText(this,s,Toast.LENGTH_LONG).show();

            }
        }
    }
    public String getRealPathFromUri(Context context, Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] proj = { MediaStore.Images.Media.DATA };
            cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }
}


ESTE EL ES OTRO activity

     public class musica extends AppCompatActivity {

    public SharedPreferences prefs;
    public Uri urim;
    MediaPlayer mediaPlayer,mp;
    public String urimp3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_musica);

        prefs=getSharedPreferences("MisPreferencias",this.MODE_PRIVATE);
        urimp3 = prefs.getString("urime", null);
            urim=Uri.parse(urimp3);
        playOnOffSound();
            // urim=Uri.parse("sdcard/bep.mp3");
      /*      mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            try {
                mediaPlayer.setDataSource(getApplicationContext(), urim);
                mediaPlayer.prepare();
                mediaPlayer.start();
            } catch (IOException e) {
                e.printStackTrace();
            }*/

    }

    private void playOnOffSound(){

        mp = MediaPlayer.create(this, urim);
        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

            @Override
            public void onCompletion(MediaPlayer mp) {
                // TODO Auto-generated method stub
                mp.release();
            }
        });
        mp.start();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
       /*if(mediaPlayer!=null){
            mediaPlayer.release();
            mediaPlayer = null;
        }*/ if(mp!=null){
            mp.release();
            mp = null;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
       /* if(mediaPlayer!=null)
        {
            mediaPlayer.start();
        }*/ if(mp!=null)
        {
            mp.start();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
       /* if(mediaPlayer!=null)
        {
            mediaPlayer.pause();
        }*/ if(mp!=null)
        {
            mp.pause();
        }
       /// musica.pause();
    }
}

Nothing great, but why does not it work? This is the error I receive:

  

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.start ()' on a null object reference

I already tried this other way and nothing. I receive a new error:

This is the code:

public class MainActivity extends AppCompatActivity {

    public SharedPreferences prefs;
    Button stop,play,examinar;
    String FilePathAudio;
    TextView url;
    private final int PICKER=1;
    private int state=1;
    private final int PLAYING=1;
    private final int PAUSING=2;

    Uri FilePath;
    MediaPlayer mediaPlayer=new MediaPlayer();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

      //  mediaPlayer=MediaPlayer.create(this,R.raw.mp3);
       // mediaPlayer.setLooping(true);
        stop=findViewById(R.id.stop);
        play=findViewById(R.id.play);
        examinar=findViewById(R.id.examinar);
        play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (state)
                {
                    case PLAYING:
                        mediaPlayer.start();
                        state=PAUSING;
                        play.setText("Pause");
                        break;
                    case PAUSING:
                        mediaPlayer.pause();
                        state=PLAYING;
                        play.setText("Play");
                        break;
                }

            }
        });
        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mediaPlayer.stop();
                play.setText("Play");
            }
        });

        examinar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pickfile();
            }
        });
    }
    private void pickfile() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("audio/*");
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        try {
            startActivityForResult(Intent.createChooser(intent, "selecione un audio"), PICKER);

        } catch (android.content.ActivityNotFoundException ex) {

        }
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case PICKER:
                if (requestCode == RESULT_OK) {
                    FilePath = data.getData();
                    FilePathAudio=getRealPathFromUri(FilePath);
                }
                try{
                    mediaPlayer.setDataSource(FilePathAudio);
                    //mediaPlayer.prepare();

                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
        }

    }
    public String getRealPathFromUri (Uri contentUri){
        Cursor cursor = null;
        try {
            String[] proj = {MediaStore.Audio.Media.DATA};
            cursor = getApplicationContext().getContentResolver().query(contentUri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
    
asked by Jose Luis Flamenco Chie 24.11.2018 в 19:14
source

1 answer

1

Your problem is that the MediaPlayer.create() is returning null . This could be due to several reasons, such as permissions, corrupt or nonexistent file, etc. But considering that it works for you when you execute it for the first time, we can discard the majority.

This saves the string in shared:

The problem must be that you are not releasing the resource properly and then when you run the app again, you can not create the MediaPlayer , the file you are trying to access is already taken and returns null .

If we put together the code of onPause and onDestroy of your code you will see it more clearly:

//onPause
musica.pause();
//onDestroy
if(musica.isPlaying()){ //Siempre es falso porque fue pausado antes.
   musica.stop();
   musica.release(); //No se ejecuta y el recurso no se libera.
}

I would recommend that you release the resource in this way, which I think is the safest:

@Override
protected void onStop(){
   if(mediaPlayer != null){
      mediaPlayer.release();
      mediaPlayer = null;
   }
}

and delete the code of the onDestroy() when adding this but it will break when wanting to do release() to mediaPlayer that is now null .

Now that you have added the debug print I can see that you are also saving the URI incorrectly.

You are saving content://media... that is not a real URI, so you can not open the file after you have closed the app.

What you must do is to transform the URI of content into an absolute path before saving it.

The code to transform it would be something like this:

public String getRealPathFromUri(Context context, Uri contentUri) {
    Cursor cursor = null;
    try {
        String[] proj = { MediaStore.Images.Media.DATA };
        cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}
    
answered by 24.11.2018 в 23:10