无法在Android上原生使用“ libnl”。无法使用`genl_ctrl_resolve()`

时间:2018-07-24 19:56:16

标签: android android-ndk ndk-build netlink 802.11

我的目标是在Android应用程序中使用libnl来获取在最新的网络扫描中接收到的信标帧列表,并打印(显示)关联的元数据,例如AP SSID,AP BSSID等... < / p>

按照基本的教程和指南,方法似乎是:

  1. 由于libnl带有自己的./configureMakefile
  2. ,因此可以为所有受支持的Android ABI交叉编译libnl。
  3. 将已编译的归档文件以PREBUILT_STATIC_LIBRARYPREBUILT_SHARED_LIBRARY的形式导入到本机C / C ++代码中
  4. 在本机代码中使用libnl方法

开发环境和配置:

  • IDE :Android Studio 3.1.2
  • NDK版本:Android NDK版本17b
  • 外部工具:Gradle,CMake
  • MinSDK版本:API 14
  • 目标SDK版本:API 21
  • 库来源:Libnl 3.2.25-link
  • 操作系统:Ubuntu 18.04 LTS

  1. 交叉编译:
    使用here中记录的NDK独立工具链方法,我已经能够成功交叉编译所有ABI(armeabi-v7aarm64-v8ax86x86_64的libnl 。这给了我.a个库的编译文件。

  2. 导入库并进行编译:
    这是紧跟Google(github)的代码示例(特别是“ hello-libs”示例)之后完成的。

注意 :我推断第1步和第2步正确完成,因为在编译和运行应用程序时,该库已成功链接到我的C / C ++源代码。此外,我能够从C / C ++源代码中调用libnl方法。我没有UnsatisfiedLinkErrorUndefined Reference to ...

  1. 在Linux中使用libnl方法
    我已使用libnl方法genl_ctrl_resolve将问题调试到语句中,以获取nl80211驱动程序的driverId。这将返回错误代码-12,表示“找不到对象”。

    ...
    struct nl_sock *socket = init_socket();
    driver_id = genl_ctrl_resolve(socket, "nl80211");
    ...
    

我的具体疑问是:

  1. 我的方法正确吗?如果没有,将不胜感激。
  2. 还有其他替代方法吗?
  3. 我的应用程序是否需要root访问权限才能获得驱动程序ID?
  4. 任何了解更多有关Native Android Development的好资源。

感谢您的帮助。 谢谢您。


PS ..

  • 我已经浏览了Android开发者网站
  • 我一直在指Android NDK Beginner's Guide by Sylvain RatabouilPro Android Apps Performance Optimization by Herve´ Guihot
  • 还尝试使用Eclipse(ADT)和较旧的SDK(r24.4.1),NDK(r10e)从头开始构建项目

2 个答案:

答案 0 :(得分:0)

如果libnl需要对 / dev / proc 的读取访问权限,则您可以忘记从无根设备上的NDK访问它。

Google已从两个版本中禁止Android,从Android 7开始,由于必须要求应用程序通过SAF间接读取文件,因此严格禁止在APK安装目录之外进行所有读取访问。

https://developer.android.com/about/versions/nougat/android-7.0-changes#permfilesys

https://developer.android.com/guide/topics/providers/document-provider

更好的方法是通过JNI使用框架network interfaces

答案 1 :(得分:0)

libnl通过套接字与内核对话。 您正在要求内核让您访问wifi的驱动程序界面。此时,了解设备正在使用哪个内核以及用于wifi的特定驱动程序将很重要。在Android上,这些是特定于制造商的,因此您不能依赖基于API级别的特定详细信息。

根据您提供的详细信息,我最大的猜测是: 1.内核正在理解您的查询 2.驱动程序没有nl80211接口。您可以试听无线扩展消息吗?

总而言之,无论API级别如何,它都可以在某些设备上运行,而不能在其他设备上运行。