1.最近有个新的需求用到了安卓通过usb与stm32通讯,在此记录下。
由于是USB通讯所以注意要在清单文件AndroidManifest.xml中添加如下权限:
1,添加相应权限:
<uses-permission android:name="android.permission.HARDWARE_TEST" />
2,AndroidManifest.xml中添加uses-feature过滤所有你设备不支持的应用:
<uses-feature android:name="android.hardware.usb.host" android:required="true"/>
3, SDK必须是12以上的,因为从 Android3.1开始,才正式支持USB Host相应开发。
4, <activity
android:name="com.epoint.testusb.UsbHostActivity"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 以下内容的 vendor-id、product-id就是USB的vid和pid了,填写自己设备对应的数据->
<usb-device vendor-id="1155" product-id="22288"/>
</resources>
下面直接贴上主程序代码。测试可以发送和接收数据。
public class UsbHostActivity extends Activity implements View.OnClickListener { TextView tvHostMessage; TextView etHostMessage; private UsbManager mUsbManager; private UsbDevice mDevice; private PendingIntent mPermissionIntent; private CommunicationThread mCommThread; private String mData; private volatile boolean mExit = false; private byte[] mBytes = new byte[8]; private StringBuffer mStringBuffer = new StringBuffer(); private static final String ACTION_USB_PERMISSION = "com.mobilemerit.usbhost.USB_PERMISSION"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.usb_host_activity); initView(); } private void initView() { setTitle("Host设备"); // getNbViewHolder().nbBack.setVisibility(View.GONE); tvHostMessage = (TextView) findViewById(R.id.tv_host_message); etHostMessage = (TextView) findViewById(R.id.et_host_message); Button btn_device = (Button) findViewById(R.id.btn_get_device); Button btn_send = (Button) findViewById(R.id.btn_send_message); Button btn_file = (Button) findViewById(R.id.btn_get_file); btn_device.setOnClickListener(this); btn_send.setOnClickListener(this); btn_file.setOnClickListener(this); mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); registerReceiver(mUsbReceiver, filter); } public void onClick(View view) { switch (view.getId()) { case R.id.btn_get_device: Toast.makeText(getApplicationContext(), "获取中", Toast.LENGTH_SHORT).show(); checkDevice(); break; case R.id.btn_send_message: //setText("发送信息内容:" + etHostMessage.getText().toString()); //发送消息 mData = etHostMessage.getText().toString(); synchronized (mData) { if (!TextUtils.isEmpty(mData)) { byte sendBuff[] = ByteUtil.hexStr2bytes("f00101efee000000"); // 此方法可能不可以发送,会返回错误 // byte sendBuff[] = {(byte)240, 0x01, 0x01, (byte)239, (byte) 238, 0x00, 0x00, 0x00}; //byte[] sendBuff = mData.getBytes(); int len = connection.bulkTransfer(endpointOut, sendBuff, sendBuff.length, 100); if (len >= 0) { mExit = false; setText("发送成功:"); } else { setText("发送失败"+len); } } int i = connection.bulkTransfer(endpointIn, mBytes, mBytes.length, 500); MyApplication.printLogDebug("数据="+i); if (i > 0) { String value = byteToHex(mBytes, i).replace("\n", ""); keyVal = ""; setText("接收的数据111:" + value); } } break; case R.id.btn_get_file: Toast.makeText(getApplicationContext(), "选择文件发送", Toast.LENGTH_SHORT).show(); break; } } public static String keyVal = ""; //串口返回转换(3188,3288) public static String byteToHex(byte[] b, int length) { for (int i = 0; i < length; i++) { String temp = Integer.toHexString(b[i] & 0xFF); if (temp.length() == 1) { temp = "0" + temp; } keyVal = keyVal + temp; } return keyVal.toUpperCase(); } UsbEndpoint endpointIn = null; UsbEndpoint endpointOut = null; private UsbDeviceConnection connection; private class CommunicationThread extends Thread { @Override public void run() { mExit = false; UsbInterface usbInterface = mDevice.getInterface(0); connection = mUsbManager.openDevice(mDevice); if (connection == null) { return; } if (!connection.claimInterface(usbInterface, true)) { connection.close(); return; } for (int i = 0; i < usbInterface.getEndpointCount(); i++) { final UsbEndpoint endpoint = usbInterface.getEndpoint(i); if (endpoint.getDirection() == UsbConstants.USB_DIR_IN) { endpointIn = endpoint; } if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) { endpointOut = endpoint; } } if (endpointOut == null) { setText("输出端口为空"); return; } if (endpointIn == null) { setText("输入端口为空"); return; } } } private void checkDevice() { HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList(); //pageControl.hideLoading(); if (deviceList == null || deviceList.isEmpty()) { setText("checkDevice fail"); return; } Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); while (deviceIterator.hasNext()) { UsbDevice device = deviceIterator.next(); setText("device_name:" + device.getDeviceName()); mUsbManager.requestPermission(device, mPermissionIntent); break; } } private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (ACTION_USB_PERMISSION.equals(action)) { synchronized (this) { UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { setText("授权成功"); if (device != null) { mDevice = device; mCommThread = new CommunicationThread(); mCommThread.start(); } } else { setText("授权失败"); } } } } }; private void setText(String text) { final String newText = "\n" + text; runOnUiThread(new Runnable() { @Override public void run() { tvHostMessage.setText(tvHostMessage.getText() + newText); } }); } }