我想在行业中使用android,
我可以使用slickdevlabs.com库连接到Profilic和Ftdi USB转串口芯片,没有任何问题。
应用程序有一个服务,它在启动时启动,连接到USB串口并执行其他操作。
我的问题是主机设备没有与用户进行任何交互,
所以当android问到
允许应用" MyAPP"访问USB设备? [选中标记]默认使用此USB设备 取消确定 没有人可以点击确定。
即使我默认选中使用...复选框,如果我重新插入USB,或重新启动主机设备,它会在下次启动时再次询问。
并在此链接中提及答案: bypass android usb host permission confirmation dialog 但代码适用于: "请注意,这些类的接口可能会根据Android的版本而改变。在我的情况下,版本是4.0.3。因此,如果您有另一个版本的Android并且此代码无法运行,则必须检查特定操作系统版本的源代码。"
所以我需要为Android 5.1提供相同的代码
答案 0 :(得分:2)
您是否尝试过使用Manifest中的intent-filter,如下所述:https://developer.android.com/guide/topics/connectivity/usb/host.html#using-intents
我遇到了类似的问题 - 似乎如果您以编程方式请求USB权限,它会忽略勾选的复选框并再次询问您。
修改强> 如果由于服务而遇到问题,您可能也想阅读此内容:https://stackoverflow.com/a/15151075/3540885
答案 1 :(得分:1)
自从您问这个问题已经有一段时间了...但是如果可以帮助某人,这是我的答案。
最初问题中接受的答案指出:
因此,如果您使用的是其他版本的Android,并且此代码不起作用,则必须检查特定版本OS的源代码。
因此,您应该直接从android源代码获取所需的文件。您可以download相对于您的版本的源代码,也可以直接浏览from the repo。
您要搜索的IUsbManager界面通常位于以下位置: / frameworks / base / android-branch-name / core / java / android / hardware / usb。至于服务管理器,可以在以下位置找到: / frameworks / base / android-branch-name / core / java / android / os /
我没有发布代码,因为我想您已经2年以上不再搜索它了:)
===编辑===
根据要求,这里是代码。我使它适用于6.0.0版,但我认为函数调用与5.1相同。待验证。
在android.harware.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, 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 ) 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中创建Java类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!" );
}
}
一旦完成,别忘了在AndroidManifest中添加android.permission.MANAGE_USB。
然后您可以使用这些函数调用:
/**
* Verify if the application is a system app and has MANAGE_USB permission
* before granting the USB permission for you specific USB devices
*/
private void manageUSBPermissions() {
if ((this.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
Log.i(TAG,"This is a system application");
if (getApplicationContext().checkCallingOrSelfPermission("android.permission.MANAGE_USB") == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG,"I have android.permission.MANAGE_USB");
grantUsbPermissions();
} else {
Log.i(TAG,"I do not have android.permission.MANAGE_USB");
}
} else {
Log.i(TAG,"This is not a system application");
}
}
/**
* This is to avoid the android usb host permission confirmation dialog
* The application need to be a system app and have MANAGE_USB permission for it to work
*/
private void grantUsbPermissions() {
try {
PackageManager pm = getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo( "com.your.package", 0 );
if( ai != null ) {
UsbManager manager = (UsbManager) getSystemService( Context.USB_SERVICE );
IBinder b = ServiceManager.getService( Context.USB_SERVICE );
IUsbManager service = IUsbManager.Stub.asInterface( b );
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while( deviceIterator.hasNext() ) {
UsbDevice device = deviceIterator.next();
if ( device.getVendorId() == 0x1234 ) {
service.grantDevicePermission( device, ai.uid );
service.setDevicePackage( device, "com.your.package", ai.uid );
}
}
}
}
catch ( Exception e ) {
Log.e(TAG, "Error granting USB permissions: " + e);
}
}
正在检查您的应用程序是否是系统应用程序,以及是否具有正确的权限,否则它将无法正常工作。
另外请注意,您的供应商ID不是十六进制而是十进制。