绕过android usb主机权限确认对话框

我想在工业中使用android

我可以使用slickdevlabs.com库连接到Profilic和Ftdi USB转串口芯片,没有任何问题。

应用程序有一个服务,它在启动时启动,连接到USB串口并执行其他操作。

我的问题是主机设备没有与用户进行任何交互,

所以当android问

Allow the app "MyAPP" to access the USB device ? [checkmark]Use by default for this USB device Cancel OK 

没有人点击确定。

即使我默认检查使用…checkbox,如果我重新插入USB,或重启主机设备,它会在下次启动时再次询问。

我使用SuperUser模式运行服务和应用程序,但没有区别,它再次询问。

我添加了意图过滤但没有区别,它每次都会问我。

        

任何意见如何绕过或禁用它?

我有root和SU访问权限

Solutions Collecting From Web of "绕过android usb主机权限确认对话框"

我知道有点晚了,但还是……

我遇到了同样的问题,我想我已经成功解决了这个问题。 Android内部使用的服务允许管理USB设备和配件。 此服务对第三方开发人员隐藏,未记录。 如果您检查UsbPermissionActivity的源代码,您将能够弄清楚该服务的调用方式。 为了调用服务,使用IUsbManager接口和ServiceManager类。 这些都是隐藏的,所以你不能直接使用它们。 但是你可以做的是创建具有完全相同名称和相应名称空间(包)的存根。 然后,您将能够编译该代码,而运行时环境将使用真实的东西。

唯一的要求您的应用程序必须是系统应用程序 – 它必须位于/ system / app /目录中。 由于您的设备已植根,这应该不是问题。

