2017年6月,英创公司在ESM6802+10.1”LCD的硬件平台上成功运行Android 7.1.1原生操作系统。2017年8月,ESM6802 Android 版可以支持GPIO、串口、以太网、U盘。后续将进一步完善对CAN、SPI、I2C、WIFI、4G等接口的支持。
Google公司专门为开发Android应用程序提供了集成开发环境Android Studio,涵盖了所有Android应用开发相关的功能。Android应用程序主要使用Java语言编写,要用到开发工具集SDK(Software Development Kit,提供java编译工具、Android系统API等,可以直接在Android Studio中下载)。当应用程序中要直接访问硬件,或者需要提高运行效率时,需要将访问硬件、复杂逻辑部分使用C/C++实现。要在Android Studio中开发编译C/C++代码,需要用到工具集NDK(Native Development Kit,提供C/C++编译工具、API、打包工具等,可直接在Android Studio中下载)。使用NDK可以将C/C++源码编译成动态链接库,供Java调用。由于Java语言要调用C/C++函数需要用到JNI(Java Native Interface)技术,这就要求使用NDK开发C/C++时,C/C++源码要符合JNI规范要求。
图1、ESM6802 Android版本工作分布图
为方便Android用户专注于Android 应用层(Java语言)的开发,英创公司对所支持的硬件接口均提供了符合JNI规范的C/C++动态链接库,用户只需要加载英创的动态链接库,就可以在纯Java语言环境中调用动态链接库中的函数,达到访问硬件资源的目的。如图1所示,用户的工作只是应用层的java程序,英创已完成了其他部分工作。这篇文章会介绍Android Studio的环境搭建,并以Step2_SerialPort为例,来介绍使用Android Studio开发、调试、安装应用到ESM6802的过程。英创对已支持的硬件接口提供对应的应用程序示例,包括C/C++部分的so文件,供用户参考。
Android应用开发更详细的资料请参考开发者网站学习:https://developer.android.google.cn/index.html 。
一、安装android studio开发环境
1、安装android studio
2、下载sdk、ndk工具集
图2、Android Studio Welcome界面
打开Android Studio,在Configure下拉菜单中选择SDK Manager,如下图
图3 SDK Manager界面
选择好Android SDK的保存路径,并在SDK Platforms页面勾选Android 7.1.1(Nougat)选择SDK版本;在SDK Tools页面如上图所示勾选NDK,CMake,LLDB等,点击OK,下载完成即可(不需要国外代理)。
二、新建项目Step2_SerialPort
点击图2中的Start a new Android Studio project,弹出新建工程的导航界面,输入应用名字(首字母大写),Company domain是生成java包的目录,此处最终生成com/emtronix/ccl/step2_serialport目录,此目录用来存放应用程序的Java源代码,点击next:
勾选Phone and Tablet,选择Minimum SDK版本,小于此版本的Android系统可能不能运行该程序。由于这里只安装了7.1.1的sdk,所以选择Android 7.1.1,点击Next。
Android Studio预设了常用的activity模板供开发者选择,这里选择Empty Activity,点击Next。
点击Finish就进入了项目的开发界面。
进入开发界面后点击下图所示位置,选择Project视图,可以更方便观察整个项目的文件结构。
点击File>>Project Structure设置SDK、JDK、NDK的路径:
如果没有安装JDK,可以勾选Use embedded JDK,使用Android Studio内置的jre环境。
三、封装串口类
通过以上步骤,Android Studio已经搭建起了应用开发的基本环境,新建了Step2_SerialPort项目。为了方便管理,可以把所有串口的操作封装成一个串口类。
1、复制英创提供的串口控制类
在src\main\java目录下新建包emtronix.hardware,新建串口控制类SerialControl.java也可以直接复制英创提供的SerialControl.java源文件到emtronix.hardware包。SerialControl中加载了C/C++动态链接库(实现了native函数),并将native函数以公共静态成员方法的形式提供给Java用户调用。
以上native函数,英创已经使用C/C++实现,并编译成了libSerialControl.so库文件,用户只需要将so库添加到项目中即可(见下一小节)。
2、添加动态链接库
在app\src\main目录下新建文件夹jniLibs\armeabi-v7a,将英创提供的libSerialControl.so文件拷贝到这个目录下。
3、封装串口类SerialPort
串口控制类SerialControl加载的so库添加完毕之后,使用SerialControl的静态方法已经可以访问操作串口。但SerialControl仅仅是串口的四个行为(方法),为了方便串口的管理,建议将串口相关的数据(设备描述符、发送接收计数等)、行为(打开、关闭、读、写)封装成一个串口类:SerialPort。
在java\com.emtronix.ccl.step2_serialport目录下新建一个串口类SerialPort,在这个类中调用SerialControl类的静态方法访问串口设备,并对外提供公共接口。在MainActivity中示例化SerialPort去操作串口。
点击ok后,开始编辑SerialPort.java文件,这里只添加了描述符mFd、发送计数mSendCount、接收计数mRecvCount成员变量。用户可以根据自己的需要在这里自行添加其他变量和方法。在对外的公共接口中都是调用SerialControl类的静态方法实现,并对读写计数,即完成了串口类的封装。封装好的串口类可以在MainActivity中实例化,然后调用这些public函数操作串口。
编辑完SerialPort类后,如果应用中还需要其他java类,像上一样新建java类,只有需要调用C/C++库的类才需要native函数。本例中又添加了查找串口类SerialPortFinder和常用工具类ToolsFunc(自己常用的通用函数)。
四、编写java应用程序
经过以上步骤之后,SerialPort类可以通过JNI接口访问C/C++动态库,已经封装好了对底层的访问,就可以在纯java语言环境中开发应用程序了。此时的开发过程,跟不直接访问硬件的是一样的,在MainActivity中实例化一个SerialPort类,调用其公共接口就可以完成对硬件资源的访问了。
1、设计界面
在app\src\main\res下有个layout文件夹,android应用的界面布局文件都在这里,此应用只有一个界面activity_main.xml,默认只有一个文本显示“Hello World!”。对Android界面的设计可以通过xml语言修改这个文件,也可以通过可视化编辑窗口拖动相应部件到Android模拟窗口。使用xml语言修改能更精细的控制界面,具体见源码;使用可视化编辑窗口能够比较直观方便的实现界面的初步编辑。这里简单介绍下可视化编辑步骤。
a)、新建一个1024*600的Android虚拟设备
点击编辑窗口中activity_main.xml左下角的Design图标进入可视化窗口,默认选择的设备是Nexus 4,点击下拉窗口,选择Add Device Definiton…。进入到了Virtual Device Configuration,点击Create Virtual Device。
进入Select Hardware后选择Tablet,点击左下角的New Hardware Profile, 设置虚拟设备的参数,如下所示,主要是分辨率、屏幕大小要与实际设备相同。
点击Finish后回到Select Hardware,选中esm6802,点击Next。进入System Image页面,选择download android 7.1.1的image,点击download。下载完成后,在下载页面点击Finish,回到System Image页面点击next。
确认配置后,点击Finish。这里并不需要运行虚拟设备,关闭Your Virtual Devices窗口。
b) 可视化编辑界面
回到activity_main.xml的编辑页面,再次点击设备下拉菜单,就可以选择刚才建立的esm6802了。
点击左上角的show design图标,就可以得到如下所示的大图显示。
这时就可以拖动左边窗口中需要的组件到虚拟设备,并在右边property窗口设置具体参数了。
不管是可视化拖动设计的界面,还是使用xml语法编写的界面,最后都可以在design页面看到设计的最终样子。Step2_SerialPort的界面如下图所示。
2、编写java代码,实现应用的业务逻辑
Android系统与用户交互的界面通过Activity加载呈现给用户,在Activity中实现对界面操作的监听,并完成相应的业务逻辑。onCreate函数就是Activity创建时候回调函数,一般在这里找到xml界面中的元部件,设置元部件的初始参数,并设置事件监听。
需要注意的是,应用程序的主线程一般又称为UI线程。UI线程5s得不到响应,就会产生ANR (Application Not Responding)错误。所以,一般UI线程主要是监听界面操作的,一切耗时阻塞的操作都要放在其他线程中实现,通过handler发送消息给UI线程更新UI,这样才能使应用运行流畅稳定。因此,在MainActivity中分别声明了串口接收线程和串口发送线程:
serialPort是前面封装的SerialPort.java类的实例化对象,当调用serialPort.OpenPort()后,实例化一个RecvThread对象并启动后,就可以使用ReadPort接收串口消息了。
RecvThread类继承Thread,在构造函数中传入主线程的handler,当读取到数据的时候,就通过此handler发送消息给主线程,完成UI刷新。
java部分的具体实现,请参考源码。Android应用开发内容很多,更详细的资料请参考开发者网站学习:https://developer.android.google.cn/index.html 。
3、编译项目
编辑好java部分代码后,就可以使用Ctrl+F9或者Build>>Make Project编译项目了。然后在Message窗口可以看到编译结果。
五、安装应用到ESM6802进行调试
1、运行应用
编译通过后可以将应用部署到ESM6802上运行。通过usb线连接PC机和ESM6802,点击工具栏中的Run app按键,在弹出的对话框中选择已连接的ESM6802,点击OK,就会把Step2_SerialPort安装到ESM6802中,并运行起来。
此时点击左下角的Android Monitor可以查看的应用程序的运行过程中,程序打印的log信息。
2、调试应用
如果,在运行过程中出现问题,一般可以通过日志信息查看错误原因,如果需要单步调试可以Ctrl+F12或者点击工具栏的停止按钮,停止运行应用。
然后Shift+F9或者点击调试按钮,进入调试模式,在弹出的对话框中选择已连接设备,点击OK。
这里在点击“打开串口”的程序里设置断点,左键点击所在行的最左边就可以设置断点。然后点击ESM6802上的“打开串口按键”,就会运行到断点处停止,等待用户调试。
调试完成后,与退出运行模式一样,点击停止按钮退出调试。
六、开机自启动用户的应用程序
用户开发好应用,有时需要应用在每一次开机的时候自启动。Android系统在启动完成的时候,会发生android.intent.action.BOOT_COMPLETED的广播,接收到此广播的应用就可以自己启动。所以,用户可以在应用中添加一个广播接收器,监听此广播,以开机启动此应用。
1、新建BootBroadcastReceiver类
在com.emtronix.ccl.step2_serialport包中新建BootBroadcastReceiver类,继承广播监听类BroadcastReceiver。重写onReveive函数,在此函数中判断Intent是否是BOOT_COMPLETE,如果为真就启动MainActivity。
2、向系统注册广播
BroadcastReceiver属于系统级监听,需要向系统注册。这里可以编辑app\src\main目录下的AndroidManifest.xml文件,在application标签中注册receiver,并添加接收此广播的权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
就可以了,如下图所示。android:priority=”999”可以增加此应用的优先级,可以优先接收到广播消息,更早启动。
系统为防止恶意程序的自启动,第三方安装的应用软件在最开始都是stop状态,这种状态下是不能自启动的。当用户自己手动点击,运行过一次后,系统认为此应用已经过用户确认安全,之后开机就能自动运行了。
七、应用程序生成apk
应用程序调试完毕,没有问题后会发布release版本的安装包。android应用程序安装包的后缀是.apk。发布后的apk文件通过U盘或者网络下载到esm6802后,点击即可完成安装。
1、生成签名
每一个应用都需要一个签名表明应用发布者的身份,只有同一个签名才能覆盖此应用。以此可以防止其他发布者以相同的应用名覆盖原有应用,确保应用的升级等操作只能由同一个发布者完成。
首先,点击Build>>Generate Signed APK…,在弹出的对话框中选择Create new。
在Key store path中点击最右边的…,在弹出的对话框中选择要存放签名的路径,并在File name中输入发布者想要的文件名字,点击OK。回到New Key Store页面,设置Store的密码,以及key相关的密码信息等。
2、发布签名应用
回到Generate Signed APK页面,点击Next。在Build Type中选择release版,Signature Versions勾选V1,点击Finish。
最后,会在app目录下生成app-release.apk文件。
在app目录下的build.gradle文件中可以指定发布apk文件的名字,在android节点中添加如下代码,重新生成signed apk即可。
八、应用程序的安装与卸载
1、安装应用程序
a、通过U盘
将最终生成了step2_serialport-release-1.0.apk,将此文件通过U盘拷贝到esm6802上,通过AnExplorer找到此文件,点击即可完成安装。
b、通过USB线,直接访问esm6802内部存储器
在屏幕顶端向下滑动,在弹出的对话框中点击USB charging this device
在弹出的对话框中选择Transfer files,这样在PC上就可以直接访问esm6802的内部存储器了。把step2_serialport-release-1.0.apk拷贝到esm6802的Download目录,打开AnExplorer,点击Internal Storage,进入Download目录,点击step2_serialport-release-1.0.apk,即可进行安装。
通过apk文件安装的应用,安装后,处于stop状态,如果需要开机启动,请手动打开一次,激活此应用,才能确保下次开机自启动。
2、卸载应用程序
如果用户需要卸载应用程序,可以有两种方法。
比较快捷的方法是在home页面,长按应用程序图标,会回到桌面,此时将图标拖动到左上角的回收站,会弹出卸载对话框,点击OK即可自动完成应用卸载。
另一种方法是在home界面点击Settings,选择Apps管理项,在里边找到要卸载的应用,点击进去,在App info中点击UNINSTALL,同样弹出卸载对话框,点击ok即可完成卸载。
成都英创信息技术有限公司 http://www.emtronix.com
原文下载:http://www.emtronix.com/download/android_studio.pdf