Android驱动(一)硬件访问服务学习之(四)Android应用程序APP编写

2023-05-16

  • 硬件平台:tiny4412
  • 系统:Android  5.0.2
  • 编译器: arm-linux-gcc-4.5.1

(一)Android通过JNI访问硬件

http://blog.csdn.net/fengyuwuzu0519/article/details/55224423

(二)Android通过硬件访问服务访问硬件

http://blog.csdn.net/fengyuwuzu0519/article/details/55271199

(三)Android加入HAL层访问硬件

http://blog.csdn.net/fengyuwuzu0519/article/details/55274891

现在我们写一个Android APP软件,来操作硬件。本文重点在于说明如何写一个硬件访问服务的APP,重点不在于APP的编写。

一、通过XML编写界面(简单)


二、通过java编译activity内容实现逻辑(简单)

(1)获取组件

(2)监听事件

三、APP调用硬件访问服务的编写要点

1、java通过JNI直接操作硬件

(1)HardControl.JAVA

加载C库,JNI的第一步

package com.example.yangfei.hardlibrary;
public class HardControl {
    public static native int ledCtrl(int which, int status);
    public static native int ledOpen();
    public static native void ledClose();//申明三个本地方法。
 
    static {
        try {
            System.loadLibrary("hardcontrol");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

(2)修改build.gradle,添加

sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}

指定SO库的路径

(3)在app/libs下建armeabi子目录,放入so文件


(4)操作硬件


HardControl hardControl = new HardControl();//依赖硬件  

HardControl hardControl = new HardControl();//依赖硬件
HardControl.ledCtrl(2, 1);

(5)JNI编译出SO,注意里面包名的信息  
#include <jni.h>  /* /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
 
#include <android/log.h>  /* liblog */
 
//__android_log_print(ANDROID_LOG_DEBUG, "JNIDemo", "native add ...");
#if 0
typedef struct {
    char *name;          /* Java里调用的函数名 */
    char *signature;    /* JNI字段描述符, 用来表示Java里调用的函数的参数和返回值类型 */
    void *fnPtr;          /* C语言实现的本地函数 */
} JNINativeMethod;
#endif
static jint fd;
jint ledOpen(JNIEnv *env, jobject cls)
{
	fd = open("/dev/leds", O_RDWR);
	__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native ledOpen : %d", fd);
	if (fd >= 0)
		return 0;
	else
		return -1;
}
void ledClose(JNIEnv *env, jobject cls)
{
	__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native ledClose ...");
	close(fd);
}
jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status)
{
	int ret = ioctl(fd, status, which);
	__android_log_print(ANDROID_LOG_DEBUG, "LEDDemo", "native ledCtrl : %d, %d, %d", which, status, ret);
	return ret;
}
static const JNINativeMethod methods[] = {
	{"ledOpen", "()I", (void *)ledOpen},
	{"ledClose", "()V", (void *)ledClose},
	{"ledCtrl", "(II)I", (void *)ledCtrl},
};
/* System.loadLibrary */
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *jvm, void *reserved)
{
	JNIEnv *env;
	jclass cls;
	if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {
		return JNI_ERR; /* JNI version not supported */
	}
	cls = (*env)->FindClass(env, "com/example/yangfei/hardlibrary/HardControl");
	if (cls == NULL) {
		return JNI_ERR;
	}
	/* 2. map java hello <-->c c_hello */
	if ((*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0])) < 0)
		return JNI_ERR;
	return JNI_VERSION_1_4;
}

从C文件编译出SO库:

arm-linux-gcc -fPIC -shared hardcontrol.c -o libhardcontrol.so -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/  -nostdlib /work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/libc.so -I /work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/include /work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/liblog.so

为什么这么编译


-I/usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ : jni.h的存放目录


-nostdlib  不使用标准库 是android系统源码里的 如下:


/work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/libc.so   : 指定libc.so,因为依赖于这个库

加入打印信息

__android_log_print(ANDROID_LOG_DEBUG,"LEDDemo", "native ledOpen ...");


I /work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/include


/work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/liblog.so


为什么这么编译SO详细见http://blog.csdn.net/fengyuwuzu0519/article/details/55224423

2、java通过硬件访问服务操作硬件

(1)操作硬件

import android.os.ILedService;

private ILedService iLedService = null ;

iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));

iLedService.ledCtrl(1, 1);

(2)import android.os.ILedService;本地并没有所以:

需要包含点什么,参考:

