USB设备访问弹出抑制?

Posted

技术标签:

【中文标题】USB设备访问弹出抑制?【英文标题】:USB device access pop-up suppression? 【发布时间】:2012-09-05 12:24:29 【问题描述】:

当 USB 设备连接到 android 平板电脑时,会出现一个要求用户许可的弹出窗口。我想压制它,因为客户不想要它。我该怎么办?

在代码中:

UsbManager.requestpermission(); 

被调用以授予 USB 设备临时访问权限。

这会引发一个弹出窗口。如何默认禁止弹出窗口或授予用户访问权限?

【问题讨论】:

【参考方案1】:

当您在应用程序中请求权限时,“默认情况下用于此 USB 设备”复选框似乎没有任何作用(我不确定为什么此复选框甚至会出现在此弹出窗口中。

相反,您应该在清单中为您的活动注册一个意图处理程序:

<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/usb_device_filter" />  
</activity>

您还必须在您的 xml 资源中创建一个过滤器文件,例如 res/xml/usb_device_filter:

<?xml version="1.0" encoding="utf-8"?>

<resources>
    <usb-device vendor-id="26214" product-id="26214" />
</resources>

此处的供应商 ID 和产品 ID 必须以十进制形式给出 - 上面的 VID 和 PID 均为 0x6666。

我上面给出的内容也适用于 USB 附件(即,附件是 USB 主机,android 是设备)——在这种情况下,意图过滤器应该注册

<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />

您还必须以完全相同的方式包含元数据过滤器。

请参阅http://developer.android.com/guide/topics/connectivity/usb/accessory.html 并搜索“使用意图过滤器”部分。

编辑

总结 - 如果您针对您的活动注册意图过滤器,USB 权限窗口将在连接 USB 设备/附件时立即显示。如果用户选中“默认使用此 USB 设备”框然后授予权限,这将被记住并且不会再次显示权限对话框(除非应用程序被卸载或用户从应用程序管理器中清除默认操作)。

我在这里放了一个小而糟糕的工作示例项目:

http://www.locusia.com/examples/permissionTest.zip

您需要编辑 res/xml/usb_device_filter.xml,否则这应该可以让您非常快速地对其进行测试。

对于服务...

似乎服务无法接收 USB 意图。我通过制作一个隐藏的活动来解决这个问题,然后重新广播意图。

我在清单中这样定义它:

<activity
    android:name=".activities.UsbEventReceiverActivity"
    android:label="YOUR APPLICATION NAME - This appears in the permission popup"
    android:theme="@style/Theme.Transparent" 
    android:noHistory="true"
    android:excludeFromRecents="true"
    android:taskAffinity="com.example.taskAffinityUsbEventReceiver"
    android:process=":UsbEventReceiverActivityProcess"
    android:exported="false"
    >    
    <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/usb_device_filter" />  
</activity>

(我的服务中有一个复杂的任务/流程布局,该区域是 YMMV)。

我这样定义活动:

public class UsbEventReceiverActivity extends Activity
   
    public static final String ACTION_USB_DEVICE_ATTACHED = "com.example.ACTION_USB_DEVICE_ATTACHED";
    @Override
    protected void onCreate(Bundle savedInstanceState)
    
        super.onCreate(savedInstanceState);
    

    @Override
    protected void onResume()
    
        super.onResume();

        Intent intent = getIntent();
        if (intent != null)
        
            if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED))
            
                Parcelable usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                // Create a new intent and put the usb device in as an extra
                Intent broadcastIntent = new Intent(ACTION_USB_DEVICE_ATTACHED);
                broadcastIntent.putExtra(UsbManager.EXTRA_DEVICE, usbDevice);

                // Broadcast this event so we can receive it
                sendBroadcast(broadcastIntent);
            
        

        // Close the activity
        finish();
    

最后一块拼图,透明主题(我不确定,但你可能会使用内置的 android 半透明主题) - res/values/styles.xml:

<?xml version="1.0" encoding="utf-8"?>  
    <resources>  
    <style name="Theme.Transparent" parent="android:Theme">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:backgroundDimEnabled">false</item>
        <item name="android:windowAnimationStyle">@null</item>
    </style>  
</resources>  

【讨论】:

对于 USB 主机模式,此信息在 developer.android.com/guide/topics/connectivity/usb/host.html 中提供。该页面上的“使用设备”部分说应用程序必须“2. 如果尚未获得连接到 USB 设备的权限,请向用户询问。” OP 的问题(也是我的问题!)是如何指示已授予权限,以便永远不会发生弹出窗口并且应用程序可以立即使用设备。 @kbro 当您说“权限已被授予”时,您到底是什么意思?如果已授予权限,则函数 UsbManger.hasPermission()(传递附件或设备)将返回 true,您可以打开并使用附件/设备。没有办法完全抑制弹出窗口 - 它必须至少显示一次,并且用户必须选中“默认情况下用于此设备”框并按是/确定/接受 - 请注意,您必须注册对活动进行意图过滤,以便记住您的应用程序的权限。 我只是在上面的答案中添加了另一段,因为之前可能并不完全清楚。 好的,我知道 android 必须至少询问一次,但我无法做到这一点 - 每次移除并重新插入设备时都会询问。我想你说的原因是应用程序调用了 RequestPermission。我需要完全回复事件过滤器。 在这种情况下自动授予权限如何工作 - 服务是否因为它与 Activity 属于同一 APK 的一部分而获得它?【参考方案2】:

晚了,但我希望能有所帮助。官方android docs 表示“当用户连接与您的设备过滤器匹配的设备时,系统会向他们显示一个对话框,询问他们是否要启动您的应用程序。如果用户接受,您的应用程序将自动获得访问设备的权限,直到设备已断开连接。”。如果您还选中了记住设备的复选框,则会授予权限,直到应用卸载或通过应用管理器删除数据。

所以你必须这样做:

    将intent-filter 添加为Wayne says,(并删除您主要活动中的所有权限)。 安装应用并关闭。 拔下并插入您的 USB。 接受权限并选中复选框以记住设备。 享受吧。

【讨论】:

如果您希望 USB 电缆在开机时已经插入,您有什么建议吗?我已经实现了这种方法,如果我在通电后插入 USB 电缆,效果会很好,但就我而言,我希望电缆始终保持插入状态。 不,直到您至少第一次这样做,因为事件在附加设备上...

以上是关于USB设备访问弹出抑制?的主要内容,如果未能解决你的问题,请参考以下文章

使用时以编程方式弹出 USB 设备

在 Linux 上弹出 USB 设备

USB设备驱动开发之远程访问USB设备(二 USB设备虚拟端)

USB设备驱动开发之远程访问USB设备

7 Linux usb驱动框架分析

将 Linux /dev/USB 作为标准文件访问以与 USB 设备通信