android apk使用framework中usb接口范例(应用RtkGps分析)
来源:互联网 发布:膛线无缝管淘宝有售吗 编辑:程序博客网 时间:2024/05/16 02:49
<intent-filter><action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /></intent-filter><meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"android:resource="@xml/usb_device_filter" />
其中usb_device_filter是一个自己编写的文件,里面描述的是希望接管的usb设备信息。如:
<?xml version="1.0" encoding="utf-8"?><resources><!-- Prolific --><usb-device vendor-id="1659"product-id="8963" /><!-- 0x067b 0x2303 PL2303 Serial--><usb-device vendor-id="1659"product-id="4660" /><!-- 0x067b 0x1234 DCU-11 Phone Cable--><usb-device vendor-id="21362"product-id="8963" /><!-- 0x5372 0x2303 Prolific2 PL2303--><!-- Generic comunnication device with Abstract Control Model subclass--><usb-device class="2"subclass="0"protocol="0" /></resources>
主要是vendor-id和product-id的值与usb设备一致。
2、首先在MainActivity中当mNavDrawerServerSwitch被checked时,start RtkNaviService,在onStartCommand中执行processStart,在processStart中执行UsbToRtklib.start(),在UsbToRtklib.start()执行UsbReceiver.start(),在UsbReceiver.start()中增加usb事件的检测:
f = new IntentFilter();
f.addAction(ACTION_USB_DEVICE_ATTACHED);
f.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
f.addAction(ACTION_USB_PERMISSION);
mContext.registerReceiver(mUsbStateListener, f);
mServiceThread = new UsbServiceThread();
mServiceThread.start();
执行UsbServiceThread的run时,子线程UsbServiceThread卡在serialControllerSet.block();等待serialControllerSet.open()来唤醒这个子线程。
主线程之后执行
findSupportedDevice() ---> probeDevice(),之后就new出UsbPl2303Controller,new UsbPl2303Controller 时就会拿到各种interface和endpoint的信息,可以用来传递数据用。
|
1)已连接usb设备:
主线程:
requestPermission()
|
ACTION_USB_PERMISSION
|
2)没有连接usb设备:当连接usb设备后,就会执行:
mUsbStateListener下的
ACTION_USB_DEVICE_ATTACHED
|
onUsbDeviceAttached();
|
probeDevice() ---> probeDevice(),之后就new出UsbPl2303Controller,requestPermission()
|
ACTION_USB_PERMISSION
|
3)
主线程:
onUsbPermissionGranted()
|
mServiceThread.setController(controller); 其中执行serialControllerSet.open() ,唤醒UsbServiceThread线程。
UsbServiceThread子线程:
mUsbController.attach();这个执行打开usb设备:
mUsbConnection = mUsbManager.openDevice(mUsbDevice);
if (mUsbConnection == null) {
throw new UsbControllerException("openDevice() failed");
}
将usb设备和本程序绑定(用本程序代替usb上层驱动来管理usb设备,如:当usb设备是U盘时,代替mass storge驱动来管理u盘,此时u盘会被卸载)
for (int i=0; i< mUsbInterfaces.length; ++i) {
if (mUsbConnection.claimInterface(mUsbInterfaces[i], true) == false) {
for (int j=0; j<i; ++j) {
mUsbConnection.releaseInterface(mUsbInterfaces[j]);
}
mUsbConnection.close();
throw new UsbControllerException("claimInterface() failed");
}
}
对usb设备的reset和初始化(就是驱动usb设备,发送controlTransfer设置usb设备)
if (!pl2303Reset()) {
detach();
throw new UsbControllerException("pl2303Reset() failed");
}
if (!pl2303Init()) {
detach();
throw new UsbControllerException("pl2303Init() failed");
}
使用之前拿到的bulk endpoint得到InputStream和OutputStream,为之后数据传输做准备。
inputStream = new UsbSerialInputStream(mUsbConnection, mBulkInEndpoint);
outputStream = new UsbSerialOutputStream(mUsbConnection, mBulkOutEndpoint);
bulk endpoint 可以使用mUsbConnection.bulkTransfer传送数据给usb device;
control endpoint可以使用mUsbConnection.controlTransfer传送数据给usb device;(control endpoint一般是endpoint 0,是不直接暴露给用户使用的,必须用这个函数操作。)
下面详解各种用法:
1、interrupt 方式数据传输:
protected static class UsbSerialInterruptListener extends Thread {
private boolean cancelRequested = false;
private UsbDeviceConnection mUsbConnection;
private ByteBuffer buffer;
private UsbRequest request;
public UsbSerialInterruptListener(UsbDeviceConnection connection, UsbEndpoint endpoint) {
this.mUsbConnection = connection;
this.setName("PL2303InterruptListener");
buffer = ByteBuffer.allocate(endpoint.getMaxPacketSize());
request = new UsbRequest();
request.initialize(connection, endpoint);
}
@Override
public void run() {
mainloop: while(!cancelRequested()) {
request.queue(buffer, buffer.capacity());
if (mUsbConnection.requestWait() == request) {
if (D) Log.v(TAG, "Interrupt received: " + buffer.toString() +
Arrays.toString(buffer.array()));
synchronized(this) {
try {
this.wait(100);
} catch (InterruptedException e) {
break mainloop;
}
if (cancelRequested) break mainloop;
}
}else {
Log.e(TAG, "requestWait failed, exiting");
break mainloop;
}
}
Log.d(TAG, "Pl2303InterruptListener thread stopped");
}
public synchronized void cancel() {
cancelRequested = true;
this.notify();
}
private synchronized boolean cancelRequested() {
return this.cancelRequested;
}
}
2、bulk的方式传输数据
bulk in:
protected class UsbSerialInputStream extends InputStream {
private static final int DEFAULT_READ_TIMEOUT_MS = 30000;
private int mTimeout = DEFAULT_READ_TIMEOUT_MS;
private UsbDeviceConnection mUsbConnection;
private UsbEndpoint mUsbEndpoint;
private byte rcvPkt[] = null;
public UsbSerialInputStream(UsbDeviceConnection connection,
UsbEndpoint bulkInEndpoint,
int writeTmoutMs
) {
mUsbConnection = connection;
mUsbEndpoint = bulkInEndpoint;
mTimeout = writeTmoutMs;
rcvPkt = new byte[mUsbEndpoint.getMaxPacketSize()];
}
public UsbSerialInputStream(UsbDeviceConnection connection,
UsbEndpoint bulkInEndpoint) {
this(connection, bulkInEndpoint, DEFAULT_READ_TIMEOUT_MS);
}
@Override
public int read() throws IOException {
synchronized(this) {
int rcvd = read(rcvPkt, 0, 1);
if (rcvd == 0) throw new IOException("timeout");
return rcvPkt[0] & 0xff;
}
}
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
int rcvd;
synchronized(this) {
if (offset == 0) {
rcvd = mUsbConnection.bulkTransfer(mUsbEndpoint, buffer,
count, mTimeout);
if (rcvd < 0) throw new IOException("bulkTransfer() error");
//if (D) Log.d(TAG, "Received " + rcvd + " bytes aligned");
return rcvd;
}else {
rcvd = mUsbConnection.bulkTransfer(mUsbEndpoint,
rcvPkt,
Math.min(count, rcvPkt.length),
mTimeout);
if (rcvd < 0) throw new IOException("bulkTransfer() error");
else if (rcvd > 0) {
System.arraycopy(rcvPkt, 0, buffer, offset, rcvd);
}
if (D) Log.d(TAG, "Received " + rcvd + " bytes");
return rcvd;
}
}
}
}
bulk out:
protected class UsbSerialOutputStream extends OutputStream {
private static final int DEFAULT_WRITE_TIMEOUT_MS = 2000;
private int mTimeout = DEFAULT_WRITE_TIMEOUT_MS;
private UsbDeviceConnection mUsbConnection;
private UsbEndpoint mUsbEndpoint;
private byte sndPkt[] = null;
public UsbSerialOutputStream(UsbDeviceConnection connection,
UsbEndpoint bulkOutEndpoint,
int writeTmoutMs
) {
mUsbConnection = connection;
mUsbEndpoint = bulkOutEndpoint;
mTimeout = writeTmoutMs;
sndPkt = new byte[mUsbEndpoint.getMaxPacketSize()];
}
public UsbSerialOutputStream(UsbDeviceConnection connection,
UsbEndpoint bulkOutEndpoint) {
this(connection, bulkOutEndpoint, DEFAULT_WRITE_TIMEOUT_MS);
}
@Override
public void write(int arg0) throws IOException {
write(new byte[] { (byte) arg0 } );
}
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
synchronized(this) {
while(count>0) {
/* XXX: timeout */
int length = count > sndPkt.length ? sndPkt.length : count;
System.arraycopy(buffer, offset, sndPkt, 0, length);
int snd = mUsbConnection.bulkTransfer(mUsbEndpoint, sndPkt, length, mTimeout);
if (snd<0) throw new IOException("bulkTransfer() failed");
count -= snd;
offset += snd;
}
}
}
}
3、control方式传输:
mUsbConnection.controlTransfer(
UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
0x01 /* set request */,
0x0000,
0x0000,
null,
0,
PL2303_INIT_TIMEOUT_MS) >= 0;
control方式一般需要看芯片手册来确定具体设置值替代上面的参数。
- android apk使用framework中usb接口范例(应用RtkGps分析)
- android framework base usb server 分析
- Android中TabActivity使用范例
- Android中TabActivity使用范例
- Android中TabActivity使用范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- Android .mk 编译 APK 范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- Android.mk编译APK范例
- vux scroller上拉加载如何停止加载更多
- pygame入门小游戏(外星人入侵(4))
- void 无类型
- CentOS7防火墙配置
- java定时任务 timer
- android apk使用framework中usb接口范例(应用RtkGps分析)
- 最通俗易懂的JavaScript知识,应有尽有。
- Ajax的使用
- 关于webstorage的使用
- 应用层--计算机网络自顶向下笔记(二)
- XlistView(代码)
- #再一次用construct2做游戏
- C语言我喜欢这样写
- 垂直居中