所以你必须在你的项目中添加一个包:“ android.hardware.usb ”并在其中放入一个名为“ IUsbManager.java ”的文件,其中包含以下内容:

 package android.hardware.usb; public interface IUsbManager extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements android.hardware.usb.IUsbManager { /** Construct the stub at attach it to the interface. */ public Stub() { throw new RuntimeException( "Stub!" ); } /** * Cast an IBinder object into an android.hardware.usb.IUsbManager interface, * generating a proxy if needed. */ public static android.hardware.usb.IUsbManager asInterface( android.os.IBinder obj ) { throw new RuntimeException( "Stub!" ); } public android.os.IBinder asBinder() { throw new RuntimeException( "Stub!" ); } public boolean onTransact( int code, android.os.Parcel data, android.os.Parcel reply, int flags ) throws android.os.RemoteException { throw new RuntimeException( "Stub!" ); } static final int TRANSACTION_getDeviceList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_openDevice = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); static final int TRANSACTION_getCurrentAccessory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); static final int TRANSACTION_openAccessory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); static final int TRANSACTION_setDevicePackage = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4); static final int TRANSACTION_setAccessoryPackage = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5); static final int TRANSACTION_hasDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6); static final int TRANSACTION_hasAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7); static final int TRANSACTION_requestDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8); static final int TRANSACTION_requestAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9); static final int TRANSACTION_grantDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 10); static final int TRANSACTION_grantAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11); static final int TRANSACTION_hasDefaults = (android.os.IBinder.FIRST_CALL_TRANSACTION + 12); static final int TRANSACTION_clearDefaults = (android.os.IBinder.FIRST_CALL_TRANSACTION + 13); static final int TRANSACTION_setCurrentFunction = (android.os.IBinder.FIRST_CALL_TRANSACTION + 14); static final int TRANSACTION_setMassStorageBackingFile = (android.os.IBinder.FIRST_CALL_TRANSACTION + 15); } /* Returns a list of all currently attached USB devices */ public void getDeviceList( android.os.Bundle devices ) throws android.os.RemoteException; /* Returns a file descriptor for communicating with the USB device. * The native fd can be passed to usb_device_new() in libusbhost. */ public android.os.ParcelFileDescriptor openDevice( java.lang.String deviceName ) throws android.os.RemoteException; /* Returns the currently attached USB accessory */ public android.hardware.usb.UsbAccessory getCurrentAccessory() throws android.os.RemoteException; /* Returns a file descriptor for communicating with the USB accessory. * This file descriptor can be used with standard Java file operations. */ public android.os.ParcelFileDescriptor openAccessory( android.hardware.usb.UsbAccessory accessory ) throws android.os.RemoteException; /* Sets the default package for a USB device * (or clears it if the package name is null) */ public void setDevicePackage( android.hardware.usb.UsbDevice device, java.lang.String packageName ) throws android.os.RemoteException; /* Sets the default package for a USB accessory * (or clears it if the package name is null) */ public void setAccessoryPackage( android.hardware.usb.UsbAccessory accessory, java.lang.String packageName ) throws android.os.RemoteException; /* Returns true if the caller has permission to access the device. */ public boolean hasDevicePermission(android.hardware.usb.UsbDevice device) throws android.os.RemoteException; /* Returns true if the caller has permission to access the accessory. */ public boolean hasAccessoryPermission( android.hardware.usb.UsbAccessory accessory ) throws android.os.RemoteException; /* Requests permission for the given package to access the device. * Will display a system dialog to query the user if permission * had not already been given. */ public void requestDevicePermission( android.hardware.usb.UsbDevice device, java.lang.String packageName, android.app.PendingIntent pi ) throws android.os.RemoteException; /* Requests permission for the given package to access the accessory. * Will display a system dialog to query the user if permission * had not already been given. Result is returned via pi. */ public void requestAccessoryPermission( android.hardware.usb.UsbAccessory accessory, java.lang.String packageName, android.app.PendingIntent pi ) throws android.os.RemoteException; /* Grants permission for the given UID to access the device */ public void grantDevicePermission( android.hardware.usb.UsbDevice device, int uid ) throws android.os.RemoteException; /* Grants permission for the given UID to access the accessory */ public void grantAccessoryPermission( android.hardware.usb.UsbAccessory accessory, int uid ) throws android.os.RemoteException; /* Returns true if the USB manager has default preferences or permissions for the package */ public boolean hasDefaults( java.lang.String packageName ) throws android.os.RemoteException; /* Clears default preferences and permissions for the package */ public void clearDefaults( java.lang.String packageName ) throws android.os.RemoteException; /* Sets the current USB function. */ public void setCurrentFunction( java.lang.String function, boolean makeDefault ) throws android.os.RemoteException; /* Sets the file path for USB mass storage backing file. */ public void setMassStorageBackingFile( java.lang.String path ) throws android.os.RemoteException; } 

然后是另一个包:“ android.os ”和“ ServiceManager.java ”:

 package android.os; import java.util.Map; public final class ServiceManager { public static IBinder getService( String name ) { throw new RuntimeException( "Stub!" ); } /** * Place a new @a service called @a name into the service * manager. * * @param name the name of the new service * @param service the service object */ public static void addService( String name, IBinder service ) { throw new RuntimeException( "Stub!" ); } /** * Retrieve an existing service called @a name from the * service manager. Non-blocking. */ public static IBinder checkService( String name ) { throw new RuntimeException( "Stub!" ); } public static String[] listServices() throws RemoteException { throw new RuntimeException( "Stub!" ); } /** * This is only intended to be called when the process is first being brought * up and bound by the activity manager. There is only one thread in the process * at that time, so no locking is done. * * @param cache the cache of service references * @hide */ public static void initServiceCache( Map cache ) { throw new RuntimeException( "Stub!" ); } } 

请注意,这些类的接口可能会根据Android的版本而更改。 在我的情况下,版本是4.0.3 。 因此,如果您有另一个版本的Android并且此代码不起作用,则必须检查特定操作系统版本的源代码。

