gpt4 book ai didi

Android USB_DEVICE_ATTACHED 持久权限

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:10:51 59 4
gpt4 key购买 nike

每次重新连接 USB 设备时,如何让 Android 不请求权限?我想让它记住 USB 设备的“默认使用”复选标记,这样我就不必每次都向同一设备授予权限。

我以编程方式检测 USB 设备(安卓手机)何时连接到我的主机设备(安卓手机),以便我可以将它们切换到 AOA 模式并将它们用作附件。基本上我有两部安卓手机和一根 OTG 数据线,我希望它们能够相互通信。

我有一个不断枚举连接的 USB 设备的线程:

UsbManager manager = (UsbManager) 
context.getSystemService(Context.USB_SERVICE);
while (!m_stopRequested) {
boolean shouldNotify = false;
HashMap<String, UsbDevice> deviceMap = m_usbManager.getDeviceList();
for (Entry<String, UsbDevice> entry : deviceMap) {
UsbDevice device = entry.getValue();
if (m_usbManager.hasPermission(device)) {
int pid = device.getProductId();
if (device.getVendorId() == VID_GOOGLE(0x18D1) && (pid == ACCESSORY_PID(0x2D01) || pid == ACCESSORY_PID_ALT(0x2D00))) {
switchDeviceToAOAMode(device);
}
} else {
m_usbManager.requestPermission(device);
}
}
Thread.sleep(1000);
}

我还注册了一个 BroadcastReceiver 来接收 USB_PERMISSION Intent :

private final class USBReceiver extends BroadcastReceiver {

public void onReceive(Context context, Intent intent) {
MCSLogger.log(TAG, "Received permission result!");

String action = intent.getAction();
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

if (ACTION_USB_PERMISSION.equals(action)) {
boolean res = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);
MCSLogger.log(TAG, "permission action for dev=" + device + " received " + res);
int pid = device.getProductId();
if (res && device.getVendorId() == VID_GOOGLE(0x18D1) && (pid == ACCESSORY_PID(0x2D01) || pid == ACCESSORY_PID_ALT(0x2D00))) {
connectAccessory()
}
}
}
};

这是我切换到 AOA 模式的方式:

  private boolean switchDeviceToAOAMode(UsbDeviceConnection connection) {
byte ioBuffer[] = new byte[2];
int devVersion;
int response;
enter code here
response = connection.controlTransfer(0xC0, 51, 0, 0, ioBuffer, 2, 0);

if (response < 0) {
MCSLogger.log(TAG, "Error starting transfer control " + response);
return false;
}

devVersion = ioBuffer[1] << 8 | ioBuffer[0];

// sometimes hangs on the next transfer :( //WIN32 libusb only
// SystemClock.sleep(1000);

byte manufacturer[] = m_manufacturer.getBytes();
response = connection.controlTransfer(0x40, 52, 0, 0, manufacturer, manufacturer.length, 0);
if (response < 0) {
MCSLogger.log(TAG, "Error transfering manufacturer " + response);
return false;
}
byte modelName[] = m_modelName.getBytes();
response = connection.controlTransfer(0x40, 52, 0, 1, modelName, modelName.length, 0);
if (response < 0) {
MCSLogger.log(TAG, "Error transfering modelName " + response);
return false;
}
byte description[] = m_description.getBytes();
response = connection.controlTransfer(0x40, 52, 0, 2, description, description.length, 0);
if (response < 0) {
MCSLogger.log(TAG, "Error transfering description " + response);
return false;
}
byte version[] = m_version.getBytes();
response = connection.controlTransfer(0x40, 52, 0, 3, version, version.length, 0);
if (response < 0) {
MCSLogger.log(TAG, "Error transfering version " + response);
return false;
}
byte uri[] = m_uri.getBytes();
response = connection.controlTransfer(0x40, 52, 0, 4, uri, uri.length, 0);
if (response < 0) {
MCSLogger.log(TAG, "Error transfering uri " + response);
return false;
}
byte serialNumber[] = m_serialNumber.getBytes();
response = connection.controlTransfer(0x40, 52, 0, 5, serialNumber, serialNumber.length, 0);
if (response < 0) {
MCSLogger.log(TAG, "Error transfering serialNumber " + response);
return false;
}

MCSLogger.log(TAG, "Accessory Identification sent " + devVersion);

response = connection.controlTransfer(0x40, 53, 0, 0, null, 0, 0);
if (response < 0) {
MCSLogger.log(TAG, "Error ending transfer control " + response);
return false;
}
return true;
}

最佳答案

@Ender 提供的答案是正确的,但是在更高版本的 Android 平台(7+)上您还需要做一件事。

您需要确保将 android:directBootAware="true" 添加到负责响应 USB_ACCESSORY_ATTACHED/USB_DEVICE_ATTACHED 权限的 Activity 标签中。

这是 Activity 的有效 list 部分:

    <activity android:name=".MainActivity"
android:directBootAware="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/usb_device_filter" />
</intent-filter>

</activity>

来源:

https://github.com/dazza5000/USBPermissionTest/blob/master/app/src/main/AndroidManifest.xml

usb_device_filter.xml

<?xml version="1.0" encoding="utf-8"?>

<resources>
<usb-device vendor-id="2049" product-id="25"/>
</resources>

来源:

https://github.com/dazza5000/USBPermissionTest/blob/master/app/src/main/res/xml/usb_device_filter.xml

android:directBootAware="true" 提示来自下面的链接,对此我深表感谢。

https://www.sdgsystems.com/post/android-usb-permissions

可以在这里找到更多详细信息:

https://issuetracker.google.com/issues/77658221

完整的工作项目在这里:

https://github.com/dazza5000/USBPermissionTest

根访问权限

如果您有 root 访问权限,您可以创建文件并将其写入磁盘,然后重新启动设备,以便读取和设置默认权限。

这些是基本步骤:

private void grantUSBPermission() { UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();

for (UsbDevice usbDevice : deviceList.values()) {
if (usbDevice.getManufacturerName() != null && usbDevice.getManufacturerName().equalsIgnoreCase(MANUFACTURER)) {
Boolean hasPermission = usbManager.hasPermission(usbDevice);
// Log if USB manager explicitly reports no permission.
if (!hasPermission) {
Log.i("DARRAN", "USB Manager reporting no permission to reader.");
DeviceFilter deviceFilter = new DeviceFilter(usbDevice);
writeSettingsFile(deviceFilter);
}
}
}

private void writeSettingsFile(DeviceFilter deviceFilter) {
PermissionUtil.writeSettingsLocked(getApplicationContext(), deviceFilter);
RootUtil.executeAsRoot(COMMAND_COPY_USB_FILE);
RootUtil.executeAsRoot(COMMAND_CHOWN_USB_FILE);
RootUtil.executeAsRoot("reboot");
}

命令:

public static final String COMMAND_COPY_USB_FILE = "cp /sdcard/Android/data/com.whereisdarran.setusbdefault/files/usb_device_manager.xml /data/system/users/0/usb_device_manager.xml";
public static final String COMMAND_CHOWN_USB_FILE = "chown system:system /data/system/users/0/usb_device_manager.xml";

完整的工作项目可以在这里找到:

https://github.com/dazza5000/set-usb-default

此外,还有一篇具有更多上下文的博客文章:

http://whereisdarran.com/2019/12/wip-how-to-programmatically-set-your-app-as-the-default-app-for-a-usb-device-on-android-root-required/

关于Android USB_DEVICE_ATTACHED 持久权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40075128/

59 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com