android app在系统重启绕过USB授权对话框,自动获取USB权限
最近由于项目需要参考了很多关于不修改android源码情况下实现屏蔽USB授权对话框的博文,结合自身实践阐述给出细节的实现过程。
当前实现的策略是开发一个android内部服务,用于响应需要使用USB授权的app的申请,app需要在使用USB之前主动申请我们自行开发的授权,走在默认授权对话框触发之前提出申请。
一、创建一个android内部服务apk
1)具体使用的AndroidManifest.xm
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.harvbot.usbpermissionissuer"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <receiver android:name=".LaunchReceiver"> <intent-filter> <action android:name="ACTION_USB_PERMISSION_ISSUER" /> </intent-filter> </receiver> <service android:enabled="true" android:name=".StubService" /> </application> <uses-permission android:name="android.permission.MANAGE_USB" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> </manifest>
2)建立android.hardware.usb.IUsbManager.java替换系统源码
/* * This file is auto-generated. DO NOT MODIFY. * Original file: frameworks/base/core/java/android/hardware/usb/IUsbManager.aidl */ package android.hardware.usb; /** @hide */ 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() { this.attachInterface(this, DESCRIPTOR); } /** * 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) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof android.hardware.usb.IUsbManager))) { return ((android.hardware.usb.IUsbManager)iin); } return new android.hardware.usb.IUsbManager.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getDeviceList: { data.enforceInterface(DESCRIPTOR); android.os.Bundle _arg0; _arg0 = new android.os.Bundle(); this.getDeviceList(_arg0); reply.writeNoException(); if ((_arg0!=null)) { reply.writeInt(1); _arg0.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { reply.writeInt(0); } return true; } case TRANSACTION_openDevice: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); android.os.ParcelFileDescriptor _result = this.openDevice(_arg0); reply.writeNoException(); if ((_result!=null)) { reply.writeInt(1); _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { reply.writeInt(0); } return true; } case TRANSACTION_getCurrentAccessory: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbAccessory _result = this.getCurrentAccessory(); reply.writeNoException(); if ((_result!=null)) { reply.writeInt(1); _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { reply.writeInt(0); } return true; } case TRANSACTION_openAccessory: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbAccessory _arg0; if ((0!=data.readInt())) { _arg0 = android.hardware.usb.UsbAccessory.CREATOR.createFromParcel(data); } else { _arg0 = null; } android.os.ParcelFileDescriptor _result = this.openAccessory(_arg0); reply.writeNoException(); if ((_result!=null)) { reply.writeInt(1); _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { reply.writeInt(0); } return true; } case TRANSACTION_setDevicePackage: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbDevice _arg0; if ((0!=data.readInt())) { _arg0 = android.hardware.usb.UsbDevice.CREATOR.createFromParcel(data); } else { _arg0 = null; } java.lang.String _arg1; _arg1 = data.readString(); int _arg2; _arg2 = data.readInt(); this.setDevicePackage(_arg0, _arg1, _arg2); reply.writeNoException(); return true; } case TRANSACTION_setAccessoryPackage: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbAccessory _arg0; if ((0!=data.readInt())) { _arg0 = android.hardware.usb.UsbAccessory.CREATOR.createFromParcel(data); } else { _arg0 = null; } java.lang.String _arg1; _arg1 = data.readString(); int _arg2; _arg2 = data.readInt(); this.setAccessoryPackage(_arg0, _arg1, _arg2); reply.writeNoException(); return true; } case TRANSACTION_hasDevicePermission: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbDevice _arg0; if ((0!=data.readInt())) { _arg0 = android.hardware.usb.UsbDevice.CREATOR.createFromParcel(data); } else { _arg0 = null; } boolean _result = this.hasDevicePermission(_arg0); reply.writeNoException(); reply.writeInt(((_result)?(1):(0))); return true; } case TRANSACTION_hasAccessoryPermission: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbAccessory _arg0; if ((0!=data.readInt())) { _arg0 = android.hardware.usb.UsbAccessory.CREATOR.createFromParcel(data); } else { _arg0 = null; } boolean _result = this.hasAccessoryPermission(_arg0); reply.writeNoException(); reply.writeInt(((_result)?(1):(0))); return true; } case TRANSACTION_requestDevicePermission: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbDevice _arg0; if ((0!=data.readInt())) { _arg0 = android.hardware.usb.UsbDevice.CREATOR.createFromParcel(data); } else { _arg0 = null; } java.lang.String _arg1; _arg1 = data.readString(); android.app.PendingIntent _arg2; if ((0!=data.readInt())) { _arg2 = android.app.PendingIntent.CREATOR.createFromParcel(data); } else { _arg2 = null; } this.requestDevicePermission(_arg0, _arg1, _arg2); reply.writeNoException(); return true; } case TRANSACTION_requestAccessoryPermission: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbAccessory _arg0; if ((0!=data.readInt())) { _arg0 = android.hardware.usb.UsbAccessory.CREATOR.createFromParcel(data); } else { _arg0 = null; } java.lang.String _arg1; _arg1 = data.readString(); android.app.PendingIntent _arg2; if ((0!=data.readInt())) { _arg2 = android.app.PendingIntent.CREATOR.createFromParcel(data); } else { _arg2 = null; } this.requestAccessoryPermission(_arg0, _arg1, _arg2); reply.writeNoException(); return true; } case TRANSACTION_grantDevicePermission: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbDevice _arg0; if ((0!=data.readInt())) { _arg0 = android.hardware.usb.UsbDevice.CREATOR.createFromParcel(data); } else { _arg0 = null; } int _arg1; _arg1 = data.readInt(); this.grantDevicePermission(_arg0, _arg1); reply.writeNoException(); return true; } case TRANSACTION_grantAccessoryPermission: { data.enforceInterface(DESCRIPTOR); android.hardware.usb.UsbAccessory _arg0; if ((0!=data.readInt())) { _arg0 = android.hardware.usb.UsbAccessory.CREATOR.createFromParcel(data); } else { _arg0 = null; } int _arg1; _arg1 = data.readInt(); this.grantAccessoryPermission(_arg0, _arg1); reply.writeNoException(); return true; } case TRANSACTION_hasDefaults: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); int _arg1; _arg1 = data.readInt(); boolean _result = this.hasDefaults(_arg0, _arg1); reply.writeNoException(); reply.writeInt(((_result)?(1):(0))); return true; } case TRANSACTION_clearDefaults: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); int _arg1; _arg1 = data.readInt(); this.clearDefaults(_arg0, _arg1); reply.writeNoException(); return true; } case TRANSACTION_setCurrentFunction: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); boolean _arg1; _arg1 = (0!=data.readInt()); this.setCurrentFunction(_arg0, _arg1); reply.writeNoException(); return true; } case TRANSACTION_setMassStorageBackingFile: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); this.setMassStorageBackingFile(_arg0); reply.writeNoException(); return true; } case TRANSACTION_allowUsbDebugging: { data.enforceInterface(DESCRIPTOR); boolean _arg0; _arg0 = (0!=data.readInt()); java.lang.String _arg1; _arg1 = data.readString(); this.allowUsbDebugging(_arg0, _arg1); reply.writeNoException(); return true; } case TRANSACTION_denyUsbDebugging: { data.enforceInterface(DESCRIPTOR); this.denyUsbDebugging(); reply.writeNoException(); return true; } case TRANSACTION_clearUsbDebuggingKeys: { data.enforceInterface(DESCRIPTOR); this.clearUsbDebuggingKeys(); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements android.hardware.usb.IUsbManager { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } /* Returns a list of all currently attached USB devices */ @Override public void getDeviceList(android.os.Bundle devices) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getDeviceList, _data, _reply, 0); _reply.readException(); if ((0!=_reply.readInt())) { devices.readFromParcel(_reply); } } finally { _reply.recycle(); _data.recycle(); } } /* Returns a file descriptor for communicating with the USB device. * The native fd can be passed to usb_device_new() in libusbhost. */ @Override public android.os.ParcelFileDescriptor openDevice(java.lang.String deviceName) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); android.os.ParcelFileDescriptor _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(deviceName); mRemote.transact(Stub.TRANSACTION_openDevice, _data, _reply, 0); _reply.readException(); if ((0!=_reply.readInt())) { _result = android.os.ParcelFileDescriptor.CREATOR.createFromParcel(_reply); } else { _result = null; } } finally { _reply.recycle(); _data.recycle(); } return _result; } /* Returns the currently attached USB accessory */ @Override public android.hardware.usb.UsbAccessory getCurrentAccessory() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); android.hardware.usb.UsbAccessory _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getCurrentAccessory, _data, _reply, 0); _reply.readException(); if ((0!=_reply.readInt())) { _result = android.hardware.usb.UsbAccessory.CREATOR.createFromParcel(_reply); } else { _result = null; } } finally { _reply.recycle(); _data.recycle(); } return _result; } /* Returns a file descriptor for communicating with the USB accessory. * This file descriptor can be used with standard Java file operations. */ @Override public android.os.ParcelFileDescriptor openAccessory(android.hardware.usb.UsbAccessory accessory) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); android.os.ParcelFileDescriptor _result; try { _data.writeInterfaceToken(DESCRIPTOR); if ((accessory!=null)) { _data.writeInt(1); accessory.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_openAccessory, _data, _reply, 0); _reply.readException(); if ((0!=_reply.readInt())) { _result = android.os.ParcelFileDescriptor.CREATOR.createFromParcel(_reply); } else { _result = null; } } finally { _reply.recycle(); _data.recycle(); } return _result; } /* Sets the default package for a USB device * (or clears it if the package name is null) */ @Override public void setDevicePackage(android.hardware.usb.UsbDevice device, java.lang.String packageName, int userId) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((device!=null)) { _data.writeInt(1); device.writeToParcel(_data, 0); } else { _data.writeInt(0); } _data.writeString(packageName); _data.writeInt(userId); mRemote.transact(Stub.TRANSACTION_setDevicePackage, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* Sets the default package for a USB accessory * (or clears it if the package name is null) */ @Override public void setAccessoryPackage(android.hardware.usb.UsbAccessory accessory, java.lang.String packageName, int userId) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((accessory!=null)) { _data.writeInt(1); accessory.writeToParcel(_data, 0); } else { _data.writeInt(0); } _data.writeString(packageName); _data.writeInt(userId); mRemote.transact(Stub.TRANSACTION_setAccessoryPackage, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* Returns true if the caller has permission to access the device. */ @Override public boolean hasDevicePermission(android.hardware.usb.UsbDevice device) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); boolean _result; try { _data.writeInterfaceToken(DESCRIPTOR); if ((device!=null)) { _data.writeInt(1); device.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_hasDevicePermission, _data, _reply, 0); _reply.readException(); _result = (0!=_reply.readInt()); } finally { _reply.recycle(); _data.recycle(); } return _result; } /* Returns true if the caller has permission to access the accessory. */ @Override public boolean hasAccessoryPermission(android.hardware.usb.UsbAccessory accessory) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); boolean _result; try { _data.writeInterfaceToken(DESCRIPTOR); if ((accessory!=null)) { _data.writeInt(1); accessory.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_hasAccessoryPermission, _data, _reply, 0); _reply.readException(); _result = (0!=_reply.readInt()); } finally { _reply.recycle(); _data.recycle(); } return _result; } /* 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. */ @Override public void requestDevicePermission(android.hardware.usb.UsbDevice device, java.lang.String packageName, android.app.PendingIntent pi) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((device!=null)) { _data.writeInt(1); device.writeToParcel(_data, 0); } else { _data.writeInt(0); } _data.writeString(packageName); if ((pi!=null)) { _data.writeInt(1); pi.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_requestDevicePermission, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* 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. */ @Override public void requestAccessoryPermission(android.hardware.usb.UsbAccessory accessory, java.lang.String packageName, android.app.PendingIntent pi) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((accessory!=null)) { _data.writeInt(1); accessory.writeToParcel(_data, 0); } else { _data.writeInt(0); } _data.writeString(packageName); if ((pi!=null)) { _data.writeInt(1); pi.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_requestAccessoryPermission, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* Grants permission for the given UID to access the device */ @Override public void grantDevicePermission(android.hardware.usb.UsbDevice device, int uid) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((device!=null)) { _data.writeInt(1); device.writeToParcel(_data, 0); } else { _data.writeInt(0); } _data.writeInt(uid); mRemote.transact(Stub.TRANSACTION_grantDevicePermission, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* Grants permission for the given UID to access the accessory */ @Override public void grantAccessoryPermission(android.hardware.usb.UsbAccessory accessory, int uid) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((accessory!=null)) { _data.writeInt(1); accessory.writeToParcel(_data, 0); } else { _data.writeInt(0); } _data.writeInt(uid); mRemote.transact(Stub.TRANSACTION_grantAccessoryPermission, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* Returns true if the USB manager has default preferences or permissions for the package */ @Override public boolean hasDefaults(java.lang.String packageName, int userId) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); boolean _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(packageName); _data.writeInt(userId); mRemote.transact(Stub.TRANSACTION_hasDefaults, _data, _reply, 0); _reply.readException(); _result = (0!=_reply.readInt()); } finally { _reply.recycle(); _data.recycle(); } return _result; } /* Clears default preferences and permissions for the package */ @Override public void clearDefaults(java.lang.String packageName, int userId) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(packageName); _data.writeInt(userId); mRemote.transact(Stub.TRANSACTION_clearDefaults, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* Sets the current USB function. */ @Override public void setCurrentFunction(java.lang.String function, boolean makeDefault) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(function); _data.writeInt(((makeDefault)?(1):(0))); mRemote.transact(Stub.TRANSACTION_setCurrentFunction, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* Sets the file path for USB mass storage backing file. */ @Override public void setMassStorageBackingFile(java.lang.String path) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(path); mRemote.transact(Stub.TRANSACTION_setMassStorageBackingFile, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* 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. */ @Override public void allowUsbDebugging(boolean alwaysAllow, java.lang.String publicKey) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(((alwaysAllow)?(1):(0))); _data.writeString(publicKey); mRemote.transact(Stub.TRANSACTION_allowUsbDebugging, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* Deny USB debugging from the attached host */ @Override public void denyUsbDebugging() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_denyUsbDebugging, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /* Clear public keys installed for secure USB debugging */ @Override public void clearUsbDebuggingKeys() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_clearUsbDebuggingKeys, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } 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); static final int TRANSACTION_clearUsbDebuggingKeys = (android.os.IBinder.FIRST_CALL_TRANSACTION + 18); } /* 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; /* Clear public keys installed for secure USB debugging */ public void clearUsbDebuggingKeys() throws android.os.RemoteException; }
3)建立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<String, IBinder> cache ) { throw new RuntimeException( "Stub!" ); } }
4)建立响应app申请的BroadcastReceiver类,com.harvbot.usbpermissionissuer.LaunchReceiver.java
package com.harvbot.usbpermissionissuer; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.XmlResourceParser; import android.hardware.usb.IUsbManager; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.os.IBinder; import android.os.ServiceManager; import android.text.TextUtils; import android.util.Log; import org.json.JSONObject; import org.xmlpull.v1.XmlPullParserException; import com.harvbot.usbpermissionissuer.logging.LogManager; public class LaunchReceiver extends BroadcastReceiver { private final String TAG = "com.harvbot.usb"; private final String ACTION_USB_PERMISSION_ISSUER = "ACTION_USB_PERMISSION_ISSUER"; private LogManager logger; public void onReceive( Context context, Intent intent ) { logger = new LogManager(context); String action = intent.getAction(); if( action != null && action.equals( ACTION_USB_PERMISSION_ISSUER ) ) { logger.log("Receiver event processing."); try { UsbDeviceDescriptor deviceFilter = new UsbDeviceDescriptor(); deviceFilter.packageName = intent.getStringExtra("packageName"); deviceFilter.vendorId = intent.getIntExtra("vendorId", -1); deviceFilter.productId = intent.getIntExtra("productId", -1); deviceFilter.deviceClass = intent.getIntExtra("deviceClass", -1); deviceFilter.deviceSubclass = intent.getIntExtra("deviceSubclass", -1); if(TextUtils.isEmpty(deviceFilter.packageName)){ logger.log("PackageName is Null"); return; } PackageManager pm = context.getPackageManager(); ApplicationInfo ai = pm.getApplicationInfo(deviceFilter.packageName, 0); UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE); IBinder b = ServiceManager.getService(Context.USB_SERVICE); IUsbManager service = IUsbManager.Stub.asInterface(b); HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); logger.log("List of usb devices was loaded. Number of attached devices: " + new Integer(deviceList.size()).toString()); if((deviceFilter.deviceClass != -1 && deviceFilter.deviceSubclass != -1) || (deviceFilter.productId != -1 && deviceFilter.vendorId != -1)) { logger.log("The usb permission will be granted for application " + ai.packageName); Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); while (deviceIterator.hasNext()) { UsbDevice device = deviceIterator.next(); if ((device.getDeviceClass() == deviceFilter.deviceClass && device.getDeviceSubclass() == deviceFilter.deviceSubclass) || (device.getVendorId() == deviceFilter.vendorId && device.getProductId() == deviceFilter.productId)) { try { service.grantDevicePermission(device, ai.uid); service.setDevicePackage(device, ai.packageName, ai.uid); logger.log("Usb permission is granted for application " + ai.packageName + " for device " + device.toString() + " and user " + ai.uid + " is granted"); } catch (SecurityException se) { logger.log(se.toString()); Log.e(TAG, se.toString()); } } } } else { logger.log("Device params is Error "+deviceFilter.toString()); } } catch(Exception e) { logger.log(e.toString()); Log.e(TAG, e.toString()); } } } }
额外需要的UsbDeviceDescriptor.java和StubService.java一并给出,日志实现自行替换
package com.harvbot.usbpermissionissuer; //二选一,确定USB设备 public class UsbDeviceDescriptor { public String packageName; //第一组,确定USB设备 public int deviceClass; public int deviceSubclass; //第二级,确定USB设备 public int vendorId; public int productId; @Override public String toString() { return "packageName:" + packageName + ", deviceClass:" + deviceClass + ", deviceSubclass: " + deviceSubclass + ", vendorId: " + vendorId + ", productId: " + productId; } }
package com.harvbot.usbpermissionissuer; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; import android.widget.Toast; public class StubService extends Service { private static final String TAG = "StubService"; @Override public IBinder onBind(Intent intent) { return null; } public void onDestroy() { Log.d(TAG, "onDestroy"); } @Override public void onStart(Intent intent, int startid) { Log.d(TAG, "onStart"); } }
5)以上关键文件工程化后生成usb-permission-issuer.apk,需要将其拷贝到android系统下的/system/prv-app目录下(该目录是系统预装apk路径),并修改其文件权限,例如777
备注:我的做法是直接下载了“kingroot”和“RE文件管理”,安装后,使用“kingroot”给“RE文件管理”开启root权限,然后通过“RE文件管理”将“usb-permission-issuer.apk”拷贝到/system/prv-app目录下,并修改其文件权限(选择文件长按,RE文件管理会出现更多功能菜单,里面有权限修改)
6)在需要的app进行动态广播申请,实例如下:
private void UsbInit() { UsbInitPermission(1); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } UsbInitPermission(2); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } UsbInitPermission(3); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } UsbInitPermission(4); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } static final String YOUR_APP_PACKAGE_NAMESPACE = "你的app-package"; static final String ACTION_USB_PERMISSION_APP = "ACTION_USB_PERMISSION_ISSUER"; private void UsbInitPermission(int id) { Intent intent_usb = new Intent(); intent_usb.setAction(ACTION_USB_PERMISSION_APP); intent_usb.putExtra("packageName", YOUR_APP_PACKAGE_NAMESPACE); //device_filter.xml里的字段 intent_usb.putExtra("vendorId", 1659); switch(id) { case 1: intent_usb.putExtra("productId", 8963); break; case 2: intent_usb.putExtra("productId", 9553); break; case 3: intent_usb.putExtra("productId", 8964); break; case 4: intent_usb.putExtra("productId", 9475); break; } //发送广播 sendBroadcast(intent_usb); }
然后再合适的地方调用UsbInit(),等待一段时间后会获得授权,再使用你的USB,这样就不会再有USB授权对话框弹出
7)如果懒得编译授权的apk,可以直接采用https://download.csdn.net/download/py8105/10313534,再完成5、6步骤。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
慧荣科技宣布推出全球首款支持最新SD 6. 0规范的SD控制器解决方案
在设计和推广固态存储设备专用NAND闪存控制器方面处于全球领导地位的慧荣科技公司(Silicon Motion Technology Corporation, 纳斯达克交易代码: SIMO)日前宣布推出全新的SD 6.0控制器解决方案,该控制器支持SD规范6.0,并满足新的A2应用性能评级,其最小随机读/写性能高达4,000/2,000 IOPS。可扩展存储卡配置了慧荣SD 6.0新控制器后,用户将极大的提高性能,能够直接从SD卡运行Android 6.x/7.x应用程序,并支持4k视频录制和播放以及AR/VR等需要高带宽的应用。 慧荣科技的SD 6.0控制器解决方案支持低电压信号,可满足低功耗SoC和功能命令队列、高速缓存功能和自我维护功能等需求——类似于管理大量数据的SSD和嵌入式存储器所使用的所有关键功能,从而支持使用高性能、高可靠性和长寿命可扩展存储卡。此外,SD 6.0控制器解决方案最高可支持2TB的容量,并提供商用和工业温度等级器件,消费类、商业、工业和汽车设备均可以使用SD 6.0卡实现高性能和高可靠存储。 慧荣科技产品企划部资深副总段喜亭表示:“可扩展存储在移动通信和工...
- 下一篇
解决移动端两端布局的input+fixed的bug
在移动端布局中,会经常出现固定在手机上下两端的页面。 但是fixed定位和软键盘碰上之后,会碰到各种的坑,ios和android上都会遇到。 下面就分享一下如何解决此问题,代码实例如下: 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <!DOCTYPE html> < html lang = "en" > < head > < meta charset = "UTF-8" > < meta name = "viewport" content = "width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" > < title >蚂蚁部落</ title > </ head > < body > < div class = "main" > < p >...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8安装Docker,最新的服务器搭配容器使用
- 设置Eclipse缩进为4个空格,增强代码规范
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7,8上快速安装Gitea,搭建Git服务器