以下是使用该服务向所有FTDI设备授予权限的示例:

 import java.util.HashMap; import java.util.Iterator; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.hardware.usb.IUsbManager; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.os.IBinder; import android.os.ServiceManager; public class LaunchReceiver extends BroadcastReceiver { public void onReceive( Context context, Intent intent ) { String action = intent.getAction(); if( action != null && action.equals( Intent.ACTION_BOOT_COMPLETED ) ) { try { PackageManager pm = context.getPackageManager(); ApplicationInfo ai = pm.getApplicationInfo( YOUR_APP_PACKAGE_NAMESPACE, 0 ); if( ai != null ) { UsbManager manager = (UsbManager) context.getSystemService( Context.USB_SERVICE ); IBinder b = ServiceManager.getService( Context.USB_SERVICE ); IUsbManager service = IUsbManager.Stub.asInterface( b ); HashMap deviceList = manager.getDeviceList(); Iterator deviceIterator = deviceList.values().iterator(); while( deviceIterator.hasNext() ) { UsbDevice device = deviceIterator.next(); if( device.getVendorId() == 0x0403 ) { service.grantDevicePermission( device, ai.uid ); service.setDevicePackage( device, YOUR_APP_PACKAGE_NAMESPACE ); } } } } catch( Exception e ) { trace( e.toString() ); } } } } 

还有一件事 – 您必须向清单添加以下权限(Lint可能不喜欢它,但您可以随时更改项目属性中的严重性级别):

  

@d_d_t aswer很棒,但它不适用于新的4.2.2。 使用此界面:

 public interface IUsbManager extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements android.hardware.usb.IUsbManager { private static final java.lang.String DESCRIPTOR = "android.hardware.usb.IUsbManager"; /** Construct the stub at attach it to the interface. */ public Stub() { throw new RuntimeException( "Stub!" ); } /** * Cast an IBinder object into an android.hardware.usb.IUsbManager * interface, generating a proxy if needed. */ public static android.hardware.usb.IUsbManager asInterface( android.os.IBinder obj) { throw new RuntimeException( "Stub!" ); } @Override public android.os.IBinder asBinder() { throw new RuntimeException( "Stub!" ); } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { throw new RuntimeException( "Stub!" ); } static final int TRANSACTION_getDeviceList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_openDevice = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); static final int TRANSACTION_getCurrentAccessory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2); static final int TRANSACTION_openAccessory = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3); static final int TRANSACTION_setDevicePackage = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4); static final int TRANSACTION_setAccessoryPackage = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5); static final int TRANSACTION_hasDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6); static final int TRANSACTION_hasAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7); static final int TRANSACTION_requestDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8); static final int TRANSACTION_requestAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9); static final int TRANSACTION_grantDevicePermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 10); static final int TRANSACTION_grantAccessoryPermission = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11); static final int TRANSACTION_hasDefaults = (android.os.IBinder.FIRST_CALL_TRANSACTION + 12); static final int TRANSACTION_clearDefaults = (android.os.IBinder.FIRST_CALL_TRANSACTION + 13); static final int TRANSACTION_setCurrentFunction = (android.os.IBinder.FIRST_CALL_TRANSACTION + 14); static final int TRANSACTION_setMassStorageBackingFile = (android.os.IBinder.FIRST_CALL_TRANSACTION + 15); static final int TRANSACTION_allowUsbDebugging = (android.os.IBinder.FIRST_CALL_TRANSACTION + 16); static final int TRANSACTION_denyUsbDebugging = (android.os.IBinder.FIRST_CALL_TRANSACTION + 17); } /* Returns a list of all currently attached USB devices */ public void getDeviceList(android.os.Bundle devices) throws android.os.RemoteException; /* * Returns a file descriptor for communicating with the USB device. The * native fd can be passed to usb_device_new() in libusbhost. */ public android.os.ParcelFileDescriptor openDevice( java.lang.String deviceName) throws android.os.RemoteException; /* Returns the currently attached USB accessory */ public android.hardware.usb.UsbAccessory getCurrentAccessory() throws android.os.RemoteException; /* * Returns a file descriptor for communicating with the USB accessory. This * file descriptor can be used with standard Java file operations. */ public android.os.ParcelFileDescriptor openAccessory( android.hardware.usb.UsbAccessory accessory) throws android.os.RemoteException; /* * Sets the default package for a USB device (or clears it if the package * name is null) */ public void setDevicePackage(android.hardware.usb.UsbDevice device, java.lang.String packageName, int userId) throws android.os.RemoteException; /* * Sets the default package for a USB accessory (or clears it if the package * name is null) */ public void setAccessoryPackage( android.hardware.usb.UsbAccessory accessory, java.lang.String packageName, int userId) throws android.os.RemoteException; /* Returns true if the caller has permission to access the device. */ public boolean hasDevicePermission(android.hardware.usb.UsbDevice device) throws android.os.RemoteException; /* Returns true if the caller has permission to access the accessory. */ public boolean hasAccessoryPermission( android.hardware.usb.UsbAccessory accessory) throws android.os.RemoteException; /* * Requests permission for the given package to access the device. Will * display a system dialog to query the user if permission had not already * been given. */ public void requestDevicePermission(android.hardware.usb.UsbDevice device, java.lang.String packageName, android.app.PendingIntent pi) throws android.os.RemoteException; /* * Requests permission for the given package to access the accessory. Will * display a system dialog to query the user if permission had not already * been given. Result is returned via pi. */ public void requestAccessoryPermission( android.hardware.usb.UsbAccessory accessory, java.lang.String packageName, android.app.PendingIntent pi) throws android.os.RemoteException; /* Grants permission for the given UID to access the device */ public void grantDevicePermission(android.hardware.usb.UsbDevice device, int uid) throws android.os.RemoteException; /* Grants permission for the given UID to access the accessory */ public void grantAccessoryPermission( android.hardware.usb.UsbAccessory accessory, int uid) throws android.os.RemoteException; /* * Returns true if the USB manager has default preferences or permissions * for the package */ public boolean hasDefaults(java.lang.String packageName, int userId) throws android.os.RemoteException; /* Clears default preferences and permissions for the package */ public void clearDefaults(java.lang.String packageName, int userId) throws android.os.RemoteException; /* Sets the current USB function. */ public void setCurrentFunction(java.lang.String function, boolean makeDefault) throws android.os.RemoteException; /* Sets the file path for USB mass storage backing file. */ public void setMassStorageBackingFile(java.lang.String path) throws android.os.RemoteException; /* * Allow USB debugging from the attached host. If alwaysAllow is true, add * the the public key to list of host keys that the user has approved. */ public void allowUsbDebugging(boolean alwaysAllow, java.lang.String publicKey) throws android.os.RemoteException; /* Deny USB debugging from the attached host */ public void denyUsbDebugging() throws android.os.RemoteException; } 

