Ответ 1
Когда вы запрашиваете разрешение внутри своего приложения, кажется, что флажок "использовать по умолчанию для этого устройства 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-хостом, а андроид - это устройство) - в этом случае фильтр-фильтр должен регистрироваться
<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();
}
}
И последний фрагмент головоломки, прозрачная тема (я не уверен, но вы, вероятно, могли бы использовать встроенную андроидную полупрозрачную тему) - 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>