绕过android usb主机权限确认对话框
我想在工业上使用安卓系统 我可以通过slickdevlabs.com库连接到Profilic和Ftdi USB到串行芯片,没有任何问题 应用程序有一个服务,它在引导时启动,连接到usb串行端口并执行其他操作 我的问题是主机设备与用户没有任何交互 所以当安卓问到绕过android usb主机权限确认对话框,android,permissions,usb,root,usbserial,Android,Permissions,Usb,Root,Usbserial,我想在工业上使用安卓系统 我可以通过slickdevlabs.com库连接到Profilic和Ftdi USB到串行芯片,没有任何问题 应用程序有一个服务,它在引导时启动,连接到usb串行端口并执行其他操作 我的问题是主机设备与用户没有任何交互 所以当安卓问到 Allow the app "MyAPP" to access the USB device ? [checkmark]Use by default for this USB device Cancel OK 没有
Allow the app "MyAPP" to access the USB device ?
[checkmark]Use by default for this USB device
Cancel OK
没有人可以单击“确定”
即使我在默认情况下选中使用。。。复选框,如果我重新插入USB或重新启动主机设备,它会在下次启动时再次询问
我以超级用户模式运行服务和应用程序,但没有区别,它再次问道
我添加了意图过滤器,但没有区别,它每次都会问我
<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访问权限。安卓系统的设计并不是为了支持这种开箱即用的使用。就个人而言,对于非交互式使用,我很想考虑在Linux内核中使用USB串行驱动程序,跳过Android USB API。但你必须认真修改安卓安装——更改内核配置和/或加载模块,创建设备文件并设置其权限或所有者,可能为允许访问的应用程序添加unix组和安卓权限 或者你可以通过android源代码查看并禁用用户确认;但是,如果您没有用于该设备的源代码android构建,这可能比linux级别的想法更为棘手,因为将开源android应用于供应商设备上并非易事(除非已经有人提供了一个源代码构建,该构建对于所讨论的设备来说功能充分)
显然,root/su访问并不适用于应用程序本身——它只意味着知道如何运行您的root黑客留下的任何工具的应用程序可以启动一个以root身份运行的帮助程序,但应用程序本身没有也不能。使用root在系统分区上安装应用程序可能会获得一些非典型的android权限,但您必须检查是否有任何可以帮助您使用usb的权限。我认为我们可以通过在
/etc/udev
中进行一些修改来实现这一点。我们可以将供应商id和设备id添加到51 android.rules
文件中。实现这一点的一种方法是,请注意,这实际上并不排除确认,将是精确定位复选框的位置
,并使用相当于类的Android来选择它,然后选择确定
。你可以编写一个在后台运行的应用程序,它甚至可以被你提到的启动服务调用,特别是为了这个目的。根据Android开发者的文档,当你的应用程序通过manifest intent过滤器启动时,你已经拥有连接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”:
打包android.os;
导入java.util.Map;
公共最终类服务管理器
{
公共静态IBinder getService(字符串名称)
{
抛出新的RuntimeException(“存根!”);
}
/**
*在服务中放置一个名为@a name的新@a服务
*经理。
*
*@param name新服务的名称
*@param service服务对象
*/
公共静态void addService(字符串名称,IBinder服务)
{
抛出新的RuntimeException(“存根!”);
}
/**
*从中检索名为@a name的现有服务
*服务管理器。非阻塞。
*/
公共静态IBinder checkService(字符串名称)
{
抛出新的RuntimeException(“存根!”);
}
公共静态字符串[]listServices()引发RemoteException
{
抛出新的RuntimeException(“存根!”);
}
/**
*仅在首次引入流程时才调用此函数
*由活动管理器启动和绑定。进程中只有一个线程
*在那个时候,没有进行锁定。
*
*@param cache服务引用的缓存
*@隐藏
*/
公共静态void initServiceCache(映射缓存)
{
抛出新的RuntimeException(“存根!”);
}
}
请注意,这些类的接口可能会随着Android版本的不同而变化。我的版本是4.0.3。
所以如果你有另一个版本的Androi
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!" );
}
}
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() );
}
}
}
}
<uses-permission android:name="android.permission.MANAGE_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 {
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;
}
...
service.setDevicePackage( usbDevice, YOUR_APP_PACKAGE_NAMESPACE, ai.uid );
....
public void onStart() {
super.onStart();
mPermissionGranted = true;
finish();
}
<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>
<?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>
<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>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1234" product-id="5678" />
</resources>