并修改添加用户ID的代码:

 ... service.setDevicePackage( usbDevice, YOUR_APP_PACKAGE_NAMESPACE, ai.uid ); .... 

如果您可以选择编译Android系统,那么您无法做任何事情。

你可以加

 public void onStart() { super.onStart(); mPermissionGranted = true; finish(); } 

到frameworks / base / packages / SystemUI / src / com / android / systemui / usb / UsbPermissionActivity.java

绕过权限确认popup窗口。

我在popup窗口中遇到了同样的问题,没有人点击它。 但我发现了一种不同的解决方案(对于有根设备)。 popup窗口由android在类UsbPermissionActivity中生成(并且UsbPermissionActivity由UsbSettingsManager启动)。 查看Android源代码,了解最新情况。 这里的好处是,我们可以操作UsbPermissionActivity的字节码来接受所有的UsbDevices。 你需要工具Smali / Baksmali这样做。 https://code.google.com/p/smali/

  1. 在您的设备上find文件SystemUI.apk
  2. 使用adb pull path/to/SystemUI.apk将其复制到您的计算机
  3. 解压缩apk
  4. 使用java -jar baksmali.jar classes.dex反汇编classes.dex文件
  5. find文件UsbPermissionActivity,在其中find所说的行

    invoke-virtual {p0}, Lcom/android/systemui/usb/UsbPermissionActivity;->setupAlert()V

  6. 通过注释并添加两个新行来改变它

