android studio实现聊天功能(android即时通讯demo开源)
Android串口通信可以实现设备与设备之间通过设备线连接进行数据(消息)传递
(一)导入so库
(二)在moudle的build中添加jniLibs
buildTypes {
sourceSets {
main { jni.srcDirs = [] }
}
}
12345
(三)添加Google的SerialPort
添加的是Google的所以必须创建android_serialport_api包
如需要更改SerialPort、SerialPortFinder位置需要重新生成so库
(四)创建串口通信工具类SerialPortUtils
package com.demo.serialport;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android_serialport_api.SerialPort;
/**
* @author renquan
*/
public class SerialPortUtils {
private final String TAG = "SerialPortUtils";
// private String path = "/dev/ttyS1";
// private int baudrate = 9600;
public boolean serialPortStatus = false; //是否打开串口标志
public String data_;
public boolean threadStatus; //线程状态,为了安全终止线程
public SerialPort serialPort = null;
public InputStream inputStream = null;
public OutputStream outputStream = null;
public ChangeTool changeTool = new ChangeTool();
/**
* 打开串口
* @return serialPort串口对象
*/
public SerialPort openSerialPort(String path,int baudrate){
try {
serialPort = new SerialPort(new File(path),baudrate,0);
this.serialPortStatus = true;
threadStatus = false; //线程状态
//获取打开的串口中的输入输出流,以便于串口数据的收发
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
new ReadThread().start(); //开始线程监控是否有数据要接收
} catch (IOException e) {
Log.e(TAG, "openSerialPort: 打开串口异常:" + e.toString());
return serialPort;
}
Log.d(TAG, "openSerialPort: 打开串口");
return serialPort;
}
/**
* 关闭串口
*/
public void closeSerialPort(){
try {
inputStream.close();
outputStream.close();
this.serialPortStatus = false;
this.threadStatus = true; //线程状态
serialPort.close();
} catch (IOException e) {
Log.e(TAG, "closeSerialPort: 关闭串口异常:"+e.toString());
return;
}
Log.d(TAG, "closeSerialPort: 关闭串口成功");
}
/**
* 发送串口指令(字符串)
* @param data String数据指令
*/
public void sendSerialPort(String data){
Log.d(TAG, "sendSerialPort: 发送数据");
try {
byte[] sendData = data.getBytes(); //string转byte[]
this.data_ = new String(sendData); //byte[]转string
if (sendData.length > 0) {
outputStream.write(sendData);
outputStream.write('n');
//outputStream.write('r'+'n');
outputStream.flush();
Log.d(TAG, "sendSerialPort: 串口数据发送成功");
}
} catch (IOException e) {
Log.e(TAG, "sendSerialPort: 串口数据发送失败:"+e.toString());
}
}
/**
* 单开一线程,来读数据
*/
private class ReadThread extends Thread{
@Override
public void run() {
super.run();
//判断进程是否在运行,更安全的结束进程
while (!threadStatus){
Log.d(TAG, "进入线程run");
//64 1024
byte[] buffer = new byte[64];
int size; //读取数据的大小
try {
size = inputStream.read(buffer);
if (size > 0){
Log.d(TAG, "run: 接收到了数据:" + changeTool.ByteArrToHex(buffer));
Log.d(TAG, "run: 接收到了数据大小:" + String.valueOf(size));
onDataReceiveListener.onDataReceive(buffer,size);
}
} catch (IOException e) {
Log.e(TAG, "run: 数据读取异常:" +e.toString());
}
}
}
}
//数据回调
public OnDataReceiveListener onDataReceiveListener = null;
public static interface OnDataReceiveListener {
public void onDataReceive(byte[] buffer, int size);
}
public void setOnDataReceiveListener(OnDataReceiveListener dataReceiveListener) {
onDataReceiveListener = dataReceiveListener;
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
package com.demo.serialport;
/**
* @author renquan
*/
public class ChangeTool {
/**
* byte数组转16进制字符串
*
* @param bytes byte数组
* @return 16进制字符串
*/
public String ByteArrToHex(byte[] bytes) {
String strHex;
StringBuilder sb = new StringBuilder();
for (byte aByte : bytes) {
strHex = Integer.toHexString(aByte & 0xFF);
sb.append(" ").append((strHex.length() == 1) ? "0" : "").append(strHex); // 每个字节由两个字符表示,位数不够,高位补0
}
return sb.toString().trim();
}
/**
* byte字节转int
*
* @param b byte字节
* @return int
*/
public static int byteToInt(byte b) {
int x = b & 0xff;
if (x == 127) {
return 0;
}
return x;
}
}
123456789101112131415161718192021222324252627282930313233343536373839
package com.demo.serialport;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
/**
* @author renquan
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText mMessage;
private Button mOpen;
private Button mSend;
private Button mClose;
private SerialPortUtils serialPortUtils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
//串口数据监听事件
serialPortUtils.setOnDataReceiveListener(new SerialPortUtils.OnDataReceiveListener() {
@Override
public void onDataReceive(byte[] buffer, int size) {
Log.d("TAG", "进入数据监听事件中。。。" + new String(buffer));
}
});
}
private void init() {
initView();
serialPortUtils = new SerialPortUtils();
}
private void initView() {
mMessage = (EditText) findViewById(R.id.message);
mOpen = (Button) findViewById(R.id.open);
mOpen.setOnClickListener(this);
mSend = (Button) findViewById(R.id.send);
mSend.setOnClickListener(this);
mClose = (Button) findViewById(R.id.close);
mClose.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.open:
// TODO 20/12/28
serialPortUtils.openSerialPort("/dev/ttyS9",9600);
break;
case R.id.send:
// TODO 20/12/28
serialPortUtils.sendSerialPort(mSend.getText().toString());
break;
case R.id.close:
serialPortUtils.closeSerialPort();
// TODO 20/12/28
break;
default:
break;
}
}
}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
Demo——github地址
本文内容由互联网用户自发贡献,该文观点仅代表作者本人。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 203304862@qq.com
本文链接:https://jinnalai.com/tuiguang/41279.html