求问:Jnijs 调用js 路径手机红外驱动路径

4151人阅读
android(29)
android应用怎么调用驱动的结构层次:
& android应用
& & & & | 通过native实现
& C/C++代码
& && && | 通过open(close、ioctl、write、read)操作设备
& C设备驱动
从上面可以看得出,上层android应用要调用底层驱动,简单的方式就是,先通过native调用C/C++,再通过open(close、ioctl、write、read)动作,操作驱动,就是那么一个过程。
上一篇文章已经说过:C/C++怎么调用驱动程序
下面说一下android应用是怎么通过native调用C/C++代码的,可以将native方法比作Java程序同C程序的接口,其实现步骤:
&&& 1、在Java中声明native()方法,然后编译;
&&& 2、用javah产生一个.h文件;
&&& 3、写一个.c文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);
&&& 4、将第三步的.c文件编译成动态链接库文件.SO;
&&& 5、在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。
首先创建一个android项目,写一个代码控制这个led的亮灭,代码如下:
public class NativeExampleActivity extends Activity {
TextView textView01;
private Button btnS
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnStart = (Button) this.findViewById(R.id.btnStart);
btnStart.setOnClickListener(clickButtonStart);
textView01 = (Button) this.findViewById(R.id.btnStart);
OnClickListener clickButtonStart = new OnClickListener()
public void onClick(View v) {
// TODO Auto-generated method stub
//textView01.setText(&led state: &+ledFunction(0));
textView01.setText(&led state: &+ledFunction(1));
System.loadLibrary(&org_natives_example_NativeExampleActivity&);//加载库文件,系统会自动处理成lib***.so
} catch (Throwable t) {
public native int ledFunction(int a);//native方法,控制led的亮灭
&&& 然后在工程的bin/classes目录下在cmd中执行javah -jni org.natives.example.NativeExampleActivity,
&&& 就会在根目录下得到一个org_natives_example_NativeExampleActivity.h的文件
&&& 然后根据头文件的内容编写org_natives_example_NativeExampleActivity.c文件
#include &com_hode_hodeframework_modelupdate_CheckFile.h&
JNIEXPORT jint JNICALL Java_org_natives_example_NativeExampleActivity_ledFunction(JNIEnv *, jobject, jint a)
fd = open(&/dev/vib&,O_RDWR);//Open device ,get the handle
ioctl(fd,0x22); //call the output function to on LEDs
ioctl(fd,0x11); //call the output function to off LEDs
ret = close(fd); //close device
之后编译生成so文件如“liborg_natives_example_NativeExampleActivity.so”,名称与System.loadLibrary(&org_natives_example_NativeExampleActivity&)中的名称一致
Android.mk文件如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE
:= liborg_natives_example_NativeExampleActivity
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES
:= org_natives_example_NativeExampleActivity.c
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
LOCAL_SHARED_LIBRARIES := libutils
include $(BUILD_SHARED_LIBRARY)
把编译生成的库.so和之前的驱动.ko文件push到手机,下载应用,led就可以跑起来了。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:384735次
积分:3801
积分:3801
排名:第5243名
原创:37篇
转载:22篇
评论:357条
(5)(3)(2)(1)(1)(4)(6)(5)(3)(5)(3)(8)(4)(3)(1)(2)(1)(1)(1)要想用java去调用C函数接口那么就需要使用JNI(Java Native Interface,Java 本地调用)去访问本地的动态链接库。
关于NDK的安装,现在有linux环境下的版本,也有windows环境下的版本,这个可自行百度,这里不多说
在eclipse中配置NDK:打开我们的eclipse-&window-&preference-&android-&ndk设置ndk路径-&ok。
1、使用cygwin编译生成.so文件:右键单击项目-&Android Tools-&Add Native Support...-&.so文件命名例如test-&ok。
    完成之后eclipse会生成一个jni文件夹,里面会生成一个test.cpp的文件。
    但是我一般不用这个文件,直接delete,新建三个文件(.h .c .mk)。
    .h和.c文件是用来编写kernel访问接口,可以直接调用驱动程序里的函数,这里需要注意命名规则:Java_包名_类名_接口名,此类表示调用.h中的方法的类
    .mk文件是用来编译生成.so文件的,这里需要注意LOCAL_MODULE := HelloJni,表示生成HelloJni.so库,
      在java中调用该库的入口是System.loadLibrary("HelloJni");
2、使用脚本编译的配置方法
在NDKr7开始,google的windos版NDK提供了一个ndk-build.cmd的脚本,这样就可以直接利用这个脚本编译,而不需要cygwin了。
1、选择你的android工程,右击-&Properties-&Builders-&new,新添加一个编译器,点击之后出现添加界面,选择Program,点击ok。
2、出现了添加界面,我们先给编译器设置名称,如XXX_builder。设置Location为&NDK安装目录&\ndk-build.cmd
设置Working Directory为${workspace_loc:/项目名称}
3、切换到Refersh选项卡,给Refersh resources upon completion打上勾,选择&the entire resource&选项
4、切换到Build Options选项卡,勾选上最后三项。再点击Specify Resource按钮,选择你的android工程
5、在编译工具列表,我们最好将我们新建的编译器置顶。选中点击Up按钮置顶ok.
样例如下:
1、com_pngcui_HelloJni.h&&&& //命名规则:Java_包名_类名_接口名
1 /* DO NOT EDIT THIS FILE - it is machine generated */
2 #include &jni.h&
3 /* Header for class com_neojet_scanner_key */
5 #ifndef _Include_com_pngcui_helloJni
6 #define _Inlcude_com_pngcui_helloJni
8 #ifdef _cplusplus
9 extern "C"{
/*Java_packagename_classname_methodname*/
/*open()*/
JNIEXPORT jint JNICALL Java_com_pngcui_helloJni_HelloJni_Open
(JNIEnv *,jobject);
/*close()*/
JNIEXPORT jint JNICALL Java_com_pngcui_helloJni_HelloJni_Close
(JNIEnv *,jobject);
/*ioctl()*/
JNIEXPORT jint JNICALL Java_com_pngcui_helloJni_HelloJni_Ioctl
(JNIEnv *,jobject,jint num,jint en);
25 #ifdef _cplusplus
2、com_pngcui_HelloJni.c    //实现.h方法
1 #include &stdio.h&
2 #include &stdlib.h&
3 #include &fcntl.h&
4 #include &errno.h&
5 #include &unistd.h&
6 #include &sys/types.h&
7 #include &sys/stat.h&
8 #include &string.h&
9 #include &stdint.h&
10 #include &termios.h&
11 #include &android/log.h&
12 #include &sys/ioctl.h&
14 #include "com_pngcui_helloJni.h"
16 #undef TCSAFLUSH
17 #define TCSAFLUSH TCSETSF
18 #ifndef _TERMIOS_H_
19 #define _TERMIOS_H_
23 int fd = 0;
26 /*open()*/
27 JNIEXPORT jint JNICALL Java_com_pngcui_helloJni_HelloJni_open
(JNIEnv *env , jobject obj){
/*只允许打开一次设备!*/
fd = open("/dev/jni",O_RDWR|O_NDELAY|O_NOCTTY);
__android_log_print(ANDROID_LOG_INFO,"serial","open /dev/jni Error..");
__android_log_print(ANDROID_LOG_INFO,"serial","open /dev/jni Sucess fd = %d",fd);
38 JNIEXPORT jint JNICALL Java_com_pngcui_helloJni_HelloJni_close
(JNIEnv *env,jobject obj){
if(fd & 0)
close(fd);
45 JNIEXPORT jint JNICALL Java_com_pngcui_helloJni_HelloJni_ioctl
(JNIEnv *env,jobject obj,jint num , jint en){
ioctl(fd,en,num);
3、Android.mk
1 LOCAL_PATH := $(call my-dir)
2 include $(CLEAR_VARS)
3 LOCAL_MODULE
:= HelloJni
4 LOCAL_SRC_FILES := com_pngcui_helloJni.c
5 LOCAL_LDLIBS += -llog
6 LOCAL_LDLIBS +=-lm
7 include $(BUILD_SHARED_LIBRARY)
在android.mk文件中我们可以知道最后会生成一个libHelloJni.so本地库文件。
  LOCAL_PATH - 编译时的目录     $(call
目录,目录&.)
目录引入操作符     如该目录下有个文件夹名称
src,则可以这样写
src),那么就会得到
目录的完整路径
  include
$(CLEAR_VARS) -清除之前的一些系统变量  LOCAL_MODULE
编译生成的目标对象  LOCAL_SRC_FILES
编译的源文件  LOCAL_C_INCLUDES
需要包含的头文件目录  LOCAL_SHARED_LIBRARIES
链接时需要的外部库  LOCAL_PRELINK_MODULE
是否需要prelink处理
  include$(BUILD_SHARED_LIBRARY)
指明要编译成动态库
把以上三个文件放入jni文件夹中,最后编写一个java类,也就是命名规则的那个java类名
1 package com.pngcui.helloJ
3 public class Jni {
public native int
public native int
public native int
Ioctl(int num, int en);
最后在调用Jni.java的类中需要声明本地库的路径
1 static {
System.loadLibrary("HelloJni");
附上完整的MainActivity.java代码
1 package com.pngcui.helloJ
3 import android.app.A
4 import android.os.B
5 import android.view.V
6 import android.view.View.OnClickL
7 import android.widget.B
9 public class MainActivity extends Activity {
Jni jni = new Jni();
private Button y1;
private Button y2;
private Button n1;
private Button n2;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
y1 = (Button)findViewById(R.id.y1);
y2 = (Button)findViewById(R.id.y2);
n1 = (Button)findViewById(R.id.n1);
n2 = (Button)findViewById(R.id.n2);
start = (Button)findViewById(R.id.start);
jni.Open();
y1.setOnClickListener(new manager());
n1.setOnClickListener(new manager());
y2.setOnClickListener(new manager());
n2.setOnClickListener(new manager());
start.setOnClickListener(new manager());
class manager implements OnClickListener{
public void onClick(View v) {
//gpio_set_value(led_gpio[i],cmd),且二极管为低电平有效
switch(v.getId()){
case R.id.y1:
jni.Ioctl(0, 0);
case R.id.n1:
jni.Ioctl(0, 1);
case R.id.y2:
jni.Ioctl(1, 0);
case R.id.n2:
jni.Ioctl(1, 1);
case R.id.start:
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
private void start() throws InterruptedException {
// TODO Auto-generated method stub
while(i&0){
jni.Ioctl(1, 0);
jni.Ioctl(0, 1);
Thread.sleep(200);
jni.Ioctl(1, 1);
jni.Ioctl(0,0);
Thread.sleep(200);
jni.Ioctl(1, 0);
System.loadLibrary("HelloJni");
最后还有一个问题,那就是权限问题!也就是说到现在我们还没有给我们的驱动程序生成的设备节点设置权限,也就是可读可写权限,如果不设置这个权限,那么我们的android应用时无法打开设备节点的!!!在调用open函数时会直接返回-1!!而在exynos4412平台上的android设置权限的文件在device/samsung/smdk4x12/conf/init.smdk4x12.rc中,而不是网上说的和文件中,但是!!本人在里面设置了chmod 777 /dev/jni 依旧不能正常open,百思不得其解,有哪位大神知道怎么去自动设置权限,还麻烦教导我一下,不甚感激!
附上蠢蠢的解决办法:在串口终端使用命令chmod 777 /dev/jni然后运行app,可暂时性解决此问题,但是开发板重启以后就需要重修设置权限!!
--------------------------------- update------------------------------------------------------
权限问题的解决方案:为什么在脚本中写了chmod命令还是不能open设备文件,因为没有烧写ramdisk.img文件啊啊啊啊!!!只烧写了system.img,因为rc脚本会编译到ramdisk镜像中。
参考链接:
最后附上查看设备权限命令:ls -al /dev/xxx
r:&对应数值4w:&对应数值2x:对应数值1-:对应数值0
eg。-rwxrwxrwx& 对应0777 即所有用户都可读可写可执行
---------------------补充驱动函数返回数据到java中----------------------
如果需要读取底层硬件状态等信息,并返回到app上,则需要使用jni里的方法去调用驱动函数的ioctl,而不能直接在java中写data = jni.Ioctl(a,b);
1 JNIEXPORT jint JNICALL Java_com_pngcui_fm_Jni_GetData
(JNIEnv *env,jobject obj,jint cmd ){
jint data = 0;
data = ioctl(fd,cmd,0);
使用如上方法才能正常返回!
阅读(...) 评论()当前位置: →
→ 转Android通过JNI调用驱动程序完全解析实例
转Android通过JNI调用驱动程序完全解析实例
& 作者及来源: 翔如飞飞 - 博客园 &
&收藏到→_→:
摘要: 【转】Android通过JNI调用驱动程序(完全解析实例)
"转Android通过JNI调用驱动程序完全解析实例"::
android通过jni调用驱动程序(完全解析实例)&要达到的目的:android系统中,用java写界面程序,调用jni中间库提供的接口,去操作某个驱动节点,实现read,writer ioctl等操作!这对底层人员是很重要的一个调试通道,也是android 系统下提供一些特殊功能接口的方法!本文前提:我们假设已经写了一个驱动程序,它是控制led的亮灭的,并且创建了一个节点:/dev/vib,也就是通过open这个vib节点,可以read/write/ioctl 操作驱动程序实现led灯的亮灭控制,具体可以看我另一篇博文《android驱动例子(led灯控制)》开发环境&1、ubuntu下的ndk编译环境,2、esclips开发环境一、编写jni模块当安装好ndk编译环境后,会在它的目录下找到sample目录,它里面有一些例子,可以参考这些例子来写我们自已的模块。1、 source文件夹下,新建“ledsjni”文件夹。2、 source/ledsjni/jni/目录下,新建“vib-jni.c”vib-jni.c文件#include &string.h&#include &jni.h&#include &fcntl.h& /*包括文件操作,如open() read() close() write()等*///----for output the debug log message#include &android/log.h&#define
"vib-jni"#define
__android_log_print(android_log_info,log_tag,__va_args__)#define
__android_log_print(android_log_error,log_tag,__va_args__)#define
device_name
"/dev/vib"
//device point#define
vib_on 0x11#define
vib_off 0x22intjstringjava_com_auly_control_vibclass_stringfromjni( jnienv* env,
jobject thiz ){
return (*env)-&newstringutf(env, "hello from jni--peter for vib!");//打印字符串} jint
java_com_auly_control_vibclass_init( jnienv*
loge("vibclass_init() /n");
fd = open(device_name,o_rdwr);//打开设备
loge("vibclass_init()-& fd = %d
if(fd == -1)
loge("open device %s error /n ",device_name);//打印调试信息
}} jint java_com_auly_control_vibclass_ioctlvib( jnienv*
env, jobject
thiz, jint controlcode ){
int ctlcode =
loge("ioctlvib() = %x --vibclass_ioctlvib /n",ctlcode);
switch(ctlcode)
case vib_on:
ioctl(fd,vib_on);//调用驱动程序中的ioctrl接口,把命令vib_on传下去,实现硬件操作
case vib_off:
ioctl(fd,vib_off);//调用驱动程序中的ioctrl接口,把命令vib_off传下去,实现硬件操作
default:break;
return 1; }3、相同目录下的新建android.mk如下android.mk文件local_path := $(call my-dir)include $(clear_vars)local_module
:= vib-jnilocal_src_files := vib-jni.clocal_cflags
:= -werrorlocal_ldlibs
:= -llog -lglesv2 //__android_log_print 函数include $(build_shared_library)可以看到,主要是修改local_src_files指向源文件的名称!还有一点很重要,如果要使用调试log 打印,也就是__android_log_print 函数。要在local_ldlibs中添加-llog,如上面的android.mk所示。4、编译jni模块#cd /home/workspace/android-ndk-r4b/sources/ledsjni进到刚才写的jni目录&#ndk-build编译jni,编译成功后,会在ledsjni文件夹下生成libs和obj两个文件夹,并在ledsjni/libs/armeabi下得到目标文件libvib-jni.so(目前ledsjni文件夹只有3个目录jni,libs,obj)二、java程序1、eclipse新建工程拷贝ledsjni目录到windows下,例如c盘下。然后在它里面新建eclipse 工程。新键工程后,x-210开发板(代码开放度高,xboot很牛) &&mini210开发板&(友善的板子,有沉淀)2、入门级嵌入式开发板 arm11内核 &,价格在500~650之间tiny6410&& &(友善之臂经典之作) & &&ok6410&& &(特点是支持wince7.0)可以去风火轮团队的店里看一下此文来自: 马开东博客
转载请注明出处 网址:
,在他们那里买板有个好处,他们提从更周到的技术支持风火轮技术开发团队 &www.官方淘宝店:&&原文地址:http://blog.csdn.net/ok138ok/article/details/6560875&&搜索此文相关文章:此文来自: 马开东博客
网址: 站长QQ
转Android通过JNI调用驱动程序完全解析实例_博客园相关文章
博客园_总排行榜
博客园_最新
博客园_月排行榜
博客园_周排行榜
博客园_日排行榜android调用JNI报Fatal signal 11 (SIGSEGV) at XXXXX的问题,高分求教大家!!!!!
[问题点数:100分,结帖人lanjian1111]
android调用JNI报Fatal signal 11 (SIGSEGV) at XXXXX的问题,高分求教大家!!!!!
[问题点数:100分,结帖人lanjian1111]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2013年3月 总版技术专家分月排行榜第三
2014年5月 移动开发大版内专家分月排行榜第一2014年4月 移动开发大版内专家分月排行榜第一
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。

我要回帖

更多关于 js 调用js 路径 的文章

 

随机推荐