聲明:主要參照文檔:
Android開(kāi)發(fā)之USB數(shù)據(jù)通信
安卓USB通信之權(quán)限管理
第一:請(qǐng)求權(quán)限和請(qǐng)求權(quán)限回調(diào)(通過(guò)廣播回調(diào))
注冊(cè)一個(gè)廣播接收器用于接收USB權(quán)限被同意或拒絕后發(fā)出的廣播
//注冊(cè)USB設(shè)備權(quán)限管理廣播
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); //ACTION_USB_PERMISSION為自定義的字符串
context.registerReceiver(usbReceiver, filter);
其中usbReceiver
的實(shí)現(xiàn)是:
private BroadcastReceiver usbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(action.equals(ACTION_USB_PERMISSION)){//ACTION_USB_PERMISSION是前面我們自己自定義的字符串
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
LogUtils.i("已獲取USB權(quán)限");
}
} else {
LogUtils.i("USB權(quán)限被拒絕");
}
};
請(qǐng)求權(quán)限:
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);//關(guān)于這個(gè)mPermissionIntent 帝际,具體的作用我還沒(méi)弄明白泌神,明白以后補(bǔ)充
manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
manager.requestPermission(device,mPermissionIntent);//device是具體某個(gè)usb設(shè)備
執(zhí)行完這個(gè)后径玖,界面會(huì)彈出對(duì)話框詢問(wèn)用戶是否授予權(quán)限卷雕,然后會(huì)發(fā)送權(quán)限廣播尚揣,所以上面我們注冊(cè)一個(gè)廣播接收器來(lái)判斷權(quán)限狀態(tài)
第二:注冊(cè)USB設(shè)備插拔廣播
USB設(shè)備被插/拔后同樣會(huì)發(fā)送一個(gè)廣播显押,因此我們需要注冊(cè)一個(gè)接收器來(lái)接收這個(gè)廣播
IntentFilter stateFilter = new IntentFilter();
stateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
stateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
context.registerReceiver(usbStateReceiver, stateFilter);
其中.usbStateReceiver
的實(shí)現(xiàn)如下:
private BroadcastReceiver usbStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//USB連接上手機(jī)時(shí)會(huì)發(fā)送廣播android.hardware.usb.action.USB_STATE"及UsbManager.ACTION_USB_DEVICE_ATTACHED
if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
LogUtils.i("有USB設(shè)備連接");
} else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {//USB被拔出
LogUtils.i("USB連接斷開(kāi)扁达,程序退出走敌!");
}
}
};
詳細(xì)介紹以上兩種匀借,另附一個(gè)自己寫的USBUtil颜阐,里面的思路是,初始化話時(shí)傳入要連接設(shè)備的VendorId和ProductId吓肋,然后自動(dòng)進(jìn)行搜索凳怨,連接,授權(quán)等。只暴露讀/寫肤舞,開(kāi)/關(guān)給外界紫新,其他的全部自己處理
未經(jīng)測(cè)試,請(qǐng)勿直接使用李剖,僅供參考C⒙省!8菟场偶芍!
package com.police.policefaceproject.utils;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
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 java.util.Iterator;
import java.util.Map;
/**
* Created by Administrator on 2018/4/18.
*/
public class USBUtils {
private Activity activity;
private final String ACTION_USB_PERMISSION = "com.gudi.usb.permission";
private UsbManager manager;
private PendingIntent mPermissionIntent;
private BroadcastReceiver usbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(action.equals(ACTION_USB_PERMISSION)){
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
USBCtrl(context);
}
} else {
LogUtils.i("USB權(quán)限被拒絕");
if(activity!=null && !activity.isDestroyed()){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
UiUtils.Alert(activity, "權(quán)限錯(cuò)誤", "請(qǐng)重新插拔設(shè)備后,授予應(yīng)用訪問(wèn)USB權(quán)限","確定", new UiUtils.AlertCallBackOne() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
;
}
});
}
}
}
}
};
private UsbDeviceConnection usbConnection;
private UsbEndpoint uepIn;
private UsbEndpoint uepOut;
private int mProductId,mVendorId;
private BroadcastReceiver usbStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//USB連接上手機(jī)時(shí)會(huì)發(fā)送廣播android.hardware.usb.action.USB_STATE"及UsbManager.ACTION_USB_DEVICE_ATTACHED
if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {//判斷其中一個(gè)就可以了
LogUtils.i("有USB設(shè)備連接");
showMsg("有USB設(shè)備連接");
USBCtrl(context);
} else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {//USB被拔出
LogUtils.i("USB連接斷開(kāi)德玫,程序退出匪蟀!");
showMsg("USB連接斷開(kāi),請(qǐng)重試");
closeConn();
}
}
};
public void init(Activity context,int productId,int vendorId){
activity = context;
mProductId = productId;
mVendorId = vendorId;
manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
//注冊(cè)USB設(shè)備權(quán)限管理廣播
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
context.registerReceiver(usbReceiver, filter);
//注冊(cè)USB設(shè)備插拔廣播
IntentFilter stateFilter = new IntentFilter();
stateFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
stateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
stateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
context.registerReceiver(usbStateReceiver, stateFilter);
}
private Map<String,UsbDevice> getDevices(){
if(manager != null){
Map<String,UsbDevice> deviceMap = manager.getDeviceList();
return deviceMap;
}
return null;
}
private UsbDeviceConnection openDevice(Context context,UsbDevice device){
if(manager.hasPermission(device)){
UsbDeviceConnection DeviceConnection = manager.openDevice(device);
return DeviceConnection;
}else{
LogUtils.i("請(qǐng)求USB權(quán)限");
manager.requestPermission(device,mPermissionIntent);
return null;
}
}
private void USBCtrl(Context context){
//獲取設(shè)備列表
Map<String,UsbDevice> devicesList= getDevices();
if(devicesList == null || devicesList.size() <=0){
LogUtils.e("未查找到USB設(shè)備");
showMsg("未查找到設(shè)備宰僧,請(qǐng)重新插拔設(shè)備");
}else{
//遍歷尋找指定設(shè)備
Iterator<UsbDevice> deviceIterator = devicesList.values().iterator();
while(deviceIterator.hasNext()){
UsbDevice usb= deviceIterator.next();
if(usb.getVendorId() == mVendorId && usb.getProductId() == mProductId){
//查找到指定設(shè)備
connDevice(context,usb);
break;
}
}
}
}
private void connDevice(Context context,UsbDevice device){
UsbEndpoint uep;
//獲得設(shè)備接口
UsbInterface usbInterface = device.getInterface(0);
//查找輸入材彪,輸出端
for(int i =0;i<usbInterface.getEndpointCount();i++){
uep=usbInterface.getEndpoint(i);
if(uep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK){
if(uep.getDirection() == UsbConstants.USB_DIR_IN){
uepIn = uep;
}else if(uep.getDirection() == UsbConstants.USB_DIR_OUT){
uepOut = uep;
}
}
}
usbConnection = openDevice(context,device);
if(usbConnection == null){
LogUtils.e("連接設(shè)備失敗");
showMsg("連接設(shè)備失敗,請(qǐng)賦予權(quán)限");
return ;
}
if(usbConnection.claimInterface(usbInterface,true)){//聲明獨(dú)占此接口琴儿,在發(fā)送或接收數(shù)據(jù)前完成
//鎖定成功
}else{
//鎖定失敗
usbConnection.close();
usbConnection = null;
LogUtils.e("鎖定接口失敗");
showMsg("鎖定接口失敗段化,請(qǐng)插拔設(shè)備重試");
}
}
public int write(byte[] data){
if(usbConnection != null){
int len= usbConnection.bulkTransfer(uepOut, data, data.length, 3000);
LogUtils.i("通過(guò)USB接口發(fā)送"+data.length+"數(shù)據(jù)");
return len;
}else{
LogUtils.i("usbConnection為null");
return -1;
}
}
public byte[] read(byte[] data){
if(usbConnection != null){
int len= usbConnection.bulkTransfer(uepOut, data, data.length, 3000);
LogUtils.i("通過(guò)USB接口接收"+data.length+"數(shù)據(jù)");
return data;
}else{
LogUtils.i("接收數(shù)據(jù),usbConnection為null");
return null;
}
}
public void closeConn(){
if(usbConnection != null){
usbConnection.close();
usbConnection=null;
}
}
private void showMsg(final String msg){
if(activity!=null ){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
UiUtils.toast(activity.getApplicationContext(),msg);
}
});
}
}
}