Обойти диалоговое окно подтверждения разрешения USB-хоста Android
Я хочу использовать Android в промышленности,
Я могу без проблем подключиться к Profilic и Ftdi USB к последовательным чипам с библиотекой slickdevlabs.com.
В приложении есть служба, которая запускается при загрузке, подключается к последовательному порту USB и выполняет другие действия.
моя проблема в том, что хост-устройство не имеет никакого взаимодействия с пользователем,
так что когда андроид спрашивает
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.
12 ответов
Я знаю, что уже немного поздно, но все же...
У меня была такая же проблема, и я думаю, что мне удалось ее решить. Есть сервис, который 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" />
@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;
}
И измените код, добавив идентификатор пользователя:
...
service.setDevicePackage( usbDevice, YOUR_APP_PACKAGE_NAMESPACE, ai.uid );
....
У меня была та же проблема с всплывающим окном, и никто не нажимал на него. Но я нашел другое решение (для рутованных устройств). Всплывающее окно генерируется android в классе UsbPermissionActivity (а UsbSettingsManager запускается UsbPermissionActivity). Посмотрите на Android Sourcecode, чтобы увидеть, что происходит. Здесь хорошо, что мы можем манипулировать байт-кодом UsbPermissionActivity, чтобы принимать все UsbDevices. Вам нужен инструмент Smali/Baksmali для этого. https://code.google.com/p/smali/
- Найдите файл SystemUI.apk на вашем устройстве
- Скопируйте его на свой компьютер с
adb pull path/to/SystemUI.apk
- Разархивируйте apk
- Разберите файл classes.dex с помощью
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
- Замените оригинальный файл classes.dex и снова заархивируйте все в SystemUI.apk.
- Замените оригинальный SystemUI.apk на вашем устройстве
adb push services.jar path/to/SystemUI.apk
или если это не работает с файловым менеджером AP
Решение - использовать фильтры намерений и добавить 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>
Если у вас есть возможность скомпилировать систему Android, то вы ничего не можете сделать.
Можете добавить
public void onStart() {
super.onStart();
mPermissionGranted = true;
finish();
}
к frameworks/base/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
обойти всплывающее окно подтверждения разрешения.
Android действительно не предназначен для поддержки такого использования из коробки. Лично, для неинтерактивного использования, я хотел бы рассмотреть возможность использования последовательного USB-драйвера в ядре Linux и пропустить USB-интерфейс Android. Но вам придется серьезно изменить установку Android - изменить конфигурацию ядра и / или загрузить модуль, создать файлы устройств и установить их разрешения или владельцев, возможно, добавить группу Unix и разрешение Android для приложений, которым разрешено получить доступ к нему.
Или вы можете просмотреть источник Android и отключить подтверждение пользователя; но если у вас нет сборки Android для Android, это может быть сложнее, чем идея уровня Linux, поскольку адаптация Android с открытым исходным кодом для запуска на устройстве-поставщике может быть нетривиальной (если кто-то уже не предлагает сборка исходного кода, достаточно функциональная для рассматриваемого устройства)
В частности, доступ root / su не относится к самим приложениям - это означает лишь то, что приложение, которое знает, как запустить любой инструмент, оставленный вашим корневым хакером, может запустить вспомогательную программу, которая запускается от имени root, но само приложение не не могу. Использование root для установки приложения в системный раздел может дать вам некоторые нетипичные разрешения для Android, но вам придется проверить, есть ли какие-нибудь, которые помогут вам с usb.
Согласно документации разработчиков Android, у вас уже есть разрешение на подключенное USB-устройство, когда ваше приложение запускается через фильтр манифеста манифеста. Возможно, вам следует попробовать этот подход и написать фильтр для точного соответствия устройству, которое вы хотите использовать, чтобы другие приложения также не могли обмениваться данными с устройством.
Смотрите "Примечание" на http://developer.android.com/guide/topics/connectivity/usb/host.html
Я думаю, что белый список аксессуаров, которые вы используете заранее, будет лучшим решением. Для этого вам нужно добавить файл usb_device_manager.xml по этому адресу / data / system / users / 0
// Обратите внимание, что 0 - это идентификатор пользователя, вероятно, это будет 0, если вы не добавили больше пользователей в Android, но если вы изменили этот идентификатор соответствующим образом
Вот как должен выглядеть файл:
<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>
Один из способов достижения этого, обратите внимание, что это на самом деле не избавляет от подтверждения, было бы точно определить местоположение checkbox
и используйте Android-эквивалент класса Robot, чтобы выбрать его, а затем выберите OK
, Вы можете написать приложение, которое работает в фоновом режиме, оно может даже вызываться той службой запуска, которую вы упомянули, специально для этой цели.
Если у вас есть доступ к исходному коду Android, вот код, необходимый для отключения диалогового окна разрешений.
Приведенное выше обновление кода создает параметр конфигурации, который вы можете использовать, или вместо этого вы можете жестко запрограммировать его, используя значение true вместо mDisablePermissionDialogs
чтобы отключить диалог разрешений.
В services/usb/java/com/android/server/usb/UsbSettingsManager.java
Если вы просто хотите скопировать / записать на флешку, вы можете использовать
следующий метод с командами 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;
}
У меня есть следующие разрешения в моем манифесте, извините, не помню, какие из них являются обязательными.
<permission android:name="com.android.example.USB_PERMISSION"/>
<permission android:name= "android.permission.INSTALL_PACKAGES"/>
<permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<data android:scheme="file" />
Если вы хотите сделать что-то еще, это может быть не очень полезно для вас извините
У меня была та же проблема, всплывающее окно с разрешением появляется каждый раз, когда я подключаю USB-кабель, чтобы решить его, я просто добавил фильтр в манифест и XML-файл для VID и PID, просто убедитесь, что вы настроили фильтрацию USB-устройства, как предложено в ссылка SO выше или как задокументировано здесь, и вы положили хорошие VID и PID. Это была моя проблема, я не поставил VID и PID, которые соответствуют моему устройству
В первый раз, когда требуется подтверждение, вы можете выбрать "всегда", а затем, даже если устройство Android выключено и включено, ваше приложение все еще имеет разрешение на доступ к USB2Serial. Просто сказать, только один раз, чтобы подтвердить!
Я думаю, что мы можем сделать это, внеся некоторые изменения в /etc/udev
, Мы могли бы добавить идентификатор поставщика и идентификатор устройства в 51-android.rules
файл.