LutfiTekin
LutfiTekin

Reputation: 471

Playing audio from uri

I am getting java.lang.SecurityException when i try to play audio file. I trying make simple app that selects audio from the phones memory and save it using sqlite and list those selected before.

In the app, first time plays audio file without any error. But after i restarted the app it does not play instead returns SecurityException. I am using this code below to pick audio file

       Intent intent = new Intent();
                intent.setType("audio/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,"Select Audio "), REQUEST_CODE);

  @Override
    protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
        if(requestCode == REQUEST_CODE && data != null){
            Toast.makeText(MainActivity.this, "DATA " + data.getData(), Toast.LENGTH_SHORT).show();
            //Prompting alertdialog for name of the audio file           
           AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Enter name for audio");
            final EditText input = new EditText(this);
            input.setInputType(InputType.TYPE_CLASS_TEXT);
            builder.setView(input);
            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                   sql.addToHistory(new soundDB.Effects(null,data.getData().toString(),input.getText().toString()));
               new loadEffects().execute();
                }
            });
            builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

            builder.show();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

and i am using those permissions at the manifest file

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
<uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED" />

06-25 11:45:21.902 17298-17372/? I/DefaultRequestDirector: I/O exception (javax.net.ssl.SSLException) caught when processing request: Write error: ssl=0x8d334c00: I/O error during system call, Broken pipe
06-25 11:46:03.204 7086-7086/? I/dex2oat: dex2oat took 893.003ms (threads: 4) arena alloc=3KB (3288B) java alloc=2MB (2752008B) native alloc=3MB (3826768B) free=2MB (2464688B)
06-25 11:46:12.890 7234-7234/? W/MediaPlayer: Couldn't open content://com.android.providers.downloads.documents/document/545: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.downloads.DownloadStorageProvider from ProcessRecord{d912193 7234:[package name]/u0a116} (pid=7234, uid=10116) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
06-25 11:46:12.938 7234-7234/? D/MediaPlayer: create failed:

Upvotes: 2

Views: 2102

Answers (2)

Jerrrrry W
Jerrrrry W

Reputation: 16

This is how I solve it. When getting audio file uri, I use ACTION_OPEN_DOCUMENT instead of ACTION_GET_CONTENT, and add this line to onActivityResult.

It will play even after device reboot. The complete code snippet

this.getContentResolver().takePersistableUriPermission(currentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
public void getAudioFileUri(View v) {

  Intent intent = new Intent();
  intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
  intent.setType("audio/*");
  intent.addCategory(Intent.CATEGORY_OPENABLE);
  try {
    startActivityForResult(Intent.createChooser(intent, "Choose audio file"), 1);
  } catch (Exception ex) {

  }
}

public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
  Uri currentUri = null;
  if (resultCode == Activity.RESULT_OK) {
    if (requestCode == 1) {
      if (resultData != null) {
        currentUri = resultData.getData();
        this.musicUri = currentUri.toString();
        this.getContentResolver().takePersistableUriPermission(currentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
      }
    }
  }
}

Upvotes: 0

CommonsWare
CommonsWare

Reputation: 1006614

But after i restarted the app it does not play instead returns SecurityException.

You only have rights to the content identified by a Uri, by default, for the lifetime of your process. Think of it as a URL tied to a user session in a Web app; once that session times out, the URL is no longer usable.

On API Level 19+, you can try using takePersistableUriPermission() to get more durable access to the content. However, that is more for ACTION_OPEN_DOCUMENT than ACTION_GET_CONTENT, and so it may not work.

Upvotes: 2

Related Questions