http://stackoverflow.com/questions/7888191/how-do-i-build-the-android-sdk-with-hidden-and-internal-apis-available

怎么包含参考:

https://www.jetbrains.com/idea/help/configuring-module-dependencies-and-libraries.html

(3)import android.os.ServiceManager;

(4)iLedService.ledCtrl(i, 1)增加try catch

(5)编译报错 java.lang.OutOfMemoryError: GC overhead limitexceeded:

参考:

http://stackoverflow.com/questions/25013638/android-studio-google-jar-causing-gc-overhead-limit-exceeded-error

build.gradle android加入:

dexOptions {
        javaMaxHeapSize "4g"
    }


(5)编译报错: Too many field references

参考:

Building Apps with Over 65K Methods

https://developer.android.com/tools/building/multidex.html

AndroidManifest.xml增加:

    <application
        android:name=“android.support.multidex.MultiDexApplication”

build.gradle defaultConfig加入:

        multiDexEnabled true

四、linux驱动之LED

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
 
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
 
static int led_gpios[] = {
	EXYNOS4212_GPM4(0),
	EXYNOS4212_GPM4(1),
	EXYNOS4212_GPM4(2),
	EXYNOS4212_GPM4(3),
};
 
static int led_open(struct inode *inode, struct file *file)
{
	/* 配置GPIO为输出引脚 */
	int i;
	for (i = 0; i < 4; i++)
		s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT);
	
	return 0;
}
 
/* app : ioctl(fd, cmd, arg) */
static long led_ioctl(struct file *filp, unsigned int cmd,
		unsigned long arg)
{
	/* 根据传入的参数设置GPIO */
	/* cmd : 0-off, 1-on */
	/* arg : 0-3, which led */
 
	if ((cmd != 0) && (cmd != 1))
		return -EINVAL;
	
	if (arg > 4)
		return -EINVAL;
	
	gpio_set_value(led_gpios[arg], !cmd);
	
	return 0;
}
 
static struct file_operations leds_ops = {/* 结构 */
    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open   =   led_open,     
	.unlocked_ioctl	= led_ioctl,
	
};
 
static int major;
static struct class *cls;
 
int leds_init(void)/* 入口函数 */
{
	major = register_chrdev(0, "leds", &leds_ops);
 
	/* 为了让系统udev,mdev给我们创建设备节点 */
	/* 创建类, 在类下创建设备 : /sys */
	cls = class_create(THIS_MODULE, "leds");
	device_create(cls, NULL, MKDEV(major, 0), NULL, "leds"); /* /dev/leds */
	
	return 0;
}
 
void leds_exit(void)/* 出口函数 */
{
	device_destroy(cls, MKDEV(major, 0));
	class_destroy(cls);
	unregister_chrdev(major, "leds");
}
 
module_init(leds_init);
module_exit(leds_exit);
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.100ask.net");

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android驱动(一)硬件访问服务学习之(四)Android应用程序APP编写 的相关文章