#invoke-virtual {p0}, Lcom/android/systemui/usb/UsbPermissionActivity;->setupAlert()V const/4 v0, 0x1 iput-boolean v0, p0, Lcom/android/systemui/usb/UsbPermissionActivity;->mPermissionGranted:Z invoke-virtual {p0}, Lcom/android/systemui/usb/UsbPermissionActivity;->finish()V

  1. java -jar smali.jar -o classes.dex out组装它
  2. 替换原来的classes.dex并将所有内容再次压缩到SystemUI.apk
  3. 使用adb push services.jar path/to/SystemUI.apk替换设备上的原始SystemUI.apk,或者如果这不适用于filemanager ap

Android实际上并不是为了支持开箱即用的这种用法而设计的。 就个人而言,对于非交互式使用,我很想考虑在linux内核中使用USB串行驱动程序并跳过android USB apis。 但你必须能够认真修改android安装 – 更改内核配置和/或加载模块,创建设备文件并设置其权限或所有者,可能添加unix组和Android权限允许的应用程序访问它。

或者你可以浏览android源码并禁用用户确认; 但如果你没有设备的源代码android构建,这可能比linux级别的想法更棘手,因为适应开源的android在供应商设备上运行可能是非常重要的(除非有人已经提供了一个来自 – 对于有问题的设备而言function足够的源代码构建)

实际上,root / su访问不适用于应用程序本身 – 它只意味着知道如何运行你的root hack留下的任何工具的应用程序可以启动一个以root身份运行的帮助程序,但是应用程序本身不会和不能。 使用root在系统分区上安装应用程序可能会获得一些非典型的android权限,但你必须检查是否有任何可以帮助你使用usb。

根据Android开发者的文档,当您的应用程序通过您的清单意图filter启动时,您已经拥有连接的USB设备的权限。 也许你应该尝试这种方法并编写一个filter来精确匹配你想要使用的设备,以防止其他应用程序也想与设备通信。

请参阅http://developer.android.com/guide/topics/connectivity/usb/host.html#permission-d上的“注意”

实现此目的的一种方法,请注意,这实际上并没有消除确认,将确定checkbox的位置,并使用Android类似于Robot类来选择它,然后选择OK 。 您可以编写一个在后台运行的应用程序,它甚至可以由您提到的启动服务调用,特别是为此目的。

我认为提前白色列出您正在使用的配件将是最佳解决方案。 为此,您需要在此位置/ data / system / users / 0添加文件usb_device_manager.xml
//请注意,0是用户ID,如果您未在Android中添加更多用户,则可能为0,但如果您确实更改了此ID

这是文件的外观:

     

对于像这样的董事会http://www.embeddedartists.com/products/app/aoa_kit.php它是:

  < ?xml version='1.0' encoding='utf-8' standalone='yes' ?>     

我想我们可以通过在/etc/udev做一些修改来做到这一点。 我们可以将供应商ID和设备ID添加到51-android.rules文件中。

第一次,当需要确认时,您可以选择“始终”,然后即使Android设备断电并启动,您的应用仍然有权访问USB2Serial。 只是说,只有一次确认!

我有同样的问题,每次插上USB线时都会出现权限popup窗口,为了解决这个问题,我只是在清单中添加了filter,并为VID和PID添加了xml文件,只需确保按照建议设置USB设备过滤上面的SO链接或这里记录的,你把好的VID和PID。 这是我的问题,我没有把VID和PID与我的设备匹配

如果你只想复制/写入usb棒,你可以使用

使用linx命令执行以下方法doCommand(“mkdir / mnt / usbhost1 / dirname”)

 private boolean doCommand(String[] commands) { boolean ran = false; try { Process process = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(process.getOutputStream()); for (String single : commands) { os.writeBytes(single + "\n"); os.flush(); } os.writeBytes("exit\n"); os.flush(); process.waitFor(); ran = true; } catch(Exception ex) { } return ran; } 

我在我的清单中有以下权限,抱歉不记得哪些是必须的。

     

如果您想要做任何其他事情,这对您来说可能不是很有用