Android中APK直接通过JNI访问驱动

点击打开链接

1.新建文件LED-JNI.c,内容如下:

[cpp]  view plain  copy
  1. #include <jni.h>  /* /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ */  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <sys/types.h>  
  5. #include <sys/stat.h>  
  6. #include <fcntl.h>  
  7. #include <sys/ioctl.h>  
  8.   
  9. #include <android/log.h>  /* liblog */  
  10.   
  11. //__android_log_print(ANDROID_LOG_DEBUG, "JNIDemo", "native add ...");  
  12.    
  13. #if 0  
  14. typedef struct {  
  15.     char *name;     /* Java里调用的函数名 */  
  16.     char *signature;   /* JNI字段描述符, 用来表示Java里调用的函数的参数和返回值类型 */  
  17.     void *fnPtr;     /* C语言实现的本地函数 */  
  18. } JNINativeMethod;  
  19. #endif  
  20.   
  21. static jint fd;  
  22.   
  23. jint ledOpen(JNIEnv *env, jobject cls)  
  24. {  
  25.     fd = open("/dev/msmgpio", O_RDWR);  
  26.     __android_log_print(ANDROID_LOG_DEBUG, "LEDDemo""native ledOpen : %d", fd);  
  27.     if (fd >= 0)  
  28.         return 0;  
  29.     else  
  30.         return -1;  
  31. }  
  32.   
  33. void ledClose(JNIEnv *env, jobject cls)  
  34. {  
  35.     __android_log_print(ANDROID_LOG_DEBUG, "LEDDemo""native ledClose ...");  
  36.     close(fd);  
  37. }  
  38.   
  39. jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)  
  40. {  
  41.     int ret = ioctl(fd, which, status);  
  42.     __android_log_print(ANDROID_LOG_DEBUG, "LEDDemo""native ledCtrl : %d, %d, %d", which, status, ret);  
  43.     return ret;  
  44. }  
  45.   
  46. static const JNINativeMethod methods[] = {  
  47.     {"ledOpen""()I", (void *)ledOpen},  
  48.     {"ledClose""()V", (void *)ledClose},  
  49.     {"ledCtrl""(II)I", (void *)ledCtrl},  
  50. };  
  51.   
  52. /* System.loadLibrary */  
  53. JNIEXPORT jint JNICALL  
  54. JNI_OnLoad(JavaVM *jvm, void *reserved)  
  55. {  
  56.     JNIEnv *env;  
  57.     jclass cls;  
  58.   
  59.     if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {  
  60.         return JNI_ERR; /* JNI version not supported */  
  61.     }  
  62.     cls = (*env)->FindClass(env, "mobiletek/hardlibrary/HardControl");  
  63.     if (cls == NULL) {  
  64.         return JNI_ERR;  
  65.     }  
  66.   
  67.     /* 2. map java hello <-->c c_hello */  
  68.     if ((*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0])) < 0)  
  69.         return JNI_ERR;  
  70.   
  71.     return JNI_VERSION_1_4;  
  72. }  

2.编译生成libhardcontrol.so,使用交叉编译器prebuilts/gcc/Linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-gcc:
arm-linux-androideabi-gcc -fPIC -shared LED-JNI.c -o libhardcontrol.so -I /usr/lib/jvm/Java-1.7.0-openjdk-amd64/include/  -nostdlib prebuilts/ndk/9/platforms/Android-19/arch-arm/usr/lib/libc.so -I prebuilts/ndk/9/platforms/android-19/arch-arm/usr/include prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/liblog.so


3.在Android Studio工程的app/libs目录下新建armeabi目录,将编译生成的libhardcontrol.so文件放入该目录下。

4.
在工程目录app/src/main/java/mobiletek下新建hardlibrary目录,在hardlibrary目录下新建HardControl.java文件,文件内容如下:

[java]  view plain  copy
  1. package mobiletek.hardlibrary;  
  2.   
  3. public class HardControl {  
  4.     public static native int ledCtrl(int which, int status);  
  5.     public static native int ledOpen();  
  6.     public static native void ledClose();  
  7.   
  8.     static {  
  9.         try {  
  10.             System.loadLibrary("hardcontrol");  
  11.         } catch (Exception e) {  
  12.             e.printStackTrace();  
  13.         }  
  14.     }  
  15.   
  16. }  

