我想在行业中使用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
没有人点击确定。
即使我默认选中使用...复选框,如果我重新插入USB,或重新启动主机设备,它会在下次启动时再次询问。
我使用SuperUser模式运行服务和应用程序,但没有区别,它再次询问。
我添加了意图过滤但没有区别,每次都会问我。
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"
android:resource="@xml/device_filter" />
有关如何绕过或禁用它的任何意见?
我有root和SU访问。
答案 0 :(得分:25)
我知道有点晚了,但还是......
我遇到了同样的问题,我想我已经成功解决了这个问题。 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<String, IBinder> 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<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> 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可能不喜欢它,但您可以随时更改项目属性中的严重性级别):
<uses-permission android:name="android.permission.MANAGE_USB" />
答案 1 :(得分:10)
@d_d_t答案很棒,但它不适用于新的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 );
....
答案 2 :(得分:6)
我在弹出窗口中遇到了同样的问题,没有人点击它。 但我发现了一种不同的解决方案(对于有根设备)。 弹出窗口由android在类 UsbPermissionActivity 中生成(并且UsbPermissionActivity由UsbSettingsManager启动)。查看Android源代码,了解最新情况。 这里的好处是,我们可以操作UsbPermissionActivity的字节码来接受所有的UsbDevices。您需要使用 Smali / Baksmali 工具才能执行此操作。 https://code.google.com/p/smali/
adb pull path/to/SystemUI.apk
java -jar baksmali.jar classes.dex
找到文件UsbPermissionActivity,在其中找到
所在的行 invoke-virtual {p0}, Lcom/android/systemui/usb/UsbPermissionActivity;->setupAlert()V
通过注释并添加两个新行
#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
java -jar smali.jar -o classes.dex out
adb push services.jar path/to/SystemUI.apk
替换设备上的原始SystemUI.apk,或者如果不能使用filemanager ap 答案 3 :(得分:5)
如果您可以选择编译Android系统,那么您无法做任何事情。
您可以添加
public void onStart() {
super.onStart();
mPermissionGranted = true;
finish();
}
到frameworks / base / packages / SystemUI / src / com / android / systemui / usb / UsbPermissionActivity.java
绕过权限确认弹出窗口。
答案 4 :(得分:4)
Android实际上并非旨在支持这种开箱即用的用法。就个人而言,对于非交互式使用,我很想考虑在linux内核中使用USB串行驱动程序并跳过android USB apis。但你必须能够认真修改android安装 - 更改内核配置和/或加载模块,创建设备文件并设置他们的权限或所有者,可能添加unix组和Android允许的应用程序权限访问它。
或者您可以查看android源并禁用用户确认;但如果你没有设备的源代码android构建,这可能比linux级别的想法更棘手,因为适应开源android在供应商设备上运行可能是非常重要的(除非某人已经提供了一个来自 - 对于有问题的设备来说功能足够的源代码构建)
指出,root / su访问本身并不适用于应用程序 - 它只意味着知道如何运行你的root hack留下的任何工具的应用程序可以启动一个以root身份运行的帮助程序,但应用程序本身没有也不可以。使用root在系统分区上安装应用程序可能会获得一些非典型的android权限,但你必须检查是否有任何可以帮助你使用usb。
答案 5 :(得分:3)
我认为提前白色列出您正在使用的配件将是最佳解决方案。
为此,您需要添加该文件
usb_device_manager.xml
在这个位置
/数据/系统/用户/ 0
//请注意,0是用户ID,如果您未在Android中添加更多用户,但如果您确实更改了此ID,则可能为0
这是文件的外观:
<settings>
<preference package="<PACKAGE NAME OF APP YOU WANT TO START ON CONNECTIONCTION>">
<usb-accessory manufacturer="<NAME OF MANUFECTURER LIKE ONE REGISTERED IN meta-data in the manifest>" model="<MODEL NAME LIKE ONE REGISTERED IN meta-data in the manifest>" version="<VERSION LIKE ONE REGISTERED IN meta-data in the manifest>" />
</preference>
对于像http://www.embeddedartists.com/products/app/aoa_kit.php这样的董事会,它是:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<settings>
<preference package="com.embeddedartists.aoa">
<usb-accessory manufacturer="Embedded Artists AB" model="AOA Board - Basic" version="1.0" />
</preference>
答案 6 :(得分:3)
解决方案是使用意图过滤器并将android:directBootAware="true"
属性添加到关联的活动中,以便在引导/重新引导后正确接收USB_DEVICE_ATTACHED
事件。重要的是,不要仅在使用意图过滤器的情况下在代码中请求USB
设备的许可,
<manifest>
<uses-feature android:name="android.hardware.usb.host" />
<activity
...
android:directBootAware="true">
<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/device_filter" />
</activity>
</manifest>
使用与此类似的 device_filter XML
资源文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1234" product-id="5678" />
</resources>
答案 7 :(得分:2)
实现此目的的一种方法,请注意,这实际上并没有消除确认,而是确定checkbox
的位置并使用与 Robot <的Android等价物/ strong>类选择它,然后选择OK
。您可以编写一个在后台运行的应用程序,它甚至可以由您提到的启动服务调用,特别是为此目的。
答案 8 :(得分:2)
根据Android开发者的文档,当您的应用通过您的清单意图过滤器启动时,您已经拥有连接的USB设备的权限。也许您应该尝试这种方法并编写一个过滤器以与您要使用的设备完全匹配,以防止其他应用也希望与设备通信。
请参阅http://developer.android.com/guide/topics/connectivity/usb/host.html#permission-d
上的“注释”答案 9 :(得分:0)
我认为我们可以通过/etc/udev
进行一些修改来实现这一目标。我们可以将供应商ID和设备ID添加到51-android.rules
文件中。
答案 10 :(得分:0)
第一次,当需要确认时,您可以选择“始终”,然后即使Android设备断电并启动,您的应用仍然有权访问USB2Serial。只是说,只有一次确认!
答案 11 :(得分:0)
我遇到了同样的问题,每次插上USB线时都会出现权限弹出窗口,为了解决这个问题,我只是在清单中添加了过滤器,并为VID和PID添加了xml文件,只需确保设置了USB设备过滤正如上面的SO链接或此处记录的那样,您可以使用良好的VID和PID。这是我的问题,我没有把与我的设备相匹配的VID和PID
答案 12 :(得分:0)
如果您有权访问Android源代码,则这是您需要禁用权限对话框的代码
以上代码更新创建了一个配置选项,您可以使用该配置选项,也可以使用mDisablePermissionDialogs
的true值对其进行硬编码以禁用权限对话框。
在services/usb/java/com/android/server/usb/UsbSettingsManager.java