Skip to content

Instantly share code, notes, and snippets.

@jj11hh
Created June 28, 2024 06:18
Show Gist options
  • Select an option

  • Save jj11hh/d19c278ccf74b88a00a7240c0f439101 to your computer and use it in GitHub Desktop.

Select an option

Save jj11hh/d19c278ccf74b88a00a7240c0f439101 to your computer and use it in GitHub Desktop.
A test script to read apk assets with JNI.
using System;
using System.Runtime.InteropServices;
using System.Text;
using UnityEngine;
public class AndroidReadAsset : MonoBehaviour
{
#if UNITY_ANDROID && !UNITY_EDITOR
[DllImport("libc")]
static extern IntPtr fdopen(int fd, string mode);
[DllImport("libc")]
static extern long fread(sbyte[] buffer, long size, long count, IntPtr stream);
[DllImport("libc")]
static extern long ftello(IntPtr stream);
[DllImport("libc")]
static extern int fseeko(IntPtr stream, long offset, int whence);
private IntPtr file;
private long length;
private long offset;
// Start is called before the first frame update
void Start()
{
var activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer")
.GetStatic<AndroidJavaObject>("currentActivity");
var assetManager = activity.Call<AndroidJavaObject>("getAssets");
var assetFd = assetManager.Call<AndroidJavaObject>("openFd", "test.bundle");
var parcelFd = assetFd.Call<AndroidJavaObject>("getParcelFileDescriptor");
length = assetFd.Call<long>("getLength");
offset = assetFd.Call<long>("getStartOffset");
var nativeFd = parcelFd.Call<int>("detachFd");
file = fdopen(nativeFd, "rb");
}
// Update is called once per frame
void Update()
{
int succ = fseeko(file, offset, 0 /* SEEK_SET */);
Debug.Log($"fseeko returns {succ}");
var buffer = new sbyte[11];
var bytesRead = fread(buffer, (long)1, (long)buffer.Length, file);
var result = Encoding.UTF8.GetString((byte[])(Array)buffer, 0, (int)bytesRead);
Debug.Log($"fread returns {result}, read {bytesRead} bytes, current position {ftello(file)}");
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment