我有一个应用程序在运行ICS 4.0.3的无根Android平板电脑上运行,该平板电脑通过USB主机模式接口控制USB设备。 android.hardware.usb.host.xml文件位于/ system / etc / permissions中,并且一切正常。除了...

重新启动后第一次运行该应用程序,然后插入USB设备时,我会弹出一个窗口,提示“允许应用程序APPNAME访问USB设备吗?[]默认情况下,此USB设备使用该设备。“取消确定””,我必须先点击“确定”,然后才能开始使用该设备。

我需要关闭用户确认,以便该应用可以直接使用该设备远。我该怎么做呢?我似乎对使用按键生成器来模拟用户点击屏幕上的按钮的一些建议,但我宁愿避免这种方法并进行设置,以使确认请求根本不会发生。 >
我可能无法让供应商为我做一个自定义内核构建,但是我应该能够从他们那里获得固件签名密钥,这样我就可以将我的应用程序签名为系统应用程序,如果可以的话。

一个相关的问题:勾选“默认情况下对此USB设备使用”框似乎无济于事-如果我拔出并重新插入该设备,则会再次收到确认提示。在这种情况下,我注意到每次拔出并重新插入(001、002、003等)时,/ dev / bus / usb / 001 /中的设备编号都会更改,这也许可以解释此特定问题。

评论

如果将应用程序部署到/ system / app,会发生什么?您可以在有和没有系统签名的情况下尝试使用。我将其写为评论是因为(a)我没有尝试过,并且(b)我不知道您是否可以使用此部署模型。

#1 楼

这个问题和答案基本上是https://stackoverflow.com/a/15151075/588476的副本。请参见上面的链接以获取示例程序和更深入的讨论。

到目前为止据我所知,有两种方法可以弹出USB权限框:


使用UsbManager.requestPermission(...)
从您的应用程序显式请求权限注册一个意图附件上的-filter,让系统在连接设备时请求许可。

在1的情况下,我发现弹出窗口中记住许可的复选框无效。

对我来说,我从软件中删除了所有与权限相关的代码,然后将意图过滤器放入清单中。插入USB设备后,如果尚未授予其权限,则会弹出USB权限框。如果用户单击“确定”但未选中“记住”框,则下次连接设备时,该框将再次弹出。但是,如果用户选中该框并按OK,则该框将永远不会再次显示(除非先卸载软件然后重新安装)。

我不确定是否存在与您的错误相关的错误设备显示为/ dev / bus / usb / 001,然后显示002等-如果您使用的是Intent过滤器,请告诉我,否则,记住复选框将无济于事。

我不会知道可以完全避免权限弹出的任何方式。我怀疑没有像您所说的那样深入研究android代码是没有办法的。

评论


你确定吗?拔出设备并重新连接后,我仍然看到许可请求。此行为与developer.android.com/guide/topics/connectivity/usb/host.html中的文档一致。 “使用意图过滤器”部分显示“如果用户接受,则您的应用程序将自动有权访问设备,直到断开设备连接”

–kbro
2013年3月7日23:09



我只能为那些设备上的Nexus 7,Galaxy S3和Galaxy Note担保,我只需要接受一次许可(Android设备以主机模式运行)-只要我启用复选框以记住决定即可。您使用的是哪种设备/ Android版本,我感觉这是自定义/ OEM设备?

– Wayne Uroda
13年8月8日,0:33

这是一款基于WonderMedia WM8850-mid SOM的OEM 7英寸平板电脑,运行着Android 4.0.3风格。

–kbro
13年8月8日在7:01

意向过滤器仅适用于当前引导会话。是的,我将USB设备插入手机并自动授予权限

–user924
19年8月23日在7:33

#2 楼

除了我的评论,我还研究了底层的Android代码。

我有一个可能的答案,但有四个以上的注意事项和障碍:


我没有尝试过,因为我没有合适的USB设备。
您需要新的权限
该权限要求您是系统应用程序
代码需要访问公共API中未提供的内容

如果部署普通的售后市场应用程序,则无需担心!

第一个先决条件是您具有MANAGE_USB权限。

然而,前提是您必须先使用系统密钥签名,然后将应用安装到/ system / app。

无论如何,如果可以,请输入以下代码:

   IBinder b = ServiceManager.getService(USB_SERVICE);
   IUsbManager service = IUsbManager.Stub.asInterface(b);
   service.grantDevicePermission(mDevice, uid);


mDevice是以前的设备。你可以查一下如何做到这一点的一个示例是这里的第一个答案。

都很好吗?编号uidServiceManager,因此不是公共API。在此示例中,这就是您尝试使用android.os.ServiceManager服务的方式(可能还有其他路线)。现在,解决这个问题超出了我的回答范围;在过去,您可以使用反射功能,但是我不知道您是否仍然可以使用。

在所有这些恶作剧之后,您似乎不再需要许可,如果您这样做,它将立即返回而没有对话框。

评论


没有签名我伪造这条指令?

– Fortran
1月7日19:06