使用device_filter.xml资源文件过滤USB枚举结果

2024-07-01

按照中的说明进行操作Android USB 主机文档 http://developer.android.com/guide/topics/connectivity/usb/host.html#discovering-d,我设法通过USB_DEVICE_ATTACHED意图。要限制对某些设备的通知,可以指定资源文件:

<activity ...>
...
    <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/device_filter" />
</activity>

设备过滤器.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <usb-device vendor-id="1234" product-id="5678" />
</resources>

问题是,如果服务在 USB 设备插入后启动,则不会收到意图。我可以用getDeviceList http://developer.android.com/reference/android/hardware/usb/UsbManager.html#getDeviceList%28%29获取设备列表,但希望避免重复过滤条件device_filter.xml文件。那可能吗?


过滤功能的实现是frameworks/base/services/java/com/android/server/usb/UsbSettingsManager.java,但不幸的是这些都是私人的。我提取了它的部分实现,可以这样使用:

private void scanDevices() {
    ArrayList<UsbDevice> devices;

    try {
        devices = UsbDeviceFilter.getMatchingHostDevices(this, R.xml.wifi_devices);
    } catch (Exception e) {
        Log.w(TAG, "Failed to parse devices.xml: " + e.getMessage());
        return;
    }

    for (UsbDevice device : devices) {
        Log.d(TAG, "Matched device " + device);
    }
}

目前仅接受主机设备,但添加对附件设备的支持很简单。

UsbDeviceFilter.xml:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.content.Context;
import android.content.res.XmlResourceParser;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;

/**
 * Utility to test whether a USB device is accepted by a device filter. Heavily
 * based on com.android.server.usb.UsbSettingsManager.
 * @author Peter Wu <[email protected] /cdn-cgi/l/email-protection>
 */
public class UsbDeviceFilter {
    private final List<DeviceFilter> hostDeviceFilters;

    public UsbDeviceFilter(XmlPullParser parser) throws XmlPullParserException,
            IOException {
        hostDeviceFilters = new ArrayList<UsbDeviceFilter.DeviceFilter>();
        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            String tagName = parser.getName();
            if ("usb-device".equals(tagName)
                    && parser.getEventType() == XmlPullParser.START_TAG) {
                hostDeviceFilters.add(DeviceFilter.read(parser));
            }
            eventType = parser.next();
        }
    }

    public boolean matchesHostDevice(UsbDevice device) {
        for (DeviceFilter filter : hostDeviceFilters) {
            if (filter.matches(device)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Get a list of connected USB Host devices matching the devices filter.
     * @param ctx A non-null application context.
     * @param resourceId The resource ID pointing to a devices filter XML file.
     * @return A list of connected host devices matching the filter. 
     * @throws XmlPullParserException
     * @throws IOException
     */
    public static ArrayList<UsbDevice> getMatchingHostDevices(Context ctx,
            int resourceId) throws XmlPullParserException, IOException {
        UsbManager usbManager = (UsbManager) ctx
                .getSystemService(Context.USB_SERVICE);
        XmlResourceParser parser = ctx.getResources().getXml(resourceId);
        UsbDeviceFilter devFilter;

        try {
            devFilter = new UsbDeviceFilter(parser);
        } finally {
            parser.close();
        }

        ArrayList<UsbDevice> matchedDevices = new ArrayList<UsbDevice>();
        for (UsbDevice device : usbManager.getDeviceList().values()) {
            if (devFilter.matchesHostDevice(device)) {
                matchedDevices.add(device);
            }
        }
        return matchedDevices;
    }

    public static class DeviceFilter {
        // USB Vendor ID (or -1 for unspecified)
        public final int mVendorId;
        // USB Product ID (or -1 for unspecified)
        public final int mProductId;
        // USB device or interface class (or -1 for unspecified)
        public final int mClass;
        // USB device subclass (or -1 for unspecified)
        public final int mSubclass;
        // USB device protocol (or -1 for unspecified)
        public final int mProtocol;

        private DeviceFilter(int vid, int pid, int clasz, int subclass,
                int protocol) {
            mVendorId = vid;
            mProductId = pid;
            mClass = clasz;
            mSubclass = subclass;
            mProtocol = protocol;
        }

        private static DeviceFilter read(XmlPullParser parser) {
            int vendorId = -1;
            int productId = -1;
            int deviceClass = -1;
            int deviceSubclass = -1;
            int deviceProtocol = -1;

            int count = parser.getAttributeCount();
            for (int i = 0; i < count; i++) {
                String name = parser.getAttributeName(i);
                // All attribute values are ints
                int value = Integer.parseInt(parser.getAttributeValue(i));

                if ("vendor-id".equals(name)) {
                    vendorId = value;
                } else if ("product-id".equals(name)) {
                    productId = value;
                } else if ("class".equals(name)) {
                    deviceClass = value;
                } else if ("subclass".equals(name)) {
                    deviceSubclass = value;
                } else if ("protocol".equals(name)) {
                    deviceProtocol = value;
                }
            }

            return new DeviceFilter(vendorId, productId, deviceClass,
                    deviceSubclass, deviceProtocol);
        }

        private boolean matches(int clasz, int subclass, int protocol) {
            return ((mClass == -1 || clasz == mClass)
                    && (mSubclass == -1 || subclass == mSubclass)
                    && (mProtocol == -1 || protocol == mProtocol));
        }

        public boolean matches(UsbDevice device) {
            if (mVendorId != -1 && device.getVendorId() != mVendorId)
                return false;
            if (mProductId != -1 && device.getProductId() != mProductId)
                return false;

            // check device class/subclass/protocol
            if (matches(device.getDeviceClass(), device.getDeviceSubclass(),
                    device.getDeviceProtocol()))
                return true;

            // if device doesn't match, check the interfaces
            int count = device.getInterfaceCount();
            for (int i = 0; i < count; i++) {
                UsbInterface intf = device.getInterface(i);
                if (matches(intf.getInterfaceClass(),
                        intf.getInterfaceSubclass(),
                        intf.getInterfaceProtocol()))
                    return true;
            }

            return false;
        }

    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用device_filter.xml资源文件过滤USB枚举结果 的相关文章

随机推荐

  • 从表达式创建动态 Linq select 子句

    假设我定义了以下变量 IQueryable
  • 如何将字典中从一个键到下一个键的所有值相加? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个字典 其中 DateTime Now Date 转换为字符串作为键 整数作为值 我需要以某种方式将从一个输入键到下一个键的所有
  • 打破弹性项目内的长单词

    我想打破 div2 内的长单词 div2 和 div3 宽度都不能大于父宽度 即 150px 唯一有效的是word break break all但这也会破坏简短的单词 div1 display flex max width 150px h
  • 是否可以获取 NSMutableAttributedString 的属性和范围列表?

    我创建了一个接受 NSAttributedString 的方法 并且我希望动态创建一个子视图和标签以将字符串放入其中 由于需要确定字体和大小等属性才能正确确定标签的大小 因此我需要确定是否可以迭代已应用于属性字符串的值和范围 我知道我可以单
  • ngx-bootstrap typeahead http 请求返回对象 Object

    我正在尝试构建一个返回 JSON 的服务的预输入 但是我的代码返回 object Object 而不是值 我究竟做错了什么 这似乎与我的 typeaheadoption 未正确映射到结果有关 但我不确定为什么会发生这种情况 这来自 ngx
  • MVC:我应该在哪里格式化数据?

    我从模型 带有数据的数组 获取数据 并且需要以特定格式显示 我需要迭代数组 格式化数据然后显示它 我应该在哪里格式化数据以显示 在模型 控制器还是视图中 谢谢 对数组的迭代并显示数据是在视图中完成的 因此我也会在视图中进行格式化 如果格式化
  • 如何更改 gdb 中的值

    所以我有这个家庭作业代码 我必须使用 gdb 进行调试 我发现了问题 但不知道如何使用gdb来改变它 define ARRAYSIZE 12 for i ARRAYSIZE 2 i gt 0 i for j i j lt ARRAYSIZE
  • 应用程序挂在 __psynch_mutexwait

    我们的应用程序似乎半随机地挂在 psynch mutexwait 处 它似乎与更新 CoreData 中存储的一堆数据的后台进程有关 但我完全无法弄清楚是谁锁定了导致死锁的原因 以下是 lldb 给我的完整堆栈跟踪 这显然是不完整的 并且线
  • 使用 spring hatoas 公开集合实体上的链接

    我的问题与这里提出的问题几乎相同 在 Spring Data REST 中公开集合实体上的链接 https stackoverflow com questions 24274127 exposing link on collection e
  • 是否可以与类型类中未提及的变量关联类型同义词?

    In 关联类型同义词 http www cse unsw edu au chak papers CKP05 html Chakravarty Keller Jones 该论文似乎表明以下内容是有效的 class C a where type
  • 如果相关服务被终止,如何更新小部件?

    我有一个录音应用程序 目前正在为其开发一个小部件 录音是由在前台状态的服务中运行的音频引擎执行的 每当音频引擎状态更改为暂停 播放 录制时 就会发送广播 并由更新小部件的接收器进行处理 这样 单击小部件中的录制按钮就会开始录制 这会导致发送
  • swaplevel() 和 reorder_levels() 有什么区别?

    在使用 pandas 的分层索引级别时 有什么区别swaplevel https pandas pydata org pandas docs stable generated pandas DataFrame swaplevel html
  • Polymer 1.x:如何在注销后重置整个应用程序

    我有一个聚合物应用程序 当用户注销时 我想将整个应用程序重置为原始状态 现在 当用户注销后重新登录时 应用程序会将用户返回到注销时所在的应用程序状态和页面 有没有方便的 即全局 应用程序设计或代码模式来实现这一点 如果没有任何方便 全局的方
  • 字符集中字符的顺序

    是否通过标准保证字符的顺序 例如 我可以算出字符集表中 1 符号后面跟着 2 符号吗 或者它是特定于平台的 1999 年的 C 标准对字符集是这样规定的 基本源字符集和基本执行字符集都应具有以下成员 拉丁字母表中的 26 个大写字母 拉丁字
  • 自定义 iOS 推送通知声音

    我一直面临一个问题 我在 iOS 中使用自定义声音实现了推送通知 它是一个 MP3 文件 当我在 iOS 5 中收到推送通知时它播放得很好 但在 iOS4 中 它不播放任何声音 你能帮我解决这个问题吗 代码是这样的 aps badge 10
  • 执行 Mongo 查询 db.collection.runCommand("text",{"search":"search text"})

    我需要在我的网站中添加全文搜索选项 在 mongodb 中添加数据库 蒙戈查询 db collection runCommand text search search text 给出了结果 但是如何使用C 执行它 collection In
  • 如何让 Meteor Cordova 应用程序允许访问域

    我刚刚做了流星更新 现在有版本 流星1 0 4 科尔多瓦4 2 0 我最近还使用 mup deploy 将我的服务器移动到数字海洋 我现在发现 虽然桌面和移动网站运行良好 但在 Android 移动应用程序中 图像不再加载 这些图像是公共
  • Angular Material 7 Datepicker:禁用多年视图

    我使用 angular material 7 0 0 rc 0 中的 MatDatepicker 并制作了一个复杂的过滤器 将时间选择器中的每个可见日期与包含大约 200 或 300 个值的数组中的每一天进行比较 每次我将日期选择器切换到多
  • 如何解决 npm install 在非 MAC 操作系统上抛出 fsevents 警告的问题?

    正在抛出以下警告npm install命令 npm WARN optional SKIPPING OPTIONAL DEPENDENCY email protected cdn cgi l email protection node mod
  • 使用device_filter.xml资源文件过滤USB枚举结果

    按照中的说明进行操作Android USB 主机文档 http developer android com guide topics connectivity usb host html discovering d 我设法通过USB DEV