android串口通信

开源demo

名称 链接 备注
usb-serial-for-android-master https://github.com/mik3y/usb-serial-for-android usb转串口通信
android-serialport-api https://github.com/cepr/android-serialport-api 串口通信
AndroidSerialportAPI https://github.com/yuanhhyuan/AndroidSerialportAPI usb转串口通信

以上demo使用的中,是一个很好的参考。如果是负责做垂直开发,需要明确“usb转串口”和“串口通信”的区别。简单理解:

  • usb转串口:硬件连接形式为,一段为串口,一端为usb,中间使用其他模块进行转换,在usb端使用usb转串口形式开发。
  • 串口通信:通用异步收发传输器,通常称作UART,是一种异步收发传输器,是电脑硬件的一部分。
  • 两种不同的通信标准,根据实际需求选择应用。usb转串口使设备连接的方式更多和更方便。

Android API串口通信

API:frameworks\base\core\java\android\hardware\SerialManager.java
使用demo如下:

package android.xxx.serial;

import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
import java.io.IOException;

import android.content.Context;
import android.hardware.SerialManager;
import android.hardware.SerialPort;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
import java.io.IOException;
import java.nio.ByteBuffer;

public class RS485SerialManager {
	private static final String TAG = "SerialManager";
	private final Context mContext;
	private static ByteBuffer mInputBuffer;
	private static ByteBuffer mOutputBuffer;
	private static SerialManager mSerialManager;
	private static SerialPort mSerialPort;

	public RS485SerialManager(Context context) {
		this.mContext = context;
		mSerialManager = (SerialManager)context.getSystemService(Context.SERIAL_SERVICE);
		if (false) {
			mInputBuffer = ByteBuffer.allocateDirect(1024);
			mOutputBuffer = ByteBuffer.allocateDirect(1024);
		} else {
			mInputBuffer = ByteBuffer.allocate(1024);
			mOutputBuffer = ByteBuffer.allocate(1024);
		}
	}

	public static void openSerial(int bandrate) {

		String[] ports = mSerialManager.getSerialPorts();
		if (ports != null && ports.length > 0) {
			try {
				if (bandrate<=0) {
					bandrate=9600;
				}
				mSerialPort = mSerialManager.openSerialPort(ports[0], bandrate);
				if (mSerialPort != null) {
					new Thread().start();
				}
			} catch (IOException e) {
			}
		}
	}
	public static void writeMsg(String msg) {
		if (/* actionId == EditorInfo.IME_ACTION_DONE && */ mSerialPort != null) {
			try {
				Log.d(TAG, "write: " + msg);
				byte[] bytes = msg.getBytes();
				mOutputBuffer.clear();
				mOutputBuffer.put(bytes);
				mSerialPort.write(mOutputBuffer, bytes.length);
			} catch (IOException e) {
				Log.e(TAG, "write failed", e);
			}
		}
	}

	public static void colse() {
		if (mSerialPort != null) {
			try {
				mSerialPort.close();
			} catch (IOException e) {
			}
			mSerialPort = null;
		}
	}
}

追踪代码,实际也是直接打开/dev/tty*设备,和android-serialport-api实现相同。区别在于
注意: 此处demo没有体现485通信输入输出切换实现。本demo是配合驱动实现了gpio口拉高拉低实现切换的,此处不做说明。

android-serialport-api:
1、app直接调用打开设备的jni接口,可能权限不足
2、需要对串口配置有很详细的了解和理解,打开设备同时需要配置

Android API:
1、可能获取不到代码,依赖系统配置,追踪mSerialManager.getSerialPorts()会发现,可打开设备需要在com.android.internal.R.array.config_serialPorts中配置

public SerialService(Context context) {
        mContext = context;
        mSerialPorts = context.getResources().getStringArray(
        		// 此处设置串口设备
                com.android.internal.R.array.config_serialPorts);
    }

    public String[] getSerialPorts() {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SERIAL_PORT, null);

        ArrayList ports = new ArrayList();
        for (int i = 0; i < mSerialPorts.length; i++) {
            String path = mSerialPorts[i];
            if (new File(path).exists()) {
                ports.add(path);
            }
        }
        String[] result = new String[ports.size()];
        ports.toArray(result);
        return result;
    }

com.android.internal.R.array.config_serialPorts的值


               /dev/ttyS1
               /dev/ttyS3

如果未配置以上数组,无法通过Android API实现串口通信。
2、开发简单

你可能感兴趣的:(Android系统开发)