Android активы, C, JNI - PullRequest
       26

Android активы, C, JNI

8 голосов
/ 24 января 2011

Как получить доступ к ресурсу Android, такому как файл .txt, из C с помощью JNI?

Я пытаюсь "file: ///android_asset/myFile.txt" и локально "myFile.txt" с дубликатом myFile.txt в папке jni с файлом реализации C.

Ответы [ 2 ]

11 голосов
/ 24 января 2011

С активами связано то, что вы не можете получить к ним доступ напрямую как к файлам. Это потому, что активы читаются непосредственно из APK. Они не распаковываются в определенную папку после установки.

Начиная с Android 2.3, есть C API для доступа к ресурсам. Посмотрите на <android/asset_manager.h> и assetManager поле в <android/native_activity.h>. Я никогда не использовал это, хотя, и я не уверен, что вы можете использовать этот API менеджера активов, если вы не полагаетесь на нативную деятельность. И вообще, это не будет работать на Android 2.2 и ниже.

Итак, я вижу три варианта:

  • вы можете извлечь ресурсы в некоторый каталог, но это займет дополнительное место
  • вы могли бы (bunlde и) использовать что-то вроде libzip для чтения ресурсов из APK в чистом C.
  • или, чтобы избежать объединения дополнительной библиотеки, я предпочитаю читать данные в C, используя JNI, из объекта Java InputStream, возвращаемого AssetManager.open(). Требуется немного кода, но он прекрасно работает.
2 голосов
/ 26 июня 2014

Если вы не можете использовать API-интерфейс AssetManager C, поскольку вам нужно вызвать библиотеку C / C ++, для которой требуется имя файла, вместо этого можно использовать необработанный ресурс.

Единственный недостаток - это необходимостьбыть скопированы в каталог данных (temp) вашего приложения во время выполнения.

Поместите файл в res / raw

Поместите файл, который вы хотите прочитать из нативного кода, в res/raw dir.

Создание копии

Во время выполнения скопируйте файл из res/raw/myfile.xml в data dir:

File dstDir = getDir("data", Context.MODE_PRIVATE);
File myFile = new File(dstDir, "tmp_myfile.xml");
FileMgr.copyResource(getResources(), R.raw.my_file, myFile);

Теперь имя файла для передачи в ваш собственный код:myFile.getAbsolutePath()

copyResource (rsrcId, dstFile)

public static File copyResource (Resources r, int rsrcId, File dstFile) throws IOException
{
    // load cascade file from application resources
    InputStream is =  r.openRawResource(rsrcId);
    FileOutputStream os = new FileOutputStream(dstFile);

    byte[] buffer = new byte[4096];
    int bytesRead;
    while ((bytesRead = is.read(buffer)) != -1)
        os.write(buffer, 0, bytesRead);
    is.close();
    os.close();

    return dstFile;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...