⑴ 怎麼查看android 設備的串口
1. 如果是linux,不需要單獨安裝什麼串口驅動
2. 但需要使用ls /dev/tty * 查看usb 串口設備是否被檢測到
2. 然後使用linux下的MINICOM進行串口信息列印,具體配置和用法可以一下
⑵ 如何開放android的串口許可權
要調用串口,肯定是要用到JNI的,而且要有打開對應串口設備的許可權
至於是不是通過USB轉的,沒啥關系,因為USB轉串口的驅動已經把USB的特徵封裝了,就當它是一個純串口操作就行
android-serialport-api也是用的JNI,要想知道能不能用,裝它的DEMO代碼試試就知道了
不然重新寫一個JNI的庫,用android-serialport-api的也行,不然網上也好多現成的代碼,基本不用重寫
⑶ android虛擬機串口通信
工具:Virtual Serial Port Driver.
用這個工具虛擬出一對串口。
下載地址
2.用串口調試助手,測試串口通信。
3.用這個命令啟動虛擬機:emulator @2.2 -scale auto -qemu -serial COM3 &
說明:
2.2:是虛擬機的名稱。
COM3是你要選擇的串口。
ps:在cmd中使用這個命令有兩種方式:1)將安卓的sdk的tools文件夾加入到path環境變數中,2)在安卓的sdk的tools文件夾下打開cmd。
4.虛擬機中測試串口通信用谷歌的一個開源項目:android_serialport_api
5.在虛擬機中運行項目。
說明:運行前要獲取設備的許可權
1)在cmd中用adb shell命令,進入虛擬機命令行環境。
2)打開dev文件夾:cd dev
3)獲取許可權:chmod 777 ttyS2
6.谷歌的開源項目不能導入進eclipse,我整理了一下,調通了。
⑷ android如何讀取串口數據
代碼如下:
import com.friendlyarm.AndroidSDK.HardwareControler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
public class MapGuider_Activity extends Activity{
private int serial_fd=0;
private byte[] serial_RevBuf=new byte[100];
private byte[] serial_SendBuf="fsjajd".getBytes();
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.mapguider);
serial_fd=HardwareControler.openSerialPort("/dev/s3c2410_serial1", 115200, 8, 1);
if(serial_fd!=-1)
{
System.out.println("打開串口成功");
HardwareControler.write(serial_fd, serial_SendBuf);
lac_handler.post(RevicePosDataThread);
}
else
{
System.out.println("指定的串口不存在或在其它進程中已被打開");
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
HardwareControler.close(serial_fd);
System.out.println("關閉串口");
lac_handler.removeCallbacks(RevicePosDataThread);
super.onDestroy();
}
Handler lac_handler =new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
}
};
Runnable RevicePosDataThread =new Runnable()
{
int err=0;
String s;
public void run() {
// TODO Auto-generated method stub
while(true)
{
//Looper.prepare();
err=HardwareControler.select(serial_fd, 1, 0);
if(err==1)//有數據可讀
{
HardwareControler.read(serial_fd, serial_RevBuf, 10);
s=new String(serial_RevBuf);
System.out.println("接收到串口數據"+s);
}
else if(err==0) //無數據可讀
{
System.out.println("沒有接收到串口數據");
}
else //出錯
{
System.out.println("接收到串口數據出錯");
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
}
⑸ Android串口通訊
1.打開串口。
2.串口處於監聽狀態
3.想串口寫入數據,串口接收到數據返回數據
SerialPort類所在的包一定要和上圖包名一直,因為串口通訊需要使用jni中的函數。
package android_serialport_api;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.fx.serialporttest.L;
public class SerialPort {
/*
* Do not remove or rename the field mFd: it is used by native method
* close();
*/
private FileDescriptor mFd;
private FileInputStream mFileInputStream;
private FileOutputStream mFileOutputStream;
/**
* 構造方法
* @param device 串口地址
* @param baurate 波特率
* @param flags
* @throws IOException
* @throws InterruptedException
*/
public SerialPort(File device,int baudrate,int flags) {
/*
* 檢測是否有訪問許可權
*/
if(!device.canRead()||!device.canWrite()){
//如果沒有讀寫許可權,嘗試chmod命令這個文件
L.tag("沒有讀寫許可權");
Process su;
try {
su = Runtime.getRuntime().exec("/system/bin/su");//獲取root讀寫許可權
String cmd = "chmod 777"+device.getAbsolutePath()+"\n"+"exit\n";
su.getOutputStream().write(cmd.getBytes()); //向此路徑文件寫入命令
if((su.waitFor()!=0||!device.canRead()||!device.canWrite())){
throw new SecurityException();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
mFd = open(device.getAbsolutePath(),baudrate,flags);
if(mFd==null){
mFd = open(device.getAbsolutePath(),baudrate,flags);
L.tag("native open return null");
}
mFileInputStream = new FileInputStream(mFd);
mFileOutputStream = new FileOutputStream(mFd);
}
public FileInputStream getmFileInputStream() {
return mFileInputStream;
}
public void setmFileInputStream(FileInputStream mFileInputStream) {
this.mFileInputStream = mFileInputStream;
}
public FileOutputStream getmFileOutputStream() {
return mFileOutputStream;
}
public void setmFileOutputStream(FileOutputStream mFileOutputStream) {
this.mFileOutputStream = mFileOutputStream;
}
//JNI
private native static FileDescriptor open(String path,int baudrate,int flags);
public native void close();
static {
System.loadLibrary("serial_port");
}
}
package android_serialport_api;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.fx.serialporttest.L;
public class SerialPortFinger {
private static ReadThread readThread;
private static FileInputStream mFileInputStream;
private static FileOutputStream mFileOutputStream;
static String path = "/dev/ttyS0";//設備主板的串口地址,地址有所不同
public void startListener(){
SerialPort serialPort = new SerialPort(new File(path), 9600, 0);//9600是波特率,這個也是有所不同,具體要看設備
mFileInputStream = serialPort.getmFileInputStream();
mFileOutputStream = serialPort.getmFileOutputStream();//獲取串口寫入流
readThread = new ReadThread();
readThread.start();//開啟監聽
}
/**
* 發送指令到串口
*
* @param cmd
* @return
*/
public boolean sendCmds(String cmd) {
boolean result = true;
byte[] mBuffer = (cmd+"\r\n").getBytes();
try {
if (mFileOutputStream != null) {
mFileOutputStream.write(mBuffer);
} else {
result = false;
}
} catch (IOException e) {
e.printStackTrace();
result = false;
}
return result;
}
static class ReadThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
int len;
StringBuffer sb = new StringBuffer("");
while(true){ //循環監聽串口,讀取返回的數據
byte[] buffer = new byte[1024];
if(mFileInputStream==null){
return;
}
try {
len = mFileInputStream.read(buffer);
if(len>0){
sb.append(new String(buffer, 0, len));
}
if(!sb.toString().equals(""))
{
L.tag(sb.toString());//收到串口的返回數據,在日誌中列印出來
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
L.tag("接受完成");
}
}
}
}
⑹ 求助,求大神,android與串口通信
轉載最近做的項目用到了藍牙串口通訊功能.畢竟是接觸到底層的一些東西,讓吾等局限於java編程思想的小菜遇到了一些意想不到的問題.
問題一,連接不上藍牙串口
直接在android自帶的藍牙例子上嘗試,發現根本連接不上藍牙串口,後來對比別人的代碼發現uuid不一樣.因為以前用過UUID.randomUUID();所以想當然的認為所有uuid都是隨機生成的.通過搜索發現,android連接藍牙串口的話,必須要這個UUID
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
問題二,在讀取從藍牙串口返回的數據時,一直阻塞在inpustream.read(buffer);那裡.
起初是因為仿照網上的例子,直接發送指令的16進制字元串過去,返回不到數據.後來通過反編譯可以使用的藍牙串口助手apk發現,需要發送的不是16進制字元串的byte數組.而是將16進制字元串轉換成的byte數組.
String string = "01 00 05 07 00 00 00 00";
string = string.replaceAll(" ", ""); byte[] bytes = hexString2Bytes(string);//正確,要發送這個bytes
byte[] bytes = string.getBytes();//錯誤,發送這個bytes獲取不到數據.
附上hexString2Bytes方法
/**
* Convert hex string to byte[] 把為字元串轉化為位元組數組
*
* @param hexString
* the hex string
* @return byte[]
*/
public static byte[] hexStringToBytes(String hexString) {
hexString = hexString.replaceAll(" ", "");
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase(Locale.getDefault());
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
/**
* Convert char to byte
*
* @param c
* char
* @return byte
*/
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
得出結論.串口通訊時,如果獲取到錯誤的信息,是不返回數據的.在socket連接時.如果沒有獲取到數據.inputstream.read(buffer);是會一直阻塞的.
⑺ Android開發之串口通信:AndroidSerialPort
Android 串口通信,基於 谷歌官方android-serialport-api 編譯
項目github地址: https://github.com/AIlll/AndroidSerialPort
讀取數據時很可能會遇到分包的情況,即不能一次性讀取正確的完整的數據
解決辦法:可以在讀取到數據時,讓讀取數據的線程sleep一段時間,等待數據全部接收完,再一次性讀取出來。這樣應該可以避免大部分的分包情況
只接收一條數據的情況下,以上方法可以應對數據分包,數據量多的情況下需要考慮是否會因為sleep導致接收多條數據,可以根據通信協議核對包頭包尾等參數。
打開串口時,會檢測讀寫許可權,當沒有許可權時,會嘗試對其進行提權
⑻ Android UART 串口通信
最近有項目需要實現windows機器和Android開發版進行UART串口通信,經過3天查找嘗試,特記錄一下最終方案,希望之後的同行少走彎路,最後在git上回開源我最終的方案希望大家支持。
Android 3.0.1
Gradle 4.1
ARM開發版 : RK3399
PC機器:Win10
開發機器:MAC 10.13.3
先上圖
由於 android-serialport-api 項目中的so使用較old的ndk編譯,所以在對於Android 6.0 以上版本兼容的時候會報錯 dlopen failed: "has text relocations" 。且使用的mk進行編譯,特升級為用cmake編譯。
升級 android-serialport-api
項目結構:
app對應原項目中的各個Activity, androidserial 是mole 對應編譯之前的so,還有API的封裝。可以直接引用androidserial,調用方法參考app目錄下的activity。
注意 關於許可權!
當接入開發板後如果發現 Error You do not have read/write permission to the serial port 需要root 許可權 ,在開發者模式中開啟root 許可權 adb和應用
使用一下命令開啟Android對串口的讀寫許可權
setenforce 0 : 關閉防火牆,有人說關鍵是這,但是我的環境不用關閉,只要給許可權就可以
注意 關於ttyS1 - 6 ttyS1 - 6 對應的是 UART 串口1-6 一般都是一一對應的。這個具體要看一下開發板的說明。
記錄的比較糙,還請見諒,如有問題請留言,我看到後肯定回復。項目主要看結構,剩下的都是復制黏貼的事。 git地址:https://github.com/braincs/AndroidSerialLibrary