1

how to slove RandomAccessFile always return FileNotFound Exception

tFile = new File(path);
RandomAccessFile testFile = null;
testFile = new RandomAccessFile(tFile, "r");

I can get the uri form File like this:content://media/external/images/media/xxxx , but how to initial File

google doc. RandomAccessFile initial , public RandomAccessFile(File file, String mode) throws FileNotFoundException , public RandomAccessFile(String name, String mode) throws FileNotFoundException

how to initial RandomAccessFile?

1 Answers1

1

You have a content Uri, not a file Uri. Content Uri is not guaranteed to be backed by a file. It can be in cloud and downloaded on demand. It can be in database.

On top of that you can't access most disk files directly on Android 10. An app can only work with files it created and files in its private data directory.

Use ContentResolver API to read content Uri, for example ContentResolver.openInputStream(...).

If you need random access copy the input stream to a file in your app's private directory.

If it's a small piece of content, you could keep it in memory. It depends on your use case.

Eugen Pechanec
  • 37,669
  • 7
  • 103
  • 124
  • has any idea not move file to app's private directory, file is store in Media collections (photos, videos, audio) – Pang-yao Liu Sep 25 '19 at 03:44
  • Yes, the file is in media store. You can not move it. Your app will *copy* it from media store to its own data directory (`context.getFilesDir()` or `context.getCacheDir()` based on use case). The process is described here: https://stackoverflow.com/a/57391293/2444099. I also recommend this article: https://commonsware.com/blog/2016/03/15/how-consume-content-uri.html – Eugen Pechanec Sep 25 '19 at 06:55
  • @EugenPechanec So what you are saying is that, from Android 10 onwards, the only reliable way is to create a copy of the file in your app's private directory? – HB. Oct 03 '19 at 05:18
  • @HB What I'm saying is that you're not guaranteed to work with a file on any version of Android (see the commonsware link, section *Pretend That the MediaStore Knows What You’re Talking About*). `openInputStream` gives you a stream. If you need random access make a local copy to file or memory. – Eugen Pechanec Oct 03 '19 at 07:10
  • This may also interest you https://commonsware.com/blog/2016/11/21/consuming-content-be-flexible.html – Eugen Pechanec Oct 03 '19 at 07:16
  • @EugenPechanec That is what I meant. Some libraries require that you pass it a file object or pass a `file://` scheme Uri. In this case I will have to create a copy of that file to my application's directory (`context.getExternalFilesDir`) in order to get a `file://` scheme Uri. Of course, when sharing the file with other applications I will have to do so using a content provider. – HB. Oct 03 '19 at 07:24
  • 1
    @HB. Correct, if you need a file for a library in your project, you need to make an app local file. Parallel to that, you can raise an issue with the library maintainer so that they start supporting input streams. – Eugen Pechanec Oct 03 '19 at 07:29
  • @EugenPechanec Thanks for the reply. Much appreciated. – HB. Oct 03 '19 at 07:31