当我们使用usb外设设备的时候,我们需要简单的了解下Android为我们提供的API。关于常用的系统api都在android.hardware.usb包下,主要以下几个类:UsbManager ?、?UsbDevice ?、?UsbDeviceConnection ?,?UsbEndpoint ?,?UsbInterface ?UsbRequest ?,?UsbConstants。
UsbManager常用方法
getDeviceList() | 获得usb设备的列表,存储在一个HashMap中 | hasPermission(UsbDevice device) | 判断当前应用程序是否具有接入usb设备的权限 | openDevice(UsbDevice device) | 打开USB设备,以便向此USB设备发送和接受数据,返回一个关于此USB设备的连接 |
UsbDevice常用方法
getDeviceClass() | 返回此USB设备的类别,用一个整型来表示 | getDeviceId() | 返回唯一标识此设备的ID号,也用一个整型来表示 | getDeviceName() | 返回此设备的名称,用一个字符串来表示 | getDeviceProtocol() | 返回此设备的协议类别,用一个整型来表示 | getDeviceSubclass() | 返回此设备的子类别,用一个整型来表示 | getVendorId() | 返回设备的vid,也就是生产商ID | getProductId() | 返回设备的pid,也就是产品ID | getInterfaceCount() | 返回此设备的接口数量 | getInterface(int index) | 得到此设备的一个接口,返回一个UsbInterface |
关于api的方法作用,这里也就不在一一赘述,源码里面都有注释,推荐一个在线访问源码的网站
http://androidxref.com/
我们整体的思路是在UsbService静态注册一个广播,然后去调用UsbAlsaManager里面的usb audio设备切换的方法。
了解了以上,我主要修改是在如下位置
frameworks\base\services\usb\java\com\android\server\usb\UsbAlsaManager.java
UsbAlsaManager.java主要是用来管理USB audio 设备以及?MIDI设备
public void selectDevice(int productId,int vendorId,UsbDevice usbDevice){
Slog.d(TAG, "selectAlsaDevice "+productId+";"+vendorId);
if(mAlsaDevices == null || mAlsaDevices.size()==0){
return ;
}
Slog.d(TAG, "mAlsaDevices != null"+usbDevice.getDeviceName());
for (UsbAlsaDevice usbAlsaDevice : mAlsaDevices) {//mAlsaDevices是系统用来存储usb audio设备的一个map
Slog.d(TAG, "usbAlsaDevice "+usbAlsaDevice.getDeviceAddress());
if(usbDevice.getDeviceName().equals(usbAlsaDevice.getDeviceAddress())){
if (mSelectedDevice != null) {
deselectAlsaDevice();
}
mSelectedDevice = usbAlsaDevice;
usbAlsaDevice.start();//去做切换的核心方法
Slog.d(TAG,"usbAlsaDevice:"+usbAlsaDevice.toString());
return ;
}
}
}
广播发送的代码:
public void switchAudio() {
Log.i(TAG, "====switchAudio====");
if (usbDeviceList == null) {
usbDeviceList = new ArrayList<>();
}
usbDeviceList.clear();
UsbManager mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
Map<String, UsbDevice> mDeviceMap = mUsbManager.getDeviceList();//获取系统内的所有usb设备
for (Map.Entry<String, UsbDevice> entry : mDeviceMap.entrySet()) {
UsbDevice usbDevice = entry.getValue();
if (isAudioMicDevice(usbDevice)) {// 判断是不是usb audio设备
usbDeviceList.add(usbDevice);
}
}
for(int i=0;i<usbDeviceList.size();i++) {
UsbDevice usbDevice = usbDeviceList.get(i);
if (usbDevice.getVendorId()==0x00&&usbDevice.getProductId()==0x00){//选择你要去切换的设备
Intent intent = new Intent("usbdevicemanager_usb_select_device");
intent.putExtra(UsbManager.EXTRA_DEVICE, usbDevice);
mContext.sendBroadcast(intent);
break;
}
}
}
private boolean isAudioMicDevice(UsbDevice usbDevice) {
boolean isAudio = false;
int intefaceCount = usbDevice.getInterfaceCount();
for (int ninterIndex = 0; !isAudio && ninterIndex < intefaceCount; ninterIndex++)
{
UsbInterface ntrface = usbDevice.getInterface(ninterIndex);
if (ntrface.getInterfaceClass() == UsbConstants.USB_CLASS_AUDIO) {
isAudio = true;
}
}
return isAudio;
}
?
广播接受的代码:
frameworks\base\services\usb\java\com\android\server\usb\UsbService.java
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
.equals(action)) {
if (mDeviceManager != null) {
mDeviceManager.updateUserRestrictions();
}
}else if(("usbdevicemanager_usb_select_device").equals(action)){
UsbDevice device = intent.<UsbDevice>getParcelableExtra(UsbManager.EXTRA_DEVICE);
if(device == null){
return;
}
Slog.w(TAG, "select_device"+device.getProductId()+";"+device.getVendorId());
if(mAlsaManager != null){
Slog.w(TAG,"mAlsaManager != null");
mAlsaManager.selectDevice(device.getProductId(),device.getVendorId(),device);
}
}
}
};
final IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction("usbdevicemanager_usb_select_device");
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiver(receiver, filter, null, null);
这样一来就可以做到去切换usb audio设备了。
|