Android Studio Serial Port

 Android Studio Serial Port

Android Studio 版本

Android Studio Arctic Fox | 2020.3.1 Patch 4

建立android_serialport_api & jni

點擊下載android_serialport_api & jni 檔案

建立android_serialport_api

main ->  java 新增Package android_serialport_api
將Download中SerialPort.java放入新增android_serialport_api













建立JNI

File -> New -> Folder -> JNI Folder 
將Download下來的jni 內容五個檔案放入新增的jni
















指定Android.mk

android_serialport_api & jni 新增完畢後
build.gradle(app)android {}中加入指定Android.mk
externalNativeBuild {
ndkBuild {
path file('src/main/jni/Android.mk')
}
}





















Layout

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<EditText
android:id="@+id/command"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="50dp"
android:layout_marginRight="15dp"
android:hint="請輸入指令" />

<Button
android:id="@+id/sendmsg_bt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/command"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
android:text="發送訊息" />

<TextView
android:id="@+id/showtext"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/sendmsg_bt"
android:layout_centerInParent="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="30dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="30dp"
android:scrollbars="vertical"/>

</RelativeLayout>

MainActivity

設定SerialPort

mSerialPort = new SerialPort(new File("/dev/tty0"), 9600, 8,1, 'N');
參數
  • 串列埠名稱(Serial port)
  • 鮑率(Baud Rate)
  • 資料位元長度(Data Bits)
  • 資料停止位元(Stop Bits)
  • 同位元檢查(Parity Bits)

接收Input訊息

private class ReadThread extends Thread {
@Override
public void run() {
super.run();
Log.e(TAG, "Read thread is open.");
while (!isInterrupted()) {
if (mInputStream == null)
return;
try {
byte[] buffer = new byte[64];
int size = mInputStream.read(buffer);
if (size > 0) {
onDataReceived(buffer, size);
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
建立一個Thread來獲取Input的訊息
宣告byte[]利用mInputStream.read()
將Input的訊息存入byte[]
宣告int 紀錄訊息長度

顯示訊息

protected void onDataReceived(final byte[] buffer, final int size) {
runOnUiThread(() -> {
String receivedMessage = new String(buffer, 0, size);
recvStr = recvStr + receivedMessage + "\n";
showtext.setText(recvStr);
});
}
byte[]訊息使用String(byte[] bytes, int offset, int length)做轉換
  • byte[] bytes
    • 要解碼的訊息,型態為byte
  • offset
    • 要從哪的byte開始解碼
  • length
    • 解碼到哪個byte

完整MainActivity

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android_serialport_api.SerialPort;

public class MainActivity extends AppCompatActivity {
private static final String TAG = "m";
protected SerialPort mSerialPort;
protected InputStream mInputStream;
protected OutputStream mOutputStream;
private ReadThread mReadThread;

private EditText command;
private Button sendmsg_bt;
private TextView showtext;

private String recvStr = "";

private class ReadThread extends Thread {
@Override
public void run() {
super.run();

Log.e(TAG, "Read thread is open.");
while (!isInterrupted()) {
if (mInputStream == null)
return;

try {
byte[] buffer = new byte[64];
int size = mInputStream.read(buffer);
if (size > 0) {
onDataReceived(buffer, size);
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

viewinit();
Set_serial();

}

@Override
protected void onDestroy() {
Log.d(TAG, "in onDestroy()");
if (mReadThread != null) {
mReadThread.interrupt();
}

if (mSerialPort != null) {
mSerialPort.close();
mSerialPort = null;

try {
mOutputStream.close();
mOutputStream = null;
mInputStream.close();
mInputStream = null;
} catch (IOException e) {
e.printStackTrace();
}
}
super.onDestroy();
}

private void viewinit() {
command = (EditText) findViewById(R.id.command);
sendmsg_bt = (Button) findViewById(R.id.sendmsg_bt);
showtext = (TextView) findViewById(R.id.showtext);
sendmsg_bt.setOnClickListener(send);
showtext.setMovementMethod(ScrollingMovementMethod.getInstance());

}

private void Set_serial() {
try {
Log.e(TAG, "Try to open serial port");
mSerialPort = new SerialPort(new File("/dev/tty0"), 9600, 8,1, 'N');
mInputStream = mSerialPort.getInputStream();
mOutputStream = mSerialPort.getOutputStream();
Log.e(TAG, "Serial port opened!");

mReadThread = new ReadThread();
mReadThread.start();
} catch (SecurityException e) {
Log.e(TAG, "Security Exception");
e.printStackTrace();
} catch (IOException e) {
Log.e(TAG, "Fail to open serial port");
e.printStackTrace();
}
}

private Button.OnClickListener send = new Button.OnClickListener() {
@Override
public void onClick(View v) {
String CMD = command.getText().toString();
byte[] bytes = CMD.getBytes();
try {
mOutputStream.write(bytes);
} catch (IOException e) {
Log.e(TAG, "Fail to send out message");
e.printStackTrace();
}
}
};

protected void onDataReceived(final byte[] buffer, final int size) {
runOnUiThread(() -> {
String receivedMessage = new String(buffer, 0, size);
recvStr = recvStr + receivedMessage + "\n";
showtext.setText(recvStr);
});
}
}

若是無法執行或有問題請看這篇Android Studio Serial_Port 無法執行

留言