kiewic
kiewic

Reputation: 16420

How to get a java.io.File from R.raw resource

I added a raw resource to my Android Studio project:

Then I need to get a java.io.File instance pointing to it.

I have tried three things, but file cannot be found and File.exists() is equal false:

// Option 1:
//
//     com.example.myapp:raw/plano_metrobus
//
val fileName = resources.getResourceName(R.raw.plano_metrobus)
Log.w("xxx", fileName)
Log.w("xxx", File(fileName).exists().toString())

// Option 2
//
//     android.resource://com.example.myapp:raw/plano_metrobus
//
val uri = Uri.parse("android.resource://" + fileName)
Log.w("xxx", uri.toString())
Log.w("xxx", File(uri.toString()).exists().toString())

// Option 3
//
//     android.resource://com.example.myapp/2131427328
//
val uri2 = Uri.parse("android.resource://" + packageName + "/" + R.raw.plano_metrobus)
Log.w("xxx", uri2.toString())
Log.w("xxx", File(uri2.toString()).exists().toString())

What is the right way to create a File object?

Upvotes: 1

Views: 1466

Answers (2)

CommonsWare
CommonsWare

Reputation: 1006819

Then I need to get a java.io.File instance pointing to it.

That is not directly possible. It is a file on your development machine. It is not a standalone file on the device — it is merely an entry in the APK file on the device.

What is the right way to get a File object?

Ideally, you don't. You cannot modify the resource, and hopefully whatever that you are using that accepts a File can also accept an InputStream. If so, use openRawResource() on a Resources object, and you get one of those by calling getResources() on a Context (e.g., Activity, Service).

If you are using some third-party library that was poorly written and requires a file, you would need to use that openRawResource() approach, then copy the bytes from that InputStream to some file that you control (e.g., in getCacheDir()). You can then use the resulting file.

Upvotes: 2

kiewic
kiewic

Reputation: 16420

Following the previous advice, I ended up using Context.getCacheDir() to create a uncompressed version of the file, and then been able to use it with PdfRenderer. Here is the solution:

val FILENAME = "FileName.pdf"
val file = File(applicationContext.cacheDir, FILENAME)
if (!file.exists()) {
    val input = resources.openRawResource(R.raw.plano_metrobus)
    val output = FileOutputStream(file)

    val buffer = ByteArray(1024)
    while (true) {
        val size = input.read(buffer)
        if (size == -1) {
            break;
        }
        output.write(buffer, 0, size)
    }

    input.close()
    output.close()
}

val fileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
val renderer = PdfRenderer(fileDescriptor)

Upvotes: 0

Related Questions