5.编辑app/src/main/java/mobiletek/led/MainActivity.java文件,内容如下:
[java]  view plain  copy
  1. package mobiletek.led;  
  2.   
  3. import android.os.RemoteException;  
  4. import android.support.v7.app.AppCompatActivity;  
  5. import android.os.Bundle;  
  6. import android.widget.Button;  
  7. import android.view.View;  
  8. import android.widget.CheckBox;  
  9. import android.widget.Toast;  
  10. import mobiletek.hardlibrary.*;  
  11.   
  12. public class MainActivity extends AppCompatActivity {  
  13.     private boolean ledon = false;  
  14.     private Button button = null;  
  15.   
  16.     private CheckBox checkBoxLed1 = null;  
  17.     private CheckBox checkBoxLed2 = null;  
  18.     private CheckBox checkBoxLed3 = null;  
  19.     private CheckBox checkBoxLed4 = null;  
  20.   
  21.     int []ledctrl = {0x120x340x560x78};  
  22.   
  23.     class MyButtonListener implements View.OnClickListener {  
  24.         @Override  
  25.         public void onClick(View v) {  
  26.             ledon = !ledon;  
  27.             if (ledon) {  
  28.                 button.setText("ALL OFF");  
  29.                 checkBoxLed1.setChecked(true);  
  30.                 checkBoxLed2.setChecked(true);  
  31.                 checkBoxLed3.setChecked(true);  
  32.                 checkBoxLed4.setChecked(true);  
  33.   
  34.                 for (int i = 0; i < 4; i++)  
  35.                     HardControl.ledCtrl(ledctrl[i], 1);  
  36.             }  
  37.             else {  
  38.                 button.setText("ALL ON");  
  39.                 checkBoxLed1.setChecked(false);  
  40.                 checkBoxLed2.setChecked(false);  
  41.                 checkBoxLed3.setChecked(false);  
  42.                 checkBoxLed4.setChecked(false);  
  43.   
  44.   
  45.                 for (int i = 0; i < 4; i++)  
  46.                     HardControl.ledCtrl(ledctrl[i], 0);  
  47.   
  48.             }  
  49.         }  
  50.     }  
  51.   
  52.     public void onCheckboxClicked(View view) {  
  53.         // Is the view now checked?  
  54.         boolean checked = ((CheckBox) view).isChecked();  
  55.   
  56.         // Check which checkbox was clicked  
  57.         switch(view.getId()) {  
  58.             case R.id.LED1:  
  59.                 if (checked) {  
  60.                     Toast.makeText(getApplicationContext(), "LED1 on", Toast.LENGTH_SHORT).show();  
  61.                     HardControl.ledCtrl(ledctrl[0], 1);  
  62.                 }  
  63.                 else {  
  64.                     Toast.makeText(getApplicationContext(), "LED1 off", Toast.LENGTH_SHORT).show();  
  65.                     HardControl.ledCtrl(ledctrl[0], 0);  
  66.                 }  
  67.                 break;  
  68.             case R.id.LED2:  
  69.                 if (checked) {  
  70.                     Toast.makeText(getApplicationContext(), "LED2 on", Toast.LENGTH_SHORT).show();  
  71.                     HardControl.ledCtrl(ledctrl[1], 1);  
  72.                 }  
  73.                 else {  
  74.                     Toast.makeText(getApplicationContext(), "LED2 off", Toast.LENGTH_SHORT).show();  
  75.                     HardControl.ledCtrl(ledctrl[1], 0);  
  76.                 }  
  77.                 break;  
  78.   
  79.             case R.id.LED3:  
  80.                 if (checked) {  
  81.                     Toast.makeText(getApplicationContext(), "LED3 on", Toast.LENGTH_SHORT).show();  
  82.                     HardControl.ledCtrl(ledctrl[2], 1);  
  83.                 }  
  84.                 else {  
  85.                     Toast.makeText(getApplicationContext(), "LED3 off", Toast.LENGTH_SHORT).show();  
  86.                     HardControl.ledCtrl(ledctrl[2], 0);  
  87.                 }  
  88.                 break;  
  89.   
  90.             case R.id.LED4:  
  91.                 if (checked) {  
  92.                     Toast.makeText(getApplicationContext(), "LED4 on", Toast.LENGTH_SHORT).show();  
  93.                     HardControl.ledCtrl(ledctrl[3], 1);  
  94.                 }  
  95.                 else {  
  96.                     Toast.makeText(getApplicationContext(), "LED4 off", Toast.LENGTH_SHORT).show();  
  97.                     HardControl.ledCtrl(ledctrl[3], 0);  
  98.                 }  
  99.                 break;  
  100.         }  
  101.     }  
  102.   
  103.     @Override  
  104.     protected void onCreate(Bundle savedInstanceState) {  
  105.         super.onCreate(savedInstanceState);  
  106.         setContentView(R.layout.activity_main);  
  107.   
  108.         button = (Button)findViewById(R.id.BUTTON);  
  109.         HardControl.ledOpen();  
  110.   
  111.         checkBoxLed1 = (CheckBox) findViewById(R.id.LED1);  
  112.         checkBoxLed2 = (CheckBox) findViewById(R.id.LED2);  
  113.         checkBoxLed3 = (CheckBox) findViewById(R.id.LED3);  
  114.         checkBoxLed4 = (CheckBox) findViewById(R.id.LED4);  
  115.   
  116.         button.setOnClickListener(new MyButtonListener());  
  117.   
  118.         /* 
  119.         button.setOnClickListener(new View.OnClickListener() { 
  120.             public void onClick(View v) { 
  121.                 // Perform action on click 
  122.                 ledon = !ledon; 
  123.                 if (ledon) 
  124.                     button.setText("ALL OFF"); 
  125.                 else 
  126.                     button.setText("ALL ON"); 
  127.             } 
  128.         }); 
  129.         */  
  130.     }  
  131. }  

