通过手机 USB 和外接设备通讯;
package com.shanwan.usbdevice;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class USBIoService extends Service {
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private MyBinder myBinder;
private PendingIntent mPermissionIntent;
private UsbManager mUsbManager;
private UsbDevice mDevice;
private final ArrayList<UsbDeviceConnection> mUsbDeviceConnectionList = new ArrayList<>();
private final ArrayList<UsbInterface> mUsbInterfaceList = new ArrayList<>();
private Thread mIOThread;
private volatile StringBuilder stringBuilder = new StringBuilder();
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
MyLog.e("action:" + action);
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
if (mIOThread != null) {
mIOThread = null;
}
mDevice = device;
initConnection();
}
} else {
showToast(getString(R.string.usb_device_connect_error1));
}
}
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
releaseConnection();
} else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
connectDevice();
}
}
};
public USBIoService() {
initVariable();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
MyLog.d("call OnBind");
initBroadcastReceiver();
initUsbManager();
return myBinder;
}
@Override
public void onCreate() {
super.onCreate();
}
private void initVariable() {
myBinder = new MyBinder();
}
@SuppressLint("UnspecifiedImmutableFlag")
private void initBroadcastReceiver() {
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
registerReceiver(mUsbReceiver, filter);
}
private void initUsbManager() {
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
}
private void initConnection() {
try {
MyLog.e("getInterfaceCount:" + mDevice.getInterfaceCount());
showToast(getString(R.string.usb_device_connect_interface) + mDevice.getInterfaceCount());
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
UsbInterface mUsbInterface = mDevice.getInterface(i);
UsbDeviceConnection mUsbDeviceConnection = mUsbManager.openDevice(mDevice);
boolean connectionState = mUsbDeviceConnection.claimInterface(mUsbInterface, false);
if (connectionState) {
mUsbDeviceConnectionList.add(mUsbDeviceConnection);
mUsbInterfaceList.add(mUsbInterface);
}
stringBuilder.append("usb接口:").append(i).append("//").append(mDevice.getInterfaceCount()).append(" 已连接:").append(connectionState).append("\n");
for (int index = 0; index < mUsbInterface.getEndpointCount(); index++) {
UsbEndpoint point = mUsbInterface.getEndpoint(index);
// MyLog.e(" i:" + i + " :" + connectionState + " j:" + index + ":" + point.toString() + " type:" + point.getType() + " :" + point.getDirection());
//判断UsbEndpoint的类型,也即是type。这种类型的UsbDevice使用USB_ENDPOINT_XFER_BULK这种类型的UsbEndpoint进行通信。
if (point.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (point.getDirection() == UsbConstants.USB_DIR_IN) {
stringBuilder.append("BULK USB_DIR_IN index:").append(index);
} else if (point.getDirection() == UsbConstants.USB_DIR_OUT) {
stringBuilder.append("BULK USB_DIR_OUT index:").append(index);
}
} else if (point.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
if (point.getDirection() == UsbConstants.USB_DIR_IN) {
stringBuilder.append("INT USB_DIR_IN index:").append(index);
} else if (point.getDirection() == UsbConstants.USB_DIR_OUT) {
stringBuilder.append("INT USB_DIR_OUT index:").append(index);
}
}
}
}
} catch (Exception e) {
showToast("错误:" + e.getMessage());
}
}
private String sendData(byte[] sendbuffer) {
int timeOut = 500;
String resultStr = "";
try {
for (int i = 0; i < mUsbInterfaceList.size(); i++) {
UsbInterface mUsbInterface = mUsbInterfaceList.get(i);
for (int index = 0; index < mUsbInterface.getEndpointCount(); index++) {
UsbEndpoint point = mUsbInterface.getEndpoint(index);
if (point.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
if (point.getDirection() == UsbConstants.USB_DIR_IN) {
byte[] receivebuffer0 = new byte[8];
int retIn = mUsbDeviceConnectionList.get(i).bulkTransfer(point, receivebuffer0, receivebuffer0.length, timeOut);
MyLog.e("receive ret: " + retIn + " " + byte2HexString(receivebuffer0, receivebuffer0.length));
if (retIn > 0)
resultStr = new String(receivebuffer0);
MyLog.e("private key:" + resultStr);
} else if (point.getDirection() == UsbConstants.USB_DIR_OUT) {
int retOut = mUsbDeviceConnectionList.get(i).bulkTransfer(point, sendbuffer, sendbuffer.length, timeOut);
MyLog.e("send ret: " + retOut + " " + byte2HexString(sendbuffer, sendbuffer.length));
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return resultStr;
}
private String getData() {
int timeOut = 500;
String resultStr = "";
try {
for (int i = 0; i < mUsbInterfaceList.size(); i++) {
UsbInterface mUsbInterface = mUsbInterfaceList.get(i);
for (int index = 0; index < mUsbInterface.getEndpointCount(); index++) {
UsbEndpoint point = mUsbInterface.getEndpoint(index);
if (point.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
if (point.getDirection() == UsbConstants.USB_DIR_IN) {
byte[] receivebuffer0 = new byte[8];
int retIn = mUsbDeviceConnectionList.get(i).bulkTransfer(point, receivebuffer0, receivebuffer0.length, timeOut);
MyLog.e("receive ret: " + retIn + " " + byte2HexString(receivebuffer0, receivebuffer0.length));
if (retIn > 0)
resultStr = new String(receivebuffer0);
MyLog.e("resultStr:" + resultStr);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return resultStr;
}
private void connectDevice() {
MyLog.e("mUsbManager:" + mUsbManager);
if (mUsbManager == null)
initUsbManager();
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
if (deviceList == null) {
showToast("devices is null,please connect");
return;
}
for (Map.Entry<String, UsbDevice> entry : deviceList.entrySet()) {
UsbDevice mDevice = entry.getValue();
this.mDevice = mDevice;
stringBuilder.append("已授权:").append(mUsbManager.hasPermission(mDevice)).append("\n");
if (mUsbManager.hasPermission(mDevice))
initConnection();
else {
mUsbManager.requestPermission(this.mDevice, mPermissionIntent);//your code
}
}
}
private void showToast(String toastStr) {
if (toastStr != null) {
Toast.makeText(USBIoService.this, toastStr, Toast.LENGTH_SHORT).show();
stringBuilder.append(toastStr).append("\n");
}
}
@Override
public boolean onUnbind(Intent intent) {
releaseConnection();
releaseBroadcastReceiver();
return super.onUnbind(intent);
}
private void releaseConnection() {
if (mIOThread != null) {
mIOThread = null;
}
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
UsbDeviceConnection mUsbDeviceConnection = mUsbDeviceConnectionList.get(i);
UsbInterface mUsbInterface = mUsbInterfaceList.get(i);
mUsbDeviceConnection.releaseInterface(mUsbInterface);
mUsbDeviceConnection.close();
}
if (mDevice != null) {
mDevice = null;
}
}
private void releaseBroadcastReceiver() {
unregisterReceiver(mUsbReceiver);
}
public static String byte2HexString(byte[] bytes, int len) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < len; i++) {
int temp = bytes[i] & 0xff;
String s = Integer.toHexString(temp);
if (s.length() < 2) {
s = '0' + s;
} else {
s = s;
}
if ((i + 1) % 8 == 0) {
s = s + "\n";
} else {
s = s + "-";
}
str.append(s);
}
return str.toString();
}
public class MyBinder extends Binder {
public void startTransferData() {
connectDevice();
}
public String sendBufferData(byte[] data) {
return sendData(data);
}
public String getReceiveKey() {
return getData();
}
public String getLogStr() {
String ret = stringBuilder.toString();
stringBuilder = new StringBuilder();
return ret;
}
}
}
USBIoUtils.class
package com.shanwan.usbdevice;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import java.util.Random;
public class USBIoUtils {
private Activity activity;
private static USBIoService.MyBinder mBinder;
public final byte[] bytes = new byte[18];
private final ServiceConnection mIOServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBinder = (USBIoService.MyBinder) service;
mBinder.startTransferData();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mBinder = null;
}
};
public void startReceive(Activity activity) {
this.activity = activity;
final Intent intent = new Intent(activity, USBIoService.class);
activity.bindService(intent, mIOServiceConnection, Service.BIND_AUTO_CREATE);
}
public void stopReceive() {
activity.unbindService(mIOServiceConnection);
}
//length用户要求产生字符串的长度
public String getRandomString(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
bytes[0] = 4;
bytes[1] = (byte) random.nextInt(8);
StringBuilder stringBuilder =new StringBuilder();
for (int i = 0; i < length; i++) {
int number = random.nextInt(62);
bytes[i + 2] = (byte) str.charAt(number);
stringBuilder.append(str.charAt(number));
}
return stringBuilder.toString();
}
public String send(byte[] bytes) {
return mBinder.sendBufferData(bytes);
}
public String getIRK(){
return mBinder.getReceiveKey();
}
public String getLog(){
return mBinder.getLogStr();
}
}