android 从驱动到应用(二)

JAVA应用程序通过调用JNI来访问驱动程序


下面是一个Led测试程序例子,驱动程序参考(一)

具体步骤:

  • 用eclipse创建一个android工程(TestLed),以下是默认生成的JAVA代码:
package com.android;

import android.app.Activity;
import android.os.Bundle;

public class TestLedActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
  •  在程序中添加本地方法
	// 添加本地实现方法
	public native int OpenLed();
	public native int ControlLed(int led_id, int cmd);
	// 添加 C/C++动态库导入方法
	static {
		System.loadLibrary("yyp_led_lib");
	}
  • 在工程目录中建立一个jni文件夹
$ cd workspace/TestLed/

$ mkdir jni

  • 用javah命令生成头文件

在工程主目录中输入命令:$ javah -classpath bin/classes/ -d jni com.android.TestLedActivity

说明:
-classpath bin/classes/:表示类的路径在 bin/classes 目录;
-d jni 表示.h 头文件的生成路径;
com.android.TestLedActivity:由 package.class 组成。

命令执行成功后发现在jni文件夹生成头文件com_android_TestLedActivity.h

$ ls jni
com_android_TestLedActivity.h

  • 创建C/C++文件 实现头文件接口

刷新eclipse工程,右键点击jni目录,创建yyp_led_lib.c文件并编辑(jni->New->File):

#include <string.h>
#include <jni.h>
#include <fcntl.h>//文件操作
#include "android/log.h"

static const char *TAG = "yyp_jni";

#define LOG_INFO(fmt,args...)		__android_log_print(ANDROID_LOG_INFO, TAG,fmt, ##args)
#define LOG_DEBUG(fmt, args...)		__android_log_print(ANDROID_LOG_DEBUG, TAG,fmt, ##args)
#define LOG_ERROR(fmt, args...) 	__android_log_print(ANDROID_LOG_ERROR, TAG, fmt,##args)
#define DEVICE_NAME		"/dev/yyp_led"



int fd;

JNIEXPORT jint JNICALL Java_com_android_ledtest_LedTestActivity_OpenLed
  (JNIEnv *env, jobject this)
{
	fd = open(DEVICE_NAME,O_RDWR|O_SYNC);
	LOG_INFO("fd = %d\r\n",fd);
	if(-1 ==  fd)
	{
		LOG_INFO("open led_devices is failed!\r\n");
		return -1;
	}
	return 0;
}

JNIEXPORT jint JNICALL Java_com_android_ledtest_LedTestActivity_ControlLed
  (JNIEnv *ent, jobject this, jint led_id, jint cmd)
{
	if (-1 == fd) {
		LOG_ERROR("Led Module is not open!\r\n");
		return -1;
	}
	if(cmd!=0 && cmd!=1)
	{
		LOG_ERROR("This conmand is not surport!\r\n");
		return -2;
	}
	switch (led_id) {
	case 1:
		ioctl(fd, cmd, 0);
		break;
	case 2:
		ioctl(fd, cmd, 1);
		break;
	case 3:
		ioctl(fd, cmd, 2);
		break;
	case 4:
		ioctl(fd, cmd, 3);
		break;
	case 0:
		ioctl(fd, cmd, 0);
		ioctl(fd, cmd, 1);
		ioctl(fd, cmd, 2);
		ioctl(fd, cmd, 3);
		break;
	default:
		LOG_ERROR("This led is not exit!\r\n");
		break;
	}
	return 0;
}

  • 创建jni中C/C++文件中对应的makefile文件

在jin文件夹创建Android.mk文件($ vim jni/Android.mk)并编辑:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := yyp_led_lib
LOCAL_SRC_FILES := yyp_led_lib.c
include $(BUILD_SHARED_LIBRARY)

  • 用ndk-build生成 .so文件

在工程目录中输入ndk-build命令:

$ ndk-build
Compile thumb  : yyp_led_lib <= yyp_led_lib.c
SharedLibrary  : libyyp_led_lib.so
Install        : libyyp_led_lib.so => libs/armeabi/libyyp_led_lib.so

刷新eclipse工程,发现在libs目录中多了.so文件(libs/armeabi/libyyp_led_lib.so)

  • 在eclipse工程中添加led控制按钮,达到在JAVA应用程序中控制led的效果
    编辑TestLedActivity.java文件:

    package com.android;
    
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class TestLedActivity extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            // 打开Led驱动
            OpenLed();
    		Button key_led1_on = (Button) findViewById(R.id.led1_on);
    		key_led1_on.setOnClickListener(new View.OnClickListener() {
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				ControlLed(1, 1);
    			}
    		});
    
    		Button key_led2_on = (Button) findViewById(R.id.led2_on);
    		key_led2_on.setOnClickListener(new View.OnClickListener() {
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				ControlLed(2, 1);
    
    			}
    		});
    
    		Button key_led3_on = (Button) findViewById(R.id.led3_on);
    		key_led3_on.setOnClickListener(new View.OnClickListener() {
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				ControlLed(3, 1);
    			}
    		});
    
    		Button key_led4_on = (Button) findViewById(R.id.led4_on);
    		key_led4_on.setOnClickListener(new View.OnClickListener() {
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				ControlLed(4, 1);
    			}
    		});
    
    		Button key_led0_on = (Button) findViewById(R.id.led0_on);
    		key_led0_on.setOnClickListener(new View.OnClickListener() {
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				ControlLed(0, 1);
    			}
    		});
    
    		Button key_led0_off = (Button) findViewById(R.id.led0_off);
    		key_led0_off.setOnClickListener(new View.OnClickListener() {
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				ControlLed(0, 0);
    			}
    		});
        }
    	// 添加本地实现方法
    	public native int OpenLed();
    	public native int ControlLed(int led_id, int cmd);
    	// 添加 C/C++动态库导入方法
    	static {
    		System.loadLibrary("yyp_led_lib");
    	}
    }
    分别在main.xml和strings.xml添加相应的控件和字符串:
    main.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello" />
        <Button
            android:id="@+id/led1_on"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:text="@string/LEDON1"></Button>
        <Button
            android:id="@+id/led2_on"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:text="@string/LEDON2"></Button>
    	<Button
            android:id="@+id/led3_on"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:text="@string/LEDON3"></Button>
        <Button
            android:id="@+id/led4_on"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:text="@string/LEDON4"></Button>
    	<Button
            android:id="@+id/led0_on"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:text="@string/LEDON0"></Button>
    	<Button
            android:id="@+id/led0_off"
    		android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:text="@string/LEDOFF0"></Button>
    
    </LinearLayout>

    strings.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string name="hello">This is a led TestApp!</string>
        <string name="app_name">ledtest</string>
        <string name="LEDON1">开启1号灯</string>
        <string name="LEDON2">开启2号灯</string>
        <string name="LEDON3">开启3号灯</string>
        <string name="LEDON4">开启4号灯</string>
        <string name="LEDON0">开启所有灯</string>
        <string name="LEDOFF0">关闭所有灯</string>
    
    </resources>

    编译成apk,运行测试,ok!





  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值