android駆動からアプリケーションへ(二)
JAVAアプリケーションはJNIを呼び出してドライバにアクセスする
以下はLedテストプログラムの例であり、ドライバリファレンス(一)
具体的な手順: eclipseでandroidエンジニアリング(TestLed)を作成します.以下はデフォルトで生成されたJAVAコードです. ローカルメソッド をプログラムに追加するプロジェクトディレクトリに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): 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ファイル:
以下はLedテストプログラムの例であり、ドライバリファレンス(一)
具体的な手順:
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");
}
$ cd workspace/TestLed/
$ mkdir jni
プロジェクトホームにコマンドを入力:$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
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
",fd);
if(-1 == fd)
{
LOG_INFO("open led_devices is failed!\r
");
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
");
return -1;
}
if(cmd!=0 && cmd!=1)
{
LOG_ERROR("This conmand is not surport!\r
");
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
");
break;
}
return 0;
}
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 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)
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!