随机推荐

  • Chrome解决“github.com拒绝了我们的访问请求”

    目录 1 网站查询特定IP 2 host文件修改 3 刷新DNS 如果你在Chrome访问github com时出现以下错误 xff1a 本博主之前的Chrome和Edge都无法访问github官网 xff0c 然后就来到了万能的C站找到了
  • STC12C5A60S2_LCD1602驱动

    文章目录 LCD1602 HLCD1602 cmain c LCD1602 H 代码如下 xff1a span class token macro property span class token directive hash span
  • 猿创征文|机器学习实战(8)——随机森林

    目录 1 随机森林 2 极端随机树 3 特征重要性 4 提升法 4 1 AdaBoost 4 2 梯度提升 机器学习实战 xff08 7 xff09 中我们已经提到 xff0c 随机森林是决策树的集成 xff0c 通常用bagging方法训
  • 总结2014——迷茫以及迷茫过后的坚持

    首先 xff0c 借用一句话和大家共勉 xff1a 少一些功利主义的追求 xff0c 多一些不为什么的坚持 xff01 xff01 不知不觉15年也快过了1个月了 xff0c 还是想着要为14年做一下总结 xff1a 记录一下自己的历程 今
  • 汇编总结:lea指令

    ea指令变种 按大小分类 leaw 2个字节 leal 4个字节 leaq 8个字节 lea的用法 leaq a b c d rax 首先lea指令是mov指令的变种 xff0c 据说 xff0c lea指令是x86体系结构中 xff0c
  • CMake语法—选项(option)

    CMake语法 选项 xff08 option xff09 1 选项 1 1 定义 1 2 说明 variable 选项名help text 描述 解释 备注value 选项初始化值 xff08 除ON而外全为OFF xff09 2 应用注
  • C++工程:总结 CMake 添加第三方库依赖方式git submodule、 find_library、FetchContent、CPM等

    CMake 已经成为了C 43 43 工程管理的主流方式 xff0c 功能非常强大 xff0c 现在大多数的 C 43 43 库都已经支持CMake xff0c 下面以 jsoncpp 为例 xff0c 介绍几种引入第三方库的方式 1 代码
  • 医学图像——DCMTK、VTK、ITK、RTK、SimpleITK

    1 引言 https github com SINTEFMedtek ITK VTK xff0c 相关童鞋应该很熟悉的 xff0c 而CTK是一个较新的界面库 xff0c 主要用于方便前面两个 TK的界面设计 xff0c 当然也可以作为通用
  • C++中的volatile

    volatile的本意是 易变的 volatile关键字是一种类型修饰符 xff0c 用它声明的类型变量表示可以被某些编译器未知的因素更改 xff0c 比如操作系统 硬件或者其它线程等 遇到这个关键字声明的变量 xff0c 编译器对访问该变
  • 3DTiles】关于GeometricError几何度量误差

    在 3DTiles 的官方文档中详细介绍了关于几何度量误差 Geometric Error 的一些理念和内涵 xff0c 概括来说可以翻译为如下定义 xff1a 几何度量误差 xff0c Geometric Error xff0c 简称 G
  • glPixelStorei 详解 包括像素传输

    3 glPixelStore 像glPixelStorei GL PACK ALIGNMENT 1 这样的调用 xff0c 通常会用于像素传输 PACK UNPACK 的场合 尤其是导入纹理 glTexImage2D 的时候 xff1a C
  • ESLint 简介

    ESLint简介 ESLint是一个用来识别 ECMAScript 并且按照规则给出报告的代码检测工具 xff0c 使用它可以避免低级错误和统一代码的风格 如果每次在代码提交之前都进行一次eslint代码检查 xff0c 就不会因为某个字段
  • IOS VasSonic 粗略见解

    因为项目需求需要在本地缓存html页面 xff0c 优化用户体验 了解到VasSonic 百度了下源码解析但是没有发现IOS的所以只有自己慢慢摸索了 一 类的简单关系 1 SonicEngine 引擎类 代理为 UIWebViewContr
  • axios的详细讲解

    一 axios的特性 axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端 xff0c 简单的理解就是ajax的封装 特性 xff1a 从浏览器中创建 XMLHttpRequests从 node js 创建
  • 无人机飞控算法-姿态估计-欧拉角-旋转矩阵-四元数

    无人机飞控算法 姿态估计 此系列记录了我理解的卡尔曼滤波从0到1的过程 xff0c 从姿态估计到位置估计 xff0c 我们从核心点一个个出发 xff0c 并结合实际模块的应用来一一揭开卡尔曼滤波的神秘面纱 提示 xff1a 在系列文章中 x
  • BMP格式详解

    介绍 数字图像在外存储器设备中的存储形式是图像文件 xff0c 图像必须按照某个已知的 公认的数据存储顺序和结构进行存储 xff0c 才能使不同的程序对图像文件顺利进行打开或存盘操作 xff0c 实现数据共享 图像数据在文件中的存储顺序和结
  • WinHex使用方法详解

    WinHex是由X Ways软件技术公司 xff08 官方网站http www x ways net xff09 开发的一款专业的磁盘编辑工具 xff0c 该工具文如其名 xff0c 是在Windows下运行的十六进制 xff08 hex
  • three.js流动线

    效果 xff1a 先看最基本的 function initThree el options options 61 options const t 61 this appInstance 61 this const width 61 el o
  • OpenGL之FBO(Frame Buffer Object)和多次离屏渲染

    第一次听到离屏渲染的时候觉得很高级 xff0c 遥不可及 xff0c 直到后来做高斯模糊的时候 xff0c 需要通过两次处理来节省性能 xff0c 一直玩一次渲染处理的我这时候才认识FBO xff0c 继而明白了离屏渲染 xff0c 今天抽
  • Android驱动(一)硬件访问服务学习之(四)Android应用程序APP编写

    硬件平台 xff1a tiny4412系统 xff1a Android 5 0 2编译器 xff1a arm linux gcc 4 5 1 xff08 一 xff09 Android通过JNI访问硬件 http blog csdn net