Готов к работе
- Среда NDK
- C-файл, используемый для последовательной связи
Примечание: путь к имени функции в файле c необходимо изменить , а также необходимо изменить как файл c, так и файл заголовка .h
Доступ к базовой библиотеке
Импорт с использованием библиотеки SO
- Создайте новую запись jni в основном каталоге и поместите туда файл C
- Создайте новые файлы Android.mk , Application.mk и настройте
- Скомпилируйте проект и получите скомпилированный файл библиотеки so.Сгенерированный каталог по умолчанию - app \ build \ intermediate \ jniLibs \ app \ debug \ armeabi, если скомпилированная версия выпуска находится в каталоге releaseasse.
- Создайте новый каталог jniLibs в основном каталоге и скопируйте сгенерированную библиотеку so в этот
- Настройте файл gradle в каталоге приложения
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ndk {
moduleName "serial_port"
ldLibs "log", "z", "m"
abiFilters "armeabi", "x86"
}
}
debug {
ndk {
moduleName "serial_port"
ldLibs "log", "z", "m"
abiFilters "armeabi", "x86"
}
}
}
- Создайте файл класса в коде, загрузите файл библиотеки so и определите метод открытия и закрытия последовательного порта.
Введение в CMake
- Создайте новую папку cpp в основном каталоге и поместите сюда исходный файл c
- Настройте файл CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
# 查找cpp目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRC 变量
aux_source_directory(src/main/cpp/ DIR_LIB_SRC)
#设置源文件
add_library(SerialPort SHARED ${DIR_LIB_SRC})
#表明头文件位置
#include_directories(src/main/cpp/)
find_library( # Sets the name of the path variable.
log-lib
log)
target_link_libraries( # Specifies the target library.
SerialPort
${log-lib})
- Настройте файл Gradle в приложении
android {
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags ""
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
- Создайте файл класса в коде, загрузите файл библиотеки so и определите метод открытия и закрытия последовательного порта.
Открыть / закрыть последовательный порт
Открывать и закрывать в jni
В файле C определены два метода, а именно открытие и закрытие последовательного порта. Метод открытия последовательного порта имеет возвращаемое значение, а возвращаемое значение - объект FileDescriptor.Мы используем этот объект для чтения и записи данных в последовательный порт.
Откройте последовательный порт
Запросить последовательный порт
Некоторые настраиваемые устройства могут иметь много последовательных портов. Какой последовательный порт нужно открыть нашему приложению? С одной стороны, вы можете запросить у производителя устройства имя последовательного порта, к которому нам нужно подключиться. С другой стороны, мы можем только перечислить все последовательные порты и попробовать их один за другим.
Запросить все последовательные порты:
определить класс SerialPortFinder и перечислить все последовательные порты и пути устройства, прочитав файл / proc / tty / drivers
Метод: метод getAllDevices () в SerialPortFinder , см. Код SerialPortFinder для конкретной реализации
включить
После нахождения соответствующего последовательного порта вызовите метод jni, чтобы открыть последовательный порт. При открытии вам необходимо передать три параметра: путь к последовательному порту, скорость передачи данных и метод открытия.
public SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException {
if (mSerialPort == null) {
//这里是打开了/dev/ttyS3 串口,波特率9600,
mSerialPort = new SerialPort(new File("/dev/ttyS3"), 9600, 0);
}
return mSerialPort;
}
При открытии последовательного порта получается объект FileDescriptor, и на основе объекта создается поток ввода и вывода для реализации операций чтения и записи.
Закройте последовательный порт
Вам необходимо закрыть последовательный порт после использования и перед выходом из приложения. Это эквивалентно файловым операциям, которым необходимо закрыть файловый поток. Последовательная связь - это, по сути, файловая операция, поэтому ее необходимо закрыть.
/**
* 关闭串口
* 使用结束时记得关闭串口
*/
public void closeSerialPort() {
if (mSerialPort != null) {
//调用native方法关闭串口
mSerialPort.close();
mSerialPort = null;
}
}
Отправить / прочитать данные
Когда последовательный порт открыт, получается поток ввода и вывода, затем следующая отправка и чтение должны работать с этим потоком.
отправить данные:
Отправляемые данные представляют собой массив байтов. Если это строка, шестнадцатеричная команда и т. Д., Их необходимо преобразовать в массив байтов и отправить. Просто напишите данные в наш выходной поток.
public void sendBufferToSerial(byte[] data) {
try {
mFileOutputStream.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
Прочитать данные:
Прочтите данные относительно передаваемых данных, относительные шаги немного больше, потому что мы не знаем, когда я отправлю последовательные данные , поэтому необходимость постоянно открывать данные подпотока из входного потока, чтобы взять , когда взять длину данных Если он не равен 0, проанализируйте данные для следующего шага.
class ReadThread extends Thread {
@Override
public void run() {
super.run();
while (!isInterrupted()) {
int size;
final byte[] buffer;
try {
buffer = new byte[128];
if (mFileInputStream == null) return;
size = mFileInputStream.read(buffer);
if (size > 0) {
//回调
if (listener != null)
listener.receiveData(size, buffer);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 开始接收串口数据
*
* @param onReceiveDataListener 数据回调
*/
public void startReceiveData(OnReceiveDataListener onReceiveDataListener) {
readThread = new ReadThread();
readThread.start();
listener = onReceiveDataListener;
}
/**
* 停止接收数据
*/
public void stopReceiveData() {
if (readThread != null) {
if (readThread.isInterrupted())
readThread.interrupt();
}
readThread = null;
listener = null;
}
Считанные данные также представляют собой массив байтов, и данные необходимо проанализировать. Как правило, поставщик оборудования предоставляет соответствующий метод анализа.
Последовательный порт читает и отправляет данные, в качестве идентификационных битов будет 2-5 байтов, обычно начиная с 0xFF, каждый пакет унифицирован, и вам нужно быть внимательными при отправке и анализе данных.
использовать
Вы можете открыть последовательный порт в приложении, а затем определить метод отправки и чтения данных в BaseActivity или BaseFragment проекта и вызвать его напрямую там, где вам нужно его использовать.
Прилагается
Исходный файл на C: