Разрешения USB без запроса

У меня есть 2 действия в моем приложении. Сказать FirstActivity а также SecondActivity, FirstActivity ОСНОВНАЯ и ЗАПУСКА деятельность. SecondActivity использует USB-устройства. Я хочу, чтобы запрос разрешения USB появлялся только один раз за время существования приложения.

Если был только один вид деятельности, следующие строки в манифесте решили мою цель:

<activity android:name=".FirstActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <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>

Это делало следующее:

  1. Запуск FirstActivity каждый раз, когда подключено USB-устройство (упомянутое в xml), если приложение еще не открыто.
  2. Запрос разрешения USB-устройства появляется только один раз.

Как мне изменить это, чтобы добиться следующего:

  1. Если SecondActivity уже запущено и подключено новое USB-устройство, я должен иметь возможность использовать устройство без перезапуска приложения. Поэтому я написал для приемника вещания следующее:

    public class TriggerReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) { 
            read connected usb devices and register serial port call listener back.
        }
    }    
    

Но проблема в том, FirstActivity снова запускается при подключении USB-устройства SecondActivity бежит. Как мне избежать этого?

Добавлю больше информации при необходимости. Был бы благодарен за любую помощь.

3 ответа

Решение

Попробуйте "удалить" фильтр намерений <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> от FirstActivity как в этом вопросе

Обновить

FirstActivity запускается на каждом USB_DEVICE_ATTACHED (четное SecondActivity работает), потому что вы установили <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> фильтр для него в AndroidManifest.xml файл. Таким образом, вы должны отключить этот фильтр, когда SecondActivity Бег. Вы можете сделать это следующим образом:

1) добавить (например, AliasFirstActivity) в AndroidManifest.xml на ваш FirstActivity и двигаться <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> фильтр для описания псевдонима (вы должны удалить <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />от FirstActivity описание) вот так:

        <activity-alias
            android:targetActivity=".FirstActivity"
            android:name=".AliasFirstActivity"
            android:label="@string/app_name">
            <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" />
            </intent-filter>

            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
                       android:resource="@xml/device_filter" />
        </activity-alias>

2) добавить этот код в onCreate() (или для onResume()) из SecondActivity

PackageManager pm = getApplicationContext().getPackageManager();
        ComponentName compName =
                new ComponentName(getPackageName(), getPackageName() + ".AliasFirstActivity");
        pm.setComponentEnabledSetting(
                compName,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);

подавить фильтр намерений USB_DEVICE_ATTACHED за FirstActivity, Вы должны иметь в SecondActivity что-то вроде того:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        triggerReceiver = new TriggerReceiver();

        IntentFilter filter = new IntentFilter();
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        registerReceiver(triggerReceiver, filter);

        PackageManager pm = getApplicationContext().getPackageManager();
        ComponentName compName =
                new ComponentName(getPackageName(), getPackageName() + ".AliasFirstActivity");
        pm.setComponentEnabledSetting(
                compName,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);
    }

Это должно решить Вашу проблему. 3) если нужно, можно восстановить <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> фильтр для FirstActivity в onDestroy() (или в onPause()) из SecondActivity используя этот код:

    PackageManager pm = getApplicationContext().getPackageManager();
    ComponentName compName =
            new ComponentName(getPackageName(), getPackageName() + ".AliasFirstActivity");
    pm.setComponentEnabledSetting(
            compName,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);

Может быть, этот ответ поможет вам: Подавление всплывающих окон доступа к USB-устройству?

Из этого ответа для вашей деятельности:

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();
}

}

Но проблема в том, FirstActivity снова запускается при подключении USB-устройства SecondActivity бежит. Как мне избежать этого?

Это не сложно ответить. В вашем AndroidManifest.xml вы буквально заявляете, что ваш FirstActivity должен быть запущен, когда событие android.hardware.usb.action.USB_DEVICE_ATTACHED происходит.

Если вы хотите обработать это событие в SecondActivity только тогда вы должны объявить это в манифесте соответственно, например:

    <activity android:name=".FirstActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name=".SecondActivity" android:launchMode="singleTask">
        <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>

Теперь, когда ваше устройство USB подключено, SecondActivity будет запущен только. Если SecondActivity уже запущен, то он не будет запущен снова (или несколько раз) из-за атрибута android:launchMode="singleTask" указано для SecondActivity, Вы можете прочитать больше о различных режимах запуска здесь, если вам интересно.

Поскольку вы заявили в своем манифесте, что SecondActivity должен быть запущен при подключении USB-устройства, система Android задаст вам следующий вопрос:

USB-диалог

После установки флажка "Использовать по умолчанию для этого USB-устройства" он больше не будет спрашивать вас. Теперь, каждый раз, когда вы подключаете USB-устройство, ваш SecondActivity будет запущен, и он также автоматически получит необходимые разрешения USB.

Дайте мне знать, если это ответит на ваш вопрос.

Другие вопросы по тегам