看着Android的发展心里很是欢喜,对于有硬件基础的我们当然可以选择Android应用+硬件产品 = 单片机+大屏幕+硬件产品+网络设备,同时价格、稳定性、通用性、美观性、开发难度,Android让我欣喜不已,不是为了逃避难度,只是真心觉得它太棒了~
这里我选择描述一下Android与zigbee,很多玩智能家居,工业控制,组网的童靴可以参考参考。
已经选择好了第一款平板,当然平板就作为了当前的协调器,我们要实现的功能是:(1)写一个Android应用与协调器通信,(2)使用一个节点将数据接收到电脑上。
(1)写一个Android应用与协调器通信
先做一个demo界面,效果如图1所示。
制作方法参考,我得博客:13-7-13 聊天窗口的绘制与实现 (实在有问题可以留言)。
接下来,引入zigbee包,***.so文件,实现协调器(平板)与底层(节点接到电脑上)对话
将libserial_port.so文件拷贝到libs中(拷贝这个图片我就不上了),填写对应的Java类,实现对so文件的调用,下面开始代码啦~
常常我们编写代码的时候头脑一热就开始编写,但是代码是逻辑的理性的,不是感性的,最好有个框架。
根据框架来看,第一部分串口操作代码如下:
/****************************************************************
* 编写SerialPort类,实现方法:串口初始化、输入数据、输出数据
* @author hanzhen
*
*/
public class SerialPort {
private static final String TAG = "SerialPort";
/*
* Do not remove or rename the field mFd: it is used by native method close();
*/
private FileDescriptor mFd;
private FileInputStream mFileInputStream;
private FileOutputStream mFileOutputStream;
/******************************************************
* 实现串口初始化工作
* @param device
* @param baudrate
* @param flags
*/
public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {
mFd = open(device.getAbsolutePath(), baudrate, flags);
Log.i(TAG, "-----path::"+device.getAbsolutePath());
if (mFd == null) {
Log.e(TAG, "native open returns null");
throw new IOException();
}
mFileInputStream = new FileInputStream(mFd);
mFileOutputStream = new FileOutputStream(mFd);
}
/*******************************************************
* 输入数据
* @return
*/
// Getters and setters
public InputStream getInputStream() {
return mFileInputStream;
}
/********************************************************
* 发送数据或输出数据
* @return
*/
public OutputStream getOutputStream() {
return mFileOutputStream;
}
//静态装入so文件,声明JNI接口类
// JNI
private native static FileDescriptor open(String path, int baudrate, int flags);
public native void close();
static {
System.loadLibrary("serial_port");
}
}
第二部分为Activity提供接口
(1)编写Application类
/***********************************************************
* 编写Application类,实现方法:打开串口、关闭串口
* @author hanzhen
*
*/
public class Application extends android.app.Application {
public SerialPortFinder mSerialPortFinder = new SerialPortFinder();
private SerialPort mSerialPort = null;
public SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException {
if (mSerialPort == null) {
String path;
int baudrate;
path="/dev/ttySAC2";
baudrate=9600;
/* Open the serial port */
mSerialPort = new SerialPort(new File(path), baudrate, 0);
}
return mSerialPort;
}
public void closeSerialPort() {
if (mSerialPort != null) {
mSerialPort.close();
mSerialPort = null;
}
}
}
千万不要忘记在manifest.xml文件中装入它:android:name="com.pitaya.zigbee.Application"
(2)编写SerialPortActivity类,实现程序
/***************************************************************
* 编写SerialPortActivity类,实现程序:
*1、提供串口数据发送数据流接口
Protected OutputStream mOutputStream;
*2、开启接收线程
提供接收抽象函数abstract void onDataReceived
* @author hanzhen
*
*/
public abstract class SerialPortActivity extends Activity {
private static final String TAG="SerialPortActivity";
protected Application mApplication;
protected SerialPort mSerialPort;
protected OutputStream mOutputStream;
private InputStream mInputStream;
private ReadThread mReadThread;
private class ReadThread extends Thread {
@Override
public void run() {
super.run();
while(!isInterrupted()) {
int size;
try {
byte[] buffer = new byte[512];
if (mInputStream == null) return;
size = mInputStream.read(buffer);
if (size > 0) {
Thread.sleep(30); //保证接收完毕
size = mInputStream.read(buffer);
onDataReceived(buffer, size);
}
} catch (IOException e) {
e.printStackTrace();
return;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mApplication = (Application) getApplication();//Return the application that owns this activity
Log.i(TAG, "---->let we get the zigbee info");
try {
Log.i(TAG, "---->open the serialPort");
mSerialPort = mApplication.getSerialPort();
Log.i(TAG, "---->serialPort info: "+mSerialPort.toString());
mOutputStream = mSerialPort.getOutputStream();
mInputStream = mSerialPort.getInputStream();
Log.i(TAG, "---->打开接收线程: ");
/* Create a receiving thread */
mReadThread = new ReadThread();
mReadThread.start();
}catch(Exception e){
e.printStackTrace();
}
}
protected abstract void onDataReceived(final byte[] buffer, final int size);
@Override
protected void onDestroy() {
if (mReadThread != null)
mReadThread.interrupt();
mApplication.closeSerialPort();
mSerialPort = null;
super.onDestroy();
}
第三部分 界面实现zigbee数据的收发
//发送数据
send_button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
String t = Emission.getText().toString();
try {
mOutputStream.write(t.getBytes());
Message(ChatMessage.MESSAGE_TO, t);
} catch (IOException e) {
e.printStackTrace();
}
}
});
//接收数据
//接收数据
private static String sbuf = "";
@Override
protected void onDataReceived(final byte[] buffer, final int size) {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
public void run() {
String zig_recept = new String(buffer, 0, size);
Log.i(TAG, zig_recept);
sbuf =sbuf+zig_recept;
if(sbuf.charAt(sbuf.length()-1) =='a' ){
Message(ChatMessage.MESSAGE_FROM, sbuf);
sbuf = "";
}
}
});
}
----------------------------------------------------------------结束-------------------------------------------------
上面完成了流程图所示的功能:
效果如图所示:
图1 程序刚起动 图2 发送字符“feiyangxiaomia”过去
图3 接收到了字符“feiyangxiaomia”,发送几个helloworld 图4 接收到了字符“helloworld”