显示串口列表这个操作还不涉及底层的东西,因为Android与Linux相似,有串口设备就会在/dev目录下生成一个文件,比如/dev/ttyS0之类的,在谷歌的ndroid-serialport-api项目中,有一个SerialPortFinder.java方法,这个方法是不涉及底层的,没有native方法,也不需要c和h文件,所以我觉得Android串口入门,应该先从这个文件开始了解。
4、然后将SerialPortFinder.java复制到你的目录下
这个文件可以在
https://github.com/cepr/android-serialport-api
下载,其中该文件在
android-serialport-api-master/android-serialport-api/project/src/android_serialport_api/SerialPortFinder.java
然后我们就可以使用了。
getAllDevicesPath()
它会返回一系列的串口名称给你,你只要拿一个字符串数组接住它就可以了
String[] devices=new SerialPortFinder().getAllDevicesPath();
之后你将devices中的字符串数组,用循环取出来,然后以TextView的方式显示出来也可以,你会发现一堆”/dev/ttyS0”,”/dev/ttyS1”之类的,这些就是串口路径,注意,Android和Linux相似,与Windows不相似,Android操作串口时操作路径,而Windows是串口名称“COMx”,示例如下:
Linux:SerialPort(“/dev/ttyS1”,9600,N,8,1)
Windows:SerialPort(“COM1”,9600,N,8,1)
这个方法的内容如下:
public String[] getAllDevicesPath() {
Log.d(TAG, "获取所有串口地址");
Vector<String> devices = new Vector<>();
try {
// Parse each driver
for (Driver driver : getDrivers()) {
for (File file : driver.getDevices()) {
String device = file.getAbsolutePath();
devices.add(device);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return devices.toArray(new String[0]);
}
里面主要使用了SerialPortFinder.java中的
getDrivers()
以及
Driver类下的
getDevices()
这两个方法看起来很相似,实际上是有本质的区别,首先getDrivers()获取到的是Drivers(注意后缀s),而一个Drivers中包含多个driver,一个driver中包含多个device(File),使用driver.getDevices()可以获得Devices(注意后缀s),即多个device。
以各个变量的串口数量来排序如下:
Drivers>driver==Devices>device(1个)
getDrivers()操作的路径是
/proc/tty/drivers
而getDevices()操作的路径是
/dev
/dev下一个ttySX是一个串口device(File),那么多个device就是串口集合Devices,一个串口集合又以driver表示在/proc/tty/drivers中,getDrivers()就是获取串口集合driver的集合,所以不管是后面的getAllDevices()方法还是getAllDevicesPath()方法,都会用两个循环来取串口设备device(File)。
for (Driver driver : getDrivers()) {
for (File file : driver.getDevices()) {
……
}
}
为了方便我们选中某个就进去,然后操作它,我们还是把它放在ListView里。
我们写一个ListView用来显示串口列表
1、将原本的activity_main.xml内容修改如下:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/id_list"/>
LinearLayout>
内容如下:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/id_item_text"
android:textSize="32sp"/>
LinearLayout>
3、本来想用ListAdapter做适配器的,不过感觉里面太多方法用不上,还是BaseAdapter简单一点,实现如下:
MainActivity.java
package com.a;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String[] devices=new SerialPortFinder().getAllDevicesPath();
ListView listView=findViewById(R.id.id_list);
BaseAdapter bA=new BaseAdapter() {
@Override
public int getCount() {
return devices.length;
}
@Override
public Object getItem(int position) {
return devices[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null)
convertView=getLayoutInflater().inflate(R.layout.item_layout,null);
TextView textView=convertView.findViewById(R.id.id_item_text);
textView.setText(devices[position]);
return convertView;
}
};
listView.setAdapter(bA);
}
}
4、效果如下:
补充:截图方式,点击左下角logcat,拉高,有一个照相机图标,点击即可。
函数getAllDevices()其实就是把device和driver结合起来,
deviceName (driverName)
将原来的getAllDevicesPath()函数改为getAllDevices()函数
final String[] devices=new SerialPortFinder().getAllDevices();
如果用过串口设备的小伙伴知道,一些设备往往有多个串口,而有一些是不能被使用的,比如上面的GS,他们表现出来的状态就是不可读不可写,那么我们如何识别这种状态呢?
我们在onCreate的
final String[] devices=new SerialPortFinder().getAllDevicesPath();
后添加如下内容,对文件的可读可写进行判断
final List<String> data = new ArrayList<>();
if (devices.length > 0) {
for (String device : devices) {
File file = new File(device);
String path = file.getAbsolutePath();
StringBuilder permission = new StringBuilder();
permission.append("[");
permission.append(file.canRead() ? " 可读" : "不可读");
permission.append(file.canWrite() ? " 可写 " : " 不可写 ");
permission.append(file.canExecute() ? "可执行" : "不可执行");
permission.append("]");
String msg = "(" + path + ")" + " 权限:" + permission;
data.add(msg);
}
}
并将BaseAdapter中的TextView获取文本的方式修改如下:
textView.setText(data.get(position));
MainActivity.java完整代码
package com.a;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String[] devices=new SerialPortFinder().getAllDevicesPath();
final List<String> data = new ArrayList<>();
if (devices.length > 0) {
for (String device : devices) {
File file = new File(device);
String path = file.getAbsolutePath();
StringBuilder permission = new StringBuilder();
permission.append("[");
permission.append(file.canRead() ? " 可读" : "不可读");
permission.append(file.canWrite() ? " 可写 " : " 不可写 ");
permission.append(file.canExecute() ? "可执行" : "不可执行");
permission.append("]");
String msg = "(" + path + ")" + " 权限:" + permission;
data.add(msg);
}
}
ListView listView=findViewById(R.id.id_list);
BaseAdapter bA=new BaseAdapter() {
@Override
public int getCount() {
return devices.length;
}
@Override
public Object getItem(int position) {
return devices[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView==null)
convertView=getLayoutInflater().inflate(R.layout.item_layout,null);
TextView textView=convertView.findViewById(R.id.id_item_text);
textView.setText(data.get(position));
return convertView;
}
};
listView.setAdapter(bA);
}
}
#technology/Android/SerialPort