android 使用服务读取串口数据实例
Posted mmsx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 使用服务读取串口数据实例相关的知识,希望对你有一定的参考价值。
一些android 手机是有串口可以提供打开,读取一些底层的数据。如果手机本身没有串口的话,那么打开估计会报错。串口读取数据肯定是使用jni调用c代码来完成的。有一个开源的串口库android-serialport-api。其主页在这里http://code.google.com/p/android-serialport-api/ ,这里可以下到APK及对源码。谷歌的代码库,无奈国内无法下载https://github.com/cepr/android-serialport-api ,GITHUB的地址,这个可以下载 但是下载源码之后发现源码不能直接使用,而且源码结构较为复杂。
在这里我是使用服务来读取串口数据,都出来数据直接写入到txt文件里面。
串口读写的库的地址:https://code.google.com/p/android-serialport-api/
github地址:https://github.com/cepr/android-serialport-api
本篇博客的下载地址:http://download.csdn.net/detail/qq_16064871/9731908
1,注意事项
选择串口时候,需要加上dev/。如果我选择ttyMT2,路径就是dev/ttyMT2。波特率就是整型38400,或者其他。
打开串口以及读取数据的串口类调用加载so库一定放在这个包下面android_serialport_api。不能放在其他包的下面。
SerialPortDevice.class
/**
*
*/
package android_serialport_api;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import android.util.Log;
public class SerialPortDevice
private FileDescriptor mFd;
private InputStream mInputStream;
private OutputStream mOutputStream;
private String path;
private int baudrate;
int flags=0;
public SerialPortDevice(String path, int baudrate, int flags)
mFd = new FileDescriptor();
this.path=path;
this.baudrate=baudrate;
this.flags=flags;
/* (non-Javadoc)
* @see com.gps.device.IDevice#connect()
*/
public boolean connect()
mFd = open(path, baudrate, 0);
if (mFd == null)
return false;
else
return true;
/*
* (non-Javadoc)
*
* @see com.gps.device.IDevice#getInputStream()
*/
public InputStream getInputStream()
// TODO Auto-generated method stub
return new FileInputStream(mFd);
/*
* (non-Javadoc)
*
* @see com.gps.device.IDevice#getOutputStream()
*/
public OutputStream getOutputStream()
// TODO Auto-generated method stub
return new FileOutputStream(mFd);
// JNI
private native static FileDescriptor open(String path, int baudrate, int flags);
public native void close();
static
System.loadLibrary("serial_port");
2,服务类,以及封装的串口管理类
SerialPortService.class 服务
package com.mmsx.serial;
import com.mmsx.serial.SerialPortIOManage.onSerialPortIOListener;
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
public class SerialPortService extends Service
@Override
public void onCreate()
SerialPortIOManage.getInstance().setonSerialPortIOListener(new onSerialPortIOListener()
@Override
public void OnIOCallBack(byte[] data, int length)
@Override
public void OnConnectStatusCallBack(boolean statue)
if (statue)
String fileString = Environment.getExternalStorageDirectory().getPath() +
"/serial.txt";
FileWrite.GetInstance().Create(fileString);
);
@Override
public void onDestroy()
SerialPortIOManage.getInstance().disConnect();
super.onDestroy();
@Override
public int onStartCommand(Intent intent, int flags, int startId)
SerialPortIOManage.getInstance().Connect("dev/ttyMT2", 38400);
return super.onStartCommand(intent, flags, startId);
@Override
public IBinder onBind(Intent intent)
return null;
service服务也是android 的四大组件,别忘了注册
<service
android:name="com.mmsx.serial.SerialPortService"
android:icon="@drawable/ic_launcher">
</service>
SerialPortIOManage.class串口打开获取数据的管理类
package com.mmsx.serial;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android_serialport_api.SerialPortDevice;
public class SerialPortIOManage
SerialPortDevice temPortDevice = null;
private InputStream mInputStream = null;
private OutputStream mOutputStream = null;
private String mstrComPath = "";
private int mnBaudrate = 57600;
ReadThread mReadThread = null;
onSerialPortIOListener mListener = null;
private static class SingletonHolder
private static final SerialPortIOManage INSTANCE = new SerialPortIOManage();
private SerialPortIOManage ()
public static final SerialPortIOManage getInstance()
return SingletonHolder.INSTANCE;
public void setonSerialPortIOListener(onSerialPortIOListener listener)
mListener = listener;
public interface onSerialPortIOListener
abstract void OnConnectStatusCallBack(boolean statue);
abstract void OnIOCallBack(byte[] data, int length);
public void Connect(String path, int baudrate)
mstrComPath = path;
mnBaudrate = baudrate;
temPortDevice = new SerialPortDevice(path, baudrate, 0);
if (temPortDevice.connect())
mInputStream = temPortDevice.getInputStream();
mOutputStream = temPortDevice.getOutputStream();
mReadThread = new ReadThread();
mReadThread.start();
if (null != mListener)
mListener.OnConnectStatusCallBack(true);
else
if (null != mListener)
mListener.OnConnectStatusCallBack(false);
public void disConnect()
if(mReadThread != null)
mReadThread.interrupt();
mReadThread = null;
try
if (mInputStream != null)
mInputStream.close();
mInputStream = null;
if (mOutputStream != null)
mOutputStream.close();
mOutputStream = null;
catch (IOException e)
e.printStackTrace();
if (temPortDevice != null)
temPortDevice.close();
class ReadThread extends Thread
public void run()
int nMaxBufLength = 1024;
byte[] buffer = new byte[nMaxBufLength];
while(!isInterrupted())
try
int byteRead = -1;
Thread.sleep(200);
if(mInputStream != null)
byteRead = mInputStream.read(buffer);
if(byteRead > 0)
if(mListener != null)
mListener.OnIOCallBack(buffer, byteRead);
FileWrite.GetInstance().Write(buffer, byteRead);
else
break;
catch (IOException e)
if (mListener != null)
mListener.OnConnectStatusCallBack(false);
break;
catch (InterruptedException e)
e.printStackTrace();
continue;
//while(!isInterrupted())
3,实现效果
4,创建文件,持续写入数据管理类
package com.mmsx.serial;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileWrite
private long nDataLength = 0;
private static class SerialPortFileWriteHolder
private static final FileWrite INSTANCE = new FileWrite();
private FileWrite ()
public static final FileWrite GetInstance()
return SerialPortFileWriteHolder.INSTANCE;
FileOutputStream moutStream = null;
private String mstrFileName ="";
public void Create(String strFileName)
Close();
mstrFileName = strFileName;
File newFile = new File(strFileName);
try
nDataLength = 0;
moutStream = new FileOutputStream(newFile);
catch (FileNotFoundException e)
public void Close()
if (moutStream != null)
try
nDataLength = 0;
moutStream.close();
catch (IOException e)
moutStream = null;
public boolean IsOpen()
return (moutStream != null);
public void Write(byte[] bytes, int nLength)
if (!IsOpen())
if (!mstrFileName.isEmpty())
File newFile = new File(mstrFileName);
if (newFile.exists())
try
nDataLength = 0;
//文件存在,往文件后面增加内容
moutStream = new FileOutputStream(newFile,true);
catch (FileNotFoundException e)
else
Create(mstrFileName);
else
return;
else
try
moutStream.write(bytes, 0, nLength);
nDataLength = nDataLength + nLength;
//文件大于10M就停止写入
if (nDataLength > 10485760)
Close();
catch (IOException e)
Close();
往存储创建文件,写入数据,别忘了权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
5,最后总结
当前进入一个activity页面,打开串口拿到数据持续写入数据到文件里面,别忘了生命周期的影响。如果点击了home,back,或者返回finish等。如果读取数据线程关闭了,怎么重新开启等问题。手机应用的大多数情况下我们只能在手机上看到一个程序的一个界面,用户除了通过程序界面上的功能按钮来在不同的窗体间切换,还可以通过Back键和 Home键来返回上一个窗口,而用户使用Back或者Home的时机是非常不确定的,任何时候用户都可以使用Home或Back来强行切换当前的界面。
HOME键的执行顺序:onPause->onStop->onRestart->onStart->onResume
BACK键的顺序: onPause->onStop->onDestroy->onCreate->onStart->onResume
onPause不要做太耗时的工作
解决办法:
可以在onResume里面重新调用查看一下线程的状态。
在这篇博客我就没有写这个方法onResume。之前在项目中遇到过,记录一下。就是打开串口采集时候,然后点击home,有概率会停止存数据。
以上是关于android 使用服务读取串口数据实例的主要内容,如果未能解决你的问题,请参考以下文章