0

I get a song from the user's library like this:

Intent selectIntent = new Intent(Intent.ACTION_GET_CONTENT);
            selectIntent.setType("audio/*");
            startActivityForResult(selectIntent, SONG_REQUEST_CODE);

and retrieve it like this:

 @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == SONG_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
            if ((data != null) && (data.getData()!=null)) {
                song = data.getData(); //song is an Uri defined previuosly
            }
        }
    }

I need to import it into a folder I defined and created like this:

final File dir2 = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Chords/Imported Audio");
dir2.mkdirs();

I tried like this as suggested by Commonsware but the file is not created:

private void importAudio(Uri uri) {
    String source = uri.getPath();
    String destinationFile = dir2 + File.separator + songName;

    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;

    try {
        bis = new BufferedInputStream(new FileInputStream(source));
        bos = new BufferedOutputStream(new FileOutputStream(destinationFile, false));

        byte[] buf = new byte[1024];
        bis.read(buf);
        do {
            bos.write(buf);
        } while (bis.read(buf) != -1);

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bis != null) bis.close();
            if (bos != null) bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

The file is not there though. How can I fix this?

Daniele
  • 4,163
  • 7
  • 44
  • 95

1 Answers1

1

The file is not there though

Most likely, you have a stack trace in LogCat. song.getPath() is unlikely to be useful. song probably does not have a file scheme, and so getPath() is meaningless.

Use ContentResolver and openInputStream() to get an InputStream on song, then use that InputStream to copy the content.

Also:

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks for the answer, I will do this using `InputStream`. Just out of curiosity, what is the `getPath()` method in the `Uri` object actually useful for? Based also on the other questions here on SO, it seams to me as it is a really confusing method and I still cannot figure out how and when to use it. Thanks also for the indixeing tip is gonna be useful and I didn't know about it – Daniele Sep 15 '17 at 14:13
  • @Daniele: "Just out of curiosity, what is the getPath() method in the Uri object actually useful for?" -- if the scheme is `file`, it is a filesystem path. If the scheme is anything else, it is a series of characters whose meaning is opaque to you. For example, `https://stackoverflow.com/questions/46241361/android-copy-audio-from-uri-to-specific-directory/46241452` is a `Uri`. Its scheme is `https`. Its path is `/questions/46241361/android-copy-audio-from-uri-to-specific-directory/46241452`, and that is just a series of characters that has no meaning to your app. – CommonsWare Sep 15 '17 at 14:16
  • Please, would you have a look at the updated answer? I tried doing like you suggested, but with no luck. The file is not created – Daniele Sep 16 '17 at 11:59
  • @Daniele: Check LogCat for error messages from your `catch` blocks, and [index the destination file](https://stackoverflow.com/questions/32789157/how-to-write-files-to-external-public-storage-in-android-so-that-they-are-visibl) (see the two bullets in my answer). – CommonsWare Sep 16 '17 at 12:24
  • I have implemented both already, permissions and indexing, even though a file manager shouldn't be based on `MediaStore` for the file to be visible – Daniele Sep 16 '17 at 16:46
  • @Daniele: You did not follow my instructions. You are still using `getPath()`. Stop using `FileInputStream`. As I wrote in my answer, use `ContentResolver` and `openInputStream()` to get an `InputStream`. Please examine LogCat for error messages from your `catch` blocks, as you should be getting a `FileNotFoundException`. – CommonsWare Sep 16 '17 at 16:48
  • That;s right I'm getting a `FileNotFoundException` but I don't quite understand how to use the content resolver and inputstream, can you provide a sample or a documentation reference? – Daniele Sep 16 '17 at 17:08
  • @Daniele: You can get an instance of `ContentResolver` by calling `getContentResolver()` on a `Context` (e.g., an `Activity`, a `Service`). [`openInputStream()` is a method on `ContentResolver`](https://developer.android.com/reference/android/content/ContentResolver.html#openInputStream(android.net.Uri)). It takes your `Uri` as a parameter. It returns an `InputStream` on the content identified by that `Uri`. – CommonsWare Sep 16 '17 at 17:11
  • ok I did it, not to write it I use a normal outputstream and write to the desired directory? – Daniele Sep 16 '17 at 17:13
  • @Daniele: Sorry, but I do not understand that question. You should be able to substitute the `InputStream` from `openInputStream()` for the `FileInputStream` in your final code snippet in your question. You might want to increase your buffer size a bit (e.g., 8192). – CommonsWare Sep 16 '17 at 17:15