使用 C++ 获取 Android APK 的名称和 NativeActivity 类
我正在使用 NDK 和 NativeActivity 编写 Android 应用程序。我的应用程序依赖于一些作为资产提供的第三方代码。目前,我正在尝试提取这些资产,同时保持文件夹结构完整。
我尝试过使用 AssetManager,但为了保持文件夹结构完整,对于像我提到的这样的简单任务,似乎会涉及大量代码。此后,我将注意力转移到尝试将 APK 视为 ZIP 文件并以这种方式提取其内容。但这需要我找到 APK 的确切路径。
在普通的 Android 应用程序中,我们会使用 getPackageCodePath,但这是附加到 Context 类的一个抽象方法。我的问题是,在不使用正常 Activity 时如何获取 APK 的确切路径?
我还尝试通过 JNI 调用 getPackageCodePath,但由于无法找到该方法而导致应用程序崩溃。
编辑: 这可能吗?
I'm writing an Android app using the NDK and NativeActivity. My app depends on a few bits of third party code that are shipped as assets. Currently I'm working on trying to extract those assets while keeping the folder structure intact.
I've tried using the AssetManager, but to keep the folder structure intact it seemed like there would a huge amount of code involved, for a simple task such as what I've mentioned. I've since switched focus to try to implement treating the APK as a ZIP file and extract its contents that way. But that requires I find the exact path to the APK.
In a normal Android app one would use getPackageCodePath, but this is an abstract method attached to the Context class. My question is how do I obtain the exact path to the APK when not using a normal Activity?
Also I tried calling getPackageCodePath via JNI, but that crashed the app on account of not being able to find the method.
EDIT:
Is this even possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我实际上能够通过 JNI 调用 getPackageCodePath 并使其正常工作。以下代码放在 NDK r7 中本机活动示例中的
android_main
顶部,记录了正确的路径并且不会崩溃:不过,我觉得这可能不是一个很好的解决方案。有两件事让我担心:
ANativeActivity
的env
成员,如果我理解正确的话,这段代码将在本机活动的线程中运行。ANativeActivity
的clazz
成员似乎命名错误,实际上是 JavaNativeActivity
的实例而不是类对象。否则这段代码将无法工作。我真的很讨厌依赖像这样明显命名错误的东西。除此之外,它确实有效,而且我实际上自己也打算使用它来尝试使用 libzip 将资产从 .apk 中提取出来并放入数据目录中。
I was actually able to call
getPackageCodePath
via JNI and get it to work. The following code put at the top ofandroid_main
in the native-activity sample in NDK r7 logs the correct path and doesn't crash:I feel like this might not be a great solution, though. There are two things that worry me:
env
member ofANativeActivity
in the main Java thread, and if I understand things correctly, this code is going to get run in the native activity's thread.ANativeActivity
'sclazz
member appears to be misnamed and is actually the instance of the JavaNativeActivity
instead of the class object. Otherwise this code wouldn't work. I really hate relying on something that is obviously misnamed like this.Aside from that, it works, and I'm actually about to use it myself to try to extract the assets out of the .apk using libzip and into the data directory.
由于我只需精确搜索如何执行附加/分离调用,因此我将在此处粘贴更新的版本。
以下似乎获得了正确的位置而不会崩溃(经过最少的测试)
Since I just had to search for exactly how to do the attach/detach calls I'll paste the updated version here.
The following seems to get the right location without crashing (after minimal testing)
2014年不得不修改成这样。
Had to modify it to this in the year 2014.
您是否尝试从应用程序中读取 /proc/self/cmdline ?
您应该能够像正常一样打开它(只要 proc 文件是正常的:-),这样您就可以从文件中读取直到 EOF,但不能查找)c FILE 并从中读取。
作为电话应用程序的示例,我可以从 android 中的 ps 看到应用程序的名称是预期的应用程序名称:
检查 cmdline 中的 pid 返回一个好的应用程序名称:
Did you try to read /proc/self/cmdline from your application?
You should be able to open it as a normal (as far as proc files are normal :-) so you can read from the file until EOF, but not seek) c FILE and read from it.
As an example for the phone app, I can see from ps in android that the name of the applications is the expected app name:
And checking the cmdline for that pid returns a good app name:
在 Java 中调用
getPackageCodePath()
并通过本机方法将 jstring 传递到您的 C++ 应用程序Call
getPackageCodePath()
in Java and pass jstring to your C++ app via native method