Android: Add APK reading, closing app. Fix JNI env not attached to thread.
This commit is contained in:
parent
e0b02d2708
commit
12940dad1d
2 changed files with 47 additions and 2 deletions
|
@ -97,5 +97,7 @@ when defined(android):
|
|||
export platform.myouAndroidGetJniEnv
|
||||
export platform.myouAndroidGetInternalDataPath
|
||||
export platform.myouAndroidGetExternalDataPath
|
||||
export platform.myouAndroidAPKFilePointerLength
|
||||
export platform.myouCloseMobileApp
|
||||
|
||||
export platform.myouSetKeyboardVisible
|
||||
|
|
|
@ -324,8 +324,17 @@ proc myouAndroidGetJniEnv*(): pointer =
|
|||
# Ussing offsets from ANativeActivity
|
||||
let vm = cast[ptr ptr array[7, pointer]](activity[1])
|
||||
# Using offsets from jni.h
|
||||
let GetEnv = cast[proc(vm: pointer, penv: var pointer, version: int32): int32 {.cdecl, gcsafe.}](vm[][6])
|
||||
discard GetEnv(vm, result, 0x00010006'i32)
|
||||
let getEnv = cast[proc(vm: pointer, penv: var pointer, version: int32): int32 {.cdecl, gcsafe.}](vm[][6])
|
||||
let attachCurrentThread = cast[proc(vm: pointer, penv: ptr pointer, args: pointer): int32 {.cdecl, gcsafe.}](vm[][4])
|
||||
let status = getEnv(vm, result, 0x00010006'i32)
|
||||
if status == -2: # JNI_EDETACHED
|
||||
# Attach thread to VM
|
||||
if attachCurrentThread(vm, result.addr, nil) != 0:
|
||||
echo "could not attach thread to VM"
|
||||
result = nil
|
||||
elif status != 0: # JNI_OK
|
||||
result = nil
|
||||
# TODO: do we ever need to detach a thread from the VM?
|
||||
|
||||
proc myouAndroidGetInternalDataPath*(): string =
|
||||
when defined(android):
|
||||
|
@ -337,5 +346,39 @@ proc myouAndroidGetExternalDataPath*(): string =
|
|||
let activity = cast[ptr array[6, cstring]](window.glfmAndroidGetActivity())
|
||||
return $activity[5]
|
||||
|
||||
when defined(android):
|
||||
proc AAssetManager_open(asset_manager: pointer, filename: cstring, mode: int32): pointer {.importc,cdecl.}
|
||||
proc AAsset_close(asset: pointer) {.importc,cdecl.}
|
||||
proc AAsset_getBuffer(asset: pointer): pointer {.importc,cdecl.}
|
||||
proc AAsset_getLength64(asset: pointer): int64 {.importc,cdecl.}
|
||||
proc ANativeActivity_finish(activity: pointer) {.importc,cdecl.}
|
||||
|
||||
type myouAAssetObj = object
|
||||
asset: pointer
|
||||
p*: pointer
|
||||
len*: int
|
||||
|
||||
type myouAAsset* = ref myouAAssetObj
|
||||
|
||||
proc `=destroy`(x: var myouAAssetObj) =
|
||||
if x.asset != nil:
|
||||
AAsset_close(x.asset)
|
||||
x.asset = nil
|
||||
|
||||
proc myouAndroidAPKFilePointerLength*(path: string): myouAAsset =
|
||||
let activity = cast[ptr array[9, pointer]](window.glfmAndroidGetActivity())
|
||||
# Ussing offsets from ANativeActivity, assuming all pointers are aligned
|
||||
let asset_manager = activity[8]
|
||||
let asset = AAssetManager_open(asset_manager, path.cstring, 3) # 3 = buffer mode
|
||||
if asset == nil:
|
||||
echo "not found in APK: ", path
|
||||
return myouAAsset()
|
||||
let p = AAsset_getBuffer(asset)
|
||||
let len = AAsset_getLength64(asset).int
|
||||
myouAAsset(asset: asset, p: p, len: len)
|
||||
|
||||
proc myouSetKeyboardVisible*(show: bool) =
|
||||
window.glfmSetKeyboardVisible(show)
|
||||
|
||||
proc myouCloseMobileApp*() =
|
||||
ANativeActivity_finish(window.glfmAndroidGetActivity())
|
||||
|
|
Loading…
Reference in a new issue