JNI获取android wifi interface name

转自: http://blog.chinaunix.net/uid-20771867-id-3261874.html
        最近学习了云中漫步关于JNI的讲解,见http://my.unix-center.net/~Simon_fu/?p=833。再加上平常工作中学习实现了一个通过JNI来获取 wifi interface name的实验工程,加深了对JNI的理解。

        首先新建一个android工程,并在里面新建一个GetNetWork.java类,该类通过jni来调用由c++实现的方法。

点击(此处)折叠或打开

  1. package org.testjni;

  2. public class GetNetWork {
  3.     static{
  4.         System.loadLibrary("NetworkInterface");
  5.     }
  6.     public static native String get(String property);
  7. }
        static代码块告诉程序所要调用的库文件名,这个库文件将会在下面实现。另外定义了一个get方法,当调用这个get方法的时候就会去调用库文件中的方法。
  
         如果是在eclipse中编辑的,这时候就需要编译一下来生成class文件。然后进入到workspace中这个工程的 bin/classes目录下,如在我的电脑中就是/workspace/TestJNI/bin/classes。在这里运行命令 javah org.testjni.GetNetWork。运行完了之后会自动产生一个org_testjni_GetNetWork.h文件,打开文件,其头部有说明“ DO   NOT  EDIT THIS FILE  -  it  is  machine generated ”,所以说最好别修改这个文件。其实这个文件也可以自己写,只是那样会比较麻烦还容易出错,最好还是用javah命令生成吧。

点击(此处)折叠或打开

  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class org_testjni_GetNetWork */

  4. #ifndef _Included_org_testjni_GetNetWork
  5. #define _Included_org_testjni_GetNetWork
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10.  * Class: org_testjni_GetNetWork
  11.  * Method: get
  12.  * Signature: (Ljava/lang/String;)Ljava/lang/String;
  13.  */
  14. JNIEXPORT jstring JNICALL Java_org_testjni_GetNetWork_get
  15.   (JNIEnv *, jclass, jstring);

  16. #ifdef __cplusplus
  17. }
  18. #endif
  19. #endif
         好了,现在需要把这个文件搬一个家。在工程中新建一个文件夹jni,并在里面建两个子文件夹include和src。这两个文件将分别用来存放头文件和源代码。将org_testjni_GetNetWork.h复制到include文件夹中。

        接下来就是用c++实现这个get方法。在jni/src目录下新建一个c++文件org_testjni_GetNetWork.cpp

点击(此处)折叠或打开

  1. #include "org_testjni_GetNetWork.h"
  2. #include "jni.h"
  3. #include "properties.h"


  4. JNIEXPORT jstring JNICALL Java_org_testjni_GetNetWork_get(JNIEnv *env, jclass,
  5.         jstring keyJ) {
  6.     int len;
  7.     const char* key;
  8.     char buf[92];
  9.     jstring rvJ = env->NewStringUTF("");

  10.     key = env->GetStringUTFChars(keyJ, 0);

  11.     len = property_get(key, buf, "");
  12.     if (len >= 0) {
  13.         rvJ = env->NewStringUTF(buf);
  14.     }

  15.     env->ReleaseStringUTFChars(keyJ, key);

  16.     return rvJ;
  17. }
          在这个方法中还调用c的方法,所以还得用c语言实现property_get方法。在jni/include中新建一个头文件properties.h,在jni/src中新建一个c文件properties.c

点击(此处)折叠或打开

  1. #ifndef __CUTILS_PROPERTIES_H
  2. #define __CUTILS_PROPERTIES_H

  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif

  6. int property_get(const char *key, char *value, const char *default_value);

  7. #ifdef __cplusplus
  8. }
  9. #endif

  10. #endif

点击(此处)折叠或打开

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <errno.h>
  5. #include <assert.h>

  6. #include <properties.h>
  7. #include <sys/system_properties.h>

  8. #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_

  9. int property_get(const char *key, char *value, const char *default_value)
  10. {
  11.     int len;

  12.     len = __system_property_get(key, value);
  13.     if(len > 0) {
  14.         return len;
  15.     }

  16.     if(default_value) {
  17.         len = strlen(default_value);
  18.         memcpy(value, default_value, len + 1);
  19.     }
  20.     return len;
  21. }
        在这里调用了__system_property_get方法,这是个系统方法,会根据key的值查找结果并存在value里面,在这个程序中查找出来的结果应该为"wlan0"。

        好了,现在应该写make文件来进行编译了。在jni目录下新建一个Android.mk文件,关于每一行的含义网上一搜有很多,就不罗嗦了。

点击(此处)折叠或打开

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_SRC_FILES := \
  4. src/org_testjni_GetNetWork.cpp \
  5. src/properties.c
  6. LOCAL_C_INCLUDES := \
  7. $(LOCAL_PATH)/include
  8. LOCAL_CFLAGS :=
  9. LOCAL_CPPFLAGS :=
  10. LOCAL_MODULE := NetworkInterface
  11. include $(BUILD_SHARED_LIBRARY)
        执行这个文件需要电脑上装有ndk,没有的话可以去android的官方网站上去下载。然后在jni目录下执行ndk-build命令,如果这个命令没有加入到环境变量中要使用绝对路径,如我的电脑上执行~/android-ndk-r8/ndk-build。运行之后会自动生成libs和obj文件夹和里面的一堆文件。我们要使用的就是libs文件夹里面的libNetworkInterface.so文件。要注意的是名字前面的lib是系统自动加的,这是一个命名规则。

       如果没出什么问题的话可以说到这里就大功告成了,直接在程序中调用get方法就可以了:

点击(此处)折叠或打开

  1. package org.testjni;

  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.util.Log;

  5. public class TestJNIActivity extends Activity {


  6.     /** Called when the activity is first created. */
  7.     @Override
  8.     public void onCreate(Bundle savedInstanceState) {
  9.         super.onCreate(savedInstanceState);
  10.         setContentView(R.layout.main);
  11.         Log.d("test","get wifi interface name from jni:"+GetNetWork.get("wifi.interface"));
  12.     }
  13. }
           运行程序后输出的结果如下,这样表明程序成功地通过jni获取到了wifi interface name。
           最后完整的工程目录如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值