最进接串口扫码器,参考 github上开源的串口通讯库https://github.com/cepr/android-serialport-api实现扫码器通讯。
Android Studio使用 cmake编译,将SerialPort.c/SerialPort.h两个文件拷贝到 cpp 文件夹下,SerialPort.java拷贝到 android.serialport包下,记得包名要和SerialPort.h中的方法名中的包名一直。了解NDK开发的你懂得。
# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.
cmake_minimum_required(VERSION 3.4.1)
# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.
add_library( # Specifies the name of the library.
serial_port
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/SerialPort.c)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
serial_port
# Links the target library to the log library
# included in the NDK.
${log-lib})
public class SerialPort {
private static final String TAG = "SerialPort";
private static final String DEFAULT_SU_PATH = "/system/bin/su";
private static String sSuPath = DEFAULT_SU_PATH;
static {
System.loadLibrary("serial_port");
}
/*
* Do not remove or rename the field mFd: it is used by native method close();
*/
private FileDescriptor mFd;
private FileInputStream mFileInputStream;
private FileOutputStream mFileOutputStream;
public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {
/* Check access permission */
if (!device.canRead() || !device.canWrite()) {
try {
/* Missing read/write permission, trying to chmod the file */
Process su;
su = Runtime.getRuntime().exec(sSuPath);
String cmd = "chmod 666 " + device.getAbsolutePath() + "\n" + "exit\n";
su.getOutputStream().write(cmd.getBytes());
if ((su.waitFor() != 0) || !device.canRead() || !device.canWrite()) {
throw new SecurityException();
}
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException();
}
}
mFd = open(device.getAbsolutePath(), baudrate, flags);
if (mFd == null) {
Log.e(TAG, "native open returns null");
throw new IOException();
}
mFileInputStream = new FileInputStream(mFd);
mFileOutputStream = new FileOutputStream(mFd);
}
public SerialPort(String devicePath, int baudrate, int flags)
throws SecurityException, IOException {
this(new File(devicePath), baudrate, flags);
}
public SerialPort(File device, int baudrate) throws SecurityException, IOException {
this(device, baudrate, 0);
}
public SerialPort(String devicePath, int baudrate) throws SecurityException, IOException {
this(new File(devicePath), baudrate, 0);
}
/**
* Set the su binary path, the default su binary path is {@link #DEFAULT_SU_PATH}
*
* @param suPath su binary path
*/
public static void setSuPath(String suPath) {
if (suPath == null) {
return;
}
sSuPath = suPath;
}
// JNI
private native static FileDescriptor open(String path, int baudrate, int flags);
// Getters and setters
public InputStream getInputStream() {
return mFileInputStream;
}
public OutputStream getOutputStream() {
return mFileOutputStream;
}
public native void close();
}
public SerialPort getSerialPort()
throws SecurityException, IOException, InvalidParameterException {
if (mSerialPort == null) {
//串口:/dev/ttyS4,波特率:115200
mSerialPort = new SerialPort(new File("/dev/ttyS4"), 115200);
}
return mSerialPort;
}
public void closeSerialPort() {
if (mSerialPort != null) {
mSerialPort.close();
mSerialPort = null;
}
}
private void openSerialPort() {
try {
mSerialPort =getSerialPort();
mInputStream = mSerialPort.getInputStream();
mReadThread = new ReadThread();
mReadThread.start();
} catch (SecurityException e) {
e.printStackTrace();
ToastCompat.makeText(this, R.string.error_security, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
ToastCompat.makeText(this, R.string.error_unknown, Toast.LENGTH_SHORT).show();
} catch (InvalidParameterException e) {
e.printStackTrace();
ToastCompat.makeText(this, R.string.error_configuration, Toast.LENGTH_SHORT).show();
}
}
private class ReadThread extends Thread {
public ReadThread() {
}
@Override
public void run() {
super.run();
while (!isInterrupted()) {
int size;
try {
byte[] buffer = new byte[64];
if (mInputStream == null) return;
size = mInputStream.read(buffer);
if (size > 0) {
String goodsCode = new String(buffer, 0, size);
EventBus.getDefault().post(new GoodsMsgEvent(goodsCode));
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}