开发工具: Eclipse开发语言: Java和c++ Pcduino跑Android系统让我兴奋了很长时间,也由此幻想了很多有趣的应用。例如 结合Yeelink做远程加电控制;结合微信开放接口与传感器向好友推送信息等等。 当然这些有趣的应用都离不开PCDUINO硬件的操作。那么在Android系统下怎么来操作硬件呢?我想大概有以下几种方式:
1、利用Arduino 库自己写c++程序然后编译成可执行文件,然后把可执行文件拷到PCDUINO中,添加权限,在模拟中端里运行可执行文件。 优点:Arduino库函数完善,非常容易操作。 缺点:貌似和Android开发的应用不能完美的结合。2、利用Android 的Jni编程,直接驱动GPIO。 优点:开发工具简单,利用Eclipse进行交叉编译,同时编译Java和c++代码。并且把硬件操作函数生成.so文件直接打包APK中。 下面我们利用ANDROID NDK来开发一个简单实例: "光电开关控制UI上的灯泡亮灭" 第一步:开发环境的搭建 1、安装Eclipse 2、安装ADT-v20插件(该版本已经直接支持Native编程) 3、安装CDT(编译c++代码) 3、安装android-ndk-r8e(该版本支持Windows,不用在Cygwin下编译了) 按照这种模式搭建的开发环境用起来非常上手,java和c++程序直接交叉编译,然后打包生成APK. 第二步:实例演练 1、新建Android 工程HelloJni,编写Java代码如下(定义本地函数) public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle(getHelloJniData()); } //c++中要实现的函数接口 public native String getHelloJniData(); //从本地函数获得字符串 public native void OpenLed(); //打开LED灯,本例子对应GPIO3 public native void CloseLed(); //关闭LED灯 public native int ReadGpioState(int i); //读取某个GPIO的状态,然后返回给Java层 //库载入代码 static { System.loadLibrary("Hellojni"); //Hellojni本地SO库 } } 2、实现本地c++代码 (此处注意可以利用 javah 生成头文件,也可以自己按照Jni规则写) #define GPIO_MODE_DIR "/sys/devices/virtual/misc/gpio/mode/" #define GPIO_PIN_DIR "/sys/devices/virtual/misc/gpio/pin/" #define GPIO_IF_PREFIX "gpio" JNIEXPORT jstring JNICALL Java_com_hellojni_MainActivity_getHelloJniData (JNIEnv * env, jobject obj ) { return (*env)->NewStringUTF(env, "hello jni"); } JNIEXPORT void JNICALL Java_com_hellojni_MainActivity_OpenLed (JNIEnv * env, jobject obj) //打开LED { __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"OPEN- LED"); memset(path, 0, sizeof(path)); sprintf(path, "%s%s%d", GPIO_MODE_DIR, GPIO_IF_PREFIX, 3); //此处对应地址/sys/devices/virtual/misc/gpio/mode/gpio3 设置为输出 fd = open(path, O_RDWR); write(fd,"1",1); close(fd); memset(path, 0, sizeof(path)); sprintf(path, "%s%s%d", GPIO_PIN_DIR, GPIO_IF_PREFIX, 3); //此处对应地址/sys/devices/virtual/misc/gpio/pin/gpio3 设置为高定平 fd = open(path, O_RDWR); write(fd,"1",1); close(fd); } JNIEXPORT void JNICALL Java_com_hellojni_MainActivity_CloseLed(JNIEnv * env, jobject obj) //关闭LED { __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"CLOSE LED"); memset(path, 0, sizeof(path)); sprintf(path, "%s%s%d", GPIO_MODE_DIR, GPIO_IF_PREFIX, 3); fd = open(path, O_RDWR); write(fd,"1",1); close(fd); memset(path, 0, sizeof(path)); sprintf(path, "%s%s%d", GPIO_PIN_DIR, GPIO_IF_PREFIX, 3); fd = open(path, O_RDWR); write(fd,"0",1); close(fd); } JNIEXPORT jint JNICALL Java_com_hellojni_MainActivity_ReadGpioState (JNIEnv *env, jobject obj,jint i) //读取某个IO口的状态 { char buf[4]; int ret = -1; int fd = -1; int state; memset((void *)buf, 0, sizeof(buf)); memset(path, 0, sizeof(path)); sprintf(path, "%s%s%d", GPIO_PIN_DIR, GPIO_IF_PREFIX, i); fd = open(path, O_RDWR); ret = read(fd, buf, sizeof(buf)); ret = buf[0] - '0'; switch( ret ) { case 0: state=0; // __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"LOW"); 返回LOG调试信息 break; case 1: state=1; // __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"HIGHT"); break; default: state=-1; ret = -1; break; } close(fd); // __android_log_print(ANDROID_LOG_INFO,LOG_TAG,"READ GPIO STATE"); return state; } 3、到这里关键代码就都准备好了,可以直接在Java层调用这些接口函数操作IO了。下面最后再配置一下Eclipse交叉编译环境。 右击HelloJni的工程属性,弹出 窗口,选Builders --->New---NDK_Builder。
到此开发环境搭建完毕!具体的细节哪里有问题,可以问度娘哦!!!
工程文件见附件!!!
感谢Lucifer㊣(1094294)大神的指导!!!
(985.58 KB, 下载次数: 22)