6.
修改app/build.gradle文件:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        applicationId "mobiletek.led"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
    }
+    sourceSets {
+       main {
+           jniLibs.srcDirs = ['libs']
+      }
+   }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:25.1.0'
}


7.
编译,生成apk,安装到开发板,打开app,即可操作LED。

编译生成的libhardcontrol.so可以不随apk一起打包,单独放在/system/lib或者/vendor/lib目录均可,这样,就不需要新建armeabi目录,也不需要修改app/build.gradle文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android JNI是一种可用于在Java代码调用C/C++代码的技术,驱动ko则是指内核模块文件,通常用于实现与硬件设备的交互。在Android应用,我们可以使用JNI来调用驱动ko,实现与底层硬件的交互。 要在Android应用调用驱动ko,首先需要在应用使用JNI技术编写C/C++代码,实现与驱动ko的交互逻辑。在C/C++代码,我们可以通过使用Linux系统提供的API来访问并且控制驱动ko。通过JNI,我们可以将C/C++代码嵌入到Java代码,并在Android应用调用这些代码。 具体来说,调用驱动ko的过程如下: 1. 在JNI层编写与驱动ko交互的C/C++代码。这些代码可以使用Linux系统提供的ioctl函数等API来与驱动ko进行通信,并发送相应的指令和数据。 2. 在Java层编写对应的JNI接口和方法。这些方法将与JNI层的C/C++代码进行绑定,以便在Java代码调用这些方法来间接调用驱动ko。 3. 在Java代码加载JNI库,并调用JNI接口方法。加载JNI库可以使用System.loadLibrary方法,然后在Java代码就可以调用JNI接口方法,进而间接调用驱动ko。 通过这种方式,我们可以在Android应用通过JNI技术调用驱动ko,实现与底层硬件的交互。注意,使用JNI调用驱动ko需要确保设备具备相应的权限,否则可能会出现权限不足的错误。同时,也需要确保驱动ko文件存在于系统,并且可以被应用访问到。 总之,使用Android JNI可以实现在应用调用驱动ko文件的功能,通过编写C/C++代码并与Java代码进行绑定,实现与底层硬件交互的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值