Подавление всплывающих окон доступа к USB-устройству?

Когда USB-устройство подключено к планшету Android, появляется всплывающее окно с запросом разрешения пользователя. Я хочу подавить это, поскольку клиент этого не хочет. Как мне это сделать?

В коде:

UsbManager.requestpermission(); 

вызывается для предоставления временного доступа к USB-устройству.

Это вызывает всплывающее окно. Как подавить всплывающее окно или предоставить пользователю доступ по умолчанию?


person Community    schedule 12.09.2012    source источник


Ответы (2)


Когда вы запрашиваете разрешение внутри своего приложения, кажется, что флажок «использовать по умолчанию для этого USB-устройства» ничего не делает (я не уверен, почему этот флажок вообще отображается в этом всплывающем окне.

Вместо этого вы должны зарегистрировать обработчик намерений для своей активности в манифесте:

<activity 
    ...
    ...
    >
    <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/usb_device_filter" />  
</activity>

Вам также необходимо создать файл фильтра в ваших xml-ресурсах, например res / xml / usb_device_filter:

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

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

Идентификатор поставщика и идентификатор продукта здесь должны быть даны в десятичном формате - выше как VID, так и PID равны 0x6666.

То, что я привел выше, также работает для USB-аксессуара (то есть, где аксессуар является USB-хостом, а Android - устройством) - в этом случае фильтр намерений должен регистрировать

<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />

и вы также должны точно таким же образом включить фильтр метаданных.

См. http://developer.android.com/guide/topics/connectivity/usb/accessory.html и найдите раздел «Использование фильтра намерений».

ИЗМЕНИТЬ

В заключение - если вы зарегистрируете фильтр намерений для своей деятельности, окно разрешения USB будет отображаться сразу после подключения USB-устройства / аксессуара. Если пользователь установит флажок «использовать по умолчанию для этого USB-устройства» и затем предоставит разрешение, это будет запомнено, и диалоговое окно разрешения больше не будет отображаться (если приложение не будет удалено или пользователь не удалит действие по умолчанию из диспетчера приложений. ).

Я поместил сюда крошечный, ужасный, рабочий пример проекта:

http://www.locusia.com/examples/permissionTest.zip

Вам нужно будет отредактировать res / xml / usb_device_filter.xml, но в противном случае это должно позволить вам очень быстро протестировать его.

Для услуг ...

Кажется, что служба не может получить намерения USB. Я обошел это, выполнив скрытое действие, которое затем ретранслировало намерения.

Я определяю это в своем манифесте так:

<activity
    android:name=".activities.UsbEventReceiverActivity"
    android:label="YOUR APPLICATION NAME - This appears in the permission popup"
    android:theme="@style/Theme.Transparent" 
    android:noHistory="true"
    android:excludeFromRecents="true"
    android:taskAffinity="com.example.taskAffinityUsbEventReceiver"
    android:process=":UsbEventReceiverActivityProcess"
    android:exported="false"
    >    
    <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/usb_device_filter" />  
</activity>

(У меня в сервисе сложная схема задач / процессов, YMMV в этой области).

Я определил деятельность так:

public class UsbEventReceiverActivity extends Activity
{   
    public static final String ACTION_USB_DEVICE_ATTACHED = "com.example.ACTION_USB_DEVICE_ATTACHED";
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume()
    {
        super.onResume();

        Intent intent = getIntent();
        if (intent != null)
        {
            if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED))
            {
                Parcelable usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                // Create a new intent and put the usb device in as an extra
                Intent broadcastIntent = new Intent(ACTION_USB_DEVICE_ATTACHED);
                broadcastIntent.putExtra(UsbManager.EXTRA_DEVICE, usbDevice);

                // Broadcast this event so we can receive it
                sendBroadcast(broadcastIntent);
            }
        }

        // Close the activity
        finish();
    }
}

И последний кусок головоломки, прозрачная тема (я не уверен, но вы, вероятно, могли бы использовать встроенную полупрозрачную тему Android) - res / values ​​/ styles.xml:

<?xml version="1.0" encoding="utf-8"?>  
    <resources>  
    <style name="Theme.Transparent" parent="android:Theme">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:backgroundDimEnabled">false</item>
        <item name="android:windowAnimationStyle">@null</item>
    </style>  
</resources>  
person Wayne Uroda    schedule 01.03.2013
comment
Для режима USB-хоста эта информация представлена ​​в developer.android.com/guide. /topics/connectivity/usb/host.html. В разделе «Работа с устройствами» на этой странице говорится, что приложение должно 2. Запросить у пользователя разрешение на подключение к USB-устройству, если оно еще не получено. Вопрос OP (и мой!) Заключается в том, как указать, что разрешение уже предоставлено, чтобы всплывающее окно НИКОГДА не появлялось, и приложение могло немедленно использовать устройство. - person kbro; 02.03.2013
comment
@kbro, когда вы говорите, что разрешение уже предоставлено, что именно вы имеете в виду? Если разрешение уже предоставлено, функция UsbManger.hasPermission () (передать либо аксессуар, либо устройство) вернет true, и вы можете просто открыть и использовать аксессуар / устройство. Невозможно полностью подавить всплывающее окно - оно должно отображаться хотя бы один раз, и пользователю нужно будет установить флажок для использования по умолчанию для этого устройства и нажать да / ок / принять - обратите внимание, что вы ДОЛЖНЫ зарегистрировать намерение- фильтровать действие, чтобы разрешение было запомнено для вашего приложения. - person Wayne Uroda; 05.03.2013
comment
Я просто добавил еще один абзац к своему ответу выше, потому что, возможно, раньше он не был полностью ясен. - person Wayne Uroda; 05.03.2013
comment
Хорошо, я понимаю, что Android должен спросить хотя бы один раз, но я не могу этого добиться - он запрашивает каждый раз, когда устройство удаляется и повторно вставляется. Я думаю, вы говорите, что причина этого в том, что приложение вызывает RequestPermission. Мне нужно ответить исключительно на фильтр событий. - person kbro; 08.03.2013
comment
Но это не совсем ответ, потому что это, кажется, противоречит разделу Использование фильтра намерений в developer.android.com/guide/topics/connectivity/usb/host.html - если пользователи соглашаются, ваше приложение автоматически получает разрешение на доступ к устройству до тех пор, пока устройство не будет отключено. Это довольно ясно о потере разрешения при отключении устройства. Однако, если вы внимательно прочитаете этот раздел, то в нем не упоминается использование по умолчанию флажка, так что это последний недостающий кусок магии, который заставит эту работу работать так, как я хочу? - person kbro; 08.03.2013
comment
В заключение, если я сделаю все ТОЧНО, как вы сказали, будет ли это работать так, что если я подключу USB-устройство один раз, до того, как мое приложение запустится, поставлю флажок и коснусь ОК, тогда у меня НИКОГДА не спросят разрешения снова , путем удаления USB-устройства и перезагрузки планшета, пока приложение не будет переустановлено или обновлено? - person kbro; 08.03.2013
comment
Да, я тестировал Galaxy S3 (Android 4.1.1), Galaxy Note (4.0.4) и Nexus 7 (4.2.2) - разрешение нужно принимать только один раз, если установлен флажок - и это будет вспомнил даже через перезагрузку / выключение питания. - person Wayne Uroda; 08.03.2013
comment
@kbro Я отредактировал свой ответ, я разместил очень небольшой демонстрационный проект, который позволит вам протестировать концепцию, прежде чем вы приступите к рефакторингу своего кода. - person Wayne Uroda; 08.03.2013
comment
Вы были удивительно любезны и терпеливы. Я попрошу своих ребят из SW это проверить. - person kbro; 08.03.2013
comment
Это нормально - в большинстве мест, где я могу помочь, многие люди уже дают ответы, поэтому, когда я сталкиваюсь с чем-то, что знаю, я стараюсь помочь как можно больше :) - person Wayne Uroda; 08.03.2013
comment
Итак, ваше приложение работает так, как рекламируется, но вы используете действие, тогда как мой код - это служба, и установка фильтра намерений в раздел ‹service› ... ‹/service› файла AndroidManifect.xml не работает. t похоже, оказывает какое-либо влияние. Также я получаю другое сообщение - ваше тестовое приложение получает Open MainActivity, когда это USB-устройство подключено? а мой говорит: Разрешить приложению APPNAME доступ к USB-устройству? - person kbro; 10.03.2013
comment
Глядя на stackoverflow.com/questions/13466103/, ответ предлагает вместо этого использовать намерения UMS_CONNECTED и UMS_DISCONNECTED. Помогло бы это в моем случае? - person kbro; 10.03.2013
comment
Пожалуйста, посмотрите новую информацию в конце моего ответа - я надеюсь, что это сработает для вас. - person Wayne Uroda; 10.03.2013
comment
Выглядит правдоподобно. Еще раз спасибо за ваши усилия. Я дам вам знать, как у нас дела! - person kbro; 10.03.2013
comment
Как в этом случае работает автоматическое предоставление разрешений - получает ли их Сервис, потому что он является частью того же APK, что и Activity? - person kbro; 10.03.2013
comment
Я не уверен - даются ли разрешения даже для каждого приложения в отдельности? Android на самом деле не имеет концепции приложения, за исключением того, что все определяется в том же манифесте - если бы я сказал, что знаю, я бы только догадывался! Все, что я знаю, это работает, даже если служба и действие выполняются в отдельных задачах и процессах. - person Wayne Uroda; 10.03.2013
comment
Думаю, это то, что я имел в виду, говоря о части того же APK. Так что, если служба и действие определены в одном и том же файле AndroidManifest.xml (а я думаю, что в файле APK есть только один из них), тогда автоматическое предоставление разрешений работает. Прекрасный!! Теперь, если бы я мог только заставить StackOverflow отправлять мне электронные письма, когда были опубликованы новые комментарии, я был бы в раю :-) - person kbro; 10.03.2013
comment
Ахах - нашел. В разделе StackExchange слева от панели вверху страницы нет ничего общего с моим профилем - поймите! - person kbro; 10.03.2013
comment
@WayneUroda, я пробовал ваш пример, и мне удалось интегрировать его в свой код, и диалоговое окно USB не появляется во второй раз, но есть еще одна проблема с активностью, активность, в которой я сделал IntentFilter для USB Прикрепил его начало, если я нахожусь в другом экран. здесь я не хочу начинать это, если я занимаюсь другим делом - person Nikunj Patel; 09.01.2014
comment
@NikPatel Мой пример охватывает это - просто используйте инструкции для служб - это создает скрытое действие (не отображается в истории, не отображается на экране), которое finish выделяется сразу после запуска. - person Wayne Uroda; 13.01.2014
comment
@WayneUroda, не могли бы вы уточнить - person Nikunj Patel; 13.01.2014
comment
@NikPatel создает скрытое действие, то есть такое, которое не отображается в истории (android:noHistory="true" android:excludeFromRecents="true" в вашем манифесте), а затем имеет само действие finish в функции onresume (чтобы действие никогда не было активным / сверху). Также вы можете присвоить действию прозрачную тему без анимации, чтобы ОС не отображала переходы. Вам решать, как вы хотите, чтобы действие выполняло свою работу - оно может порождать новый поток, транслировать намерение в другую часть вашего приложения или что-то еще. - person Wayne Uroda; 13.01.2014
comment
@WayneUroda yap Я попробую то же самое и дам вам знать спасибо :) - person Nikunj Patel; 13.01.2014
comment
вот одна проблема с приложением, я хочу показать диалог, когда распечатка закончилась. так что на самом деле, когда я распечатываю, должен быть виден мой диалог, и когда я нахожусь на другом мероприятии и подключаю кабель USB, не должно быть никакого эффекта ... после попытки этого примера я все еще не достигаю этого. не могли бы вы помочь мне в этом - person Nikunj Patel; 20.01.2014
comment
@WayneUroda: Как только USB-соединение между Android и USB-устройством будет установлено, будет ли это соединение длиться вечно? Я протестировал свой код, запустив успешное соединение и оставил его в таком состоянии всю ночь. На следующий день я вижу, что не могу отправлять какие-либо данные через USB-соединение. Я предполагаю, что через какое-то время соединение прервалось. Это нормально, или мне нужно отправлять какие-либо фиктивные сигналы через определенные промежутки времени между устройством android и usb, чтобы поддерживать соединение в живом / активном состоянии? - person Basher51; 03.07.2014
comment
@WayneUroda: Кроме того, в моем случае у меня есть широковещательный приемник вместо активности / службы, который прослушивает подключенные к usb / намерения разрешения. Пока все работает нормально, и мой приемник действительно получает эти намерения при перезагрузке устройства. Мне просто нужно чтобы отключить повторное появление всплывающего окна разрешений USB. Нужно ли мне использовать это прозрачное действие в моем случае? Кроме того, появится ли это всплывающее окно повторно при обновлении приложения? Пожалуйста, помогите мне, так как я очень близок к получению солнца. Спасибо. - person Basher51; 03.07.2014
comment
Спасибо, у меня почти работает. Однако, чтобы запустить службу, мне пришлось сделать намерение явным (предоставив this, null, MyService.class в качестве дополнительных аргументов) и использовать startService(), а не sendBroadcast() - только тогда служба действительно запустится. - person user149408; 29.05.2017
comment
Я использовал это невидимое занятие несколько лет. Но теперь возникает одна проблема: устройство usb_device_filter.xml используется для нескольких приложений. Затем, когда я подключаю USB, отображается окно выбора активности, я должен выбрать тот, который является невидимым действием, в противном случае разрешение не будет предоставлено. Поэтому я хотел бы знать, могу ли я использовать приемник, но не невидимое действие (мы уже знаем, что служба не работает)? Можно ли запустить приемник, объявленный в манифесте, из подключаемого модуля USB-устройства (определенного в usb_device_filter.xml)? - person Yeung; 30.01.2018
comment
Я следил за этим и использовал правильный идентификатор поставщика и идентификатор продукта, но все же каждый раз, когда USB-устройство (Arduino Teensy) отключается от телефона, приложение снова требует разрешения. Что-то мне не хватает. Для получения дополнительной информации я задал новый вопрос: stackoverflow.com/q/54298521 - person Wowsk; 24.01.2019
comment
для меня это работает, но если устройство перезагружено, появляется диалоговое окно подтверждения. Я установил приложение в папку System / priv-app - person Jemo Mgebrishvili; 12.03.2019
comment
@WayneUroda как запомнить разрешение после перезагрузки? - person user924; 22.08.2019
comment
@WayneUroda, Привет, я использую фрагмент, где прошу USB-разрешение для биометрического устройства. Теперь, если я использую ваш код, мне нужно передать фильтр намерений в его Activity, и это приведет меня к этому конкретному Activity, если я буду следовать вашим шагам в диалоговом окне разрешений. Пожалуйста, расскажите мне, как это сделать во фрагменте - person Priyanka Alachiya; 19.03.2020
comment
к сведению: вы можете узнать идентификатор поставщика и идентификатор продукта из adb logcat. просто подключите устройство и проверьте там - person nexus; 05.04.2020

Поздно, но я надеюсь помочь. В официальной документации Android говорится: «Когда пользователи подключают устройство, которое соответствует вашему устройству. filter, система представляет им диалоговое окно, в котором спрашивается, хотят ли они запустить ваше приложение. Если пользователи соглашаются, ваше приложение автоматически получает разрешение на доступ к устройству до тех пор, пока устройство не будет отключено. ". Если вы также установите флажок для запоминания устройства, разрешение предоставляется до тех пор, пока приложение не будет удалено или данные не будут удалены через диспетчер приложений.

Итак, вы должны сделать:

  1. Добавьте фильтр намерений как Уэйн говорит (и удалите все о разрешениях в вашем основном действии).
  2. Установите приложение и ЗАКРЫТЬ.
  3. Отключите и подключите usb.
  4. Примите разрешение и установите флажок, чтобы запомнить устройство.
  5. Наслаждаться.
person jlbofh    schedule 07.05.2019
comment
Есть ли у вас предложение, если вы ожидаете, что кабель USB уже будет подключен при включении питания? Я реализовал этот подход, и он отлично работает, если я подключаю USB-кабель после включения, но в моем случае я ожидаю, что кабель будет оставаться подключенным все время. - person Ryan Tensmeyer; 19.05.2021