androidandroid-usb

USB Permissions without prompt


I have 2 activities within my app. Say FirstActivity and SecondActivity. FirstActivity is the MAIN and LAUNCHER activity. SecondActivity uses usb devices. I want the prompt for USB permission to appear only once within lifetime of the app.

If there was only one Activity, the following lines in manifest solved my purpose:

<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>

This was doing the following:

  1. Launching FirstActivity whenever usb device (mentioned in xml) is connected is app is not already open.
  2. Prompt for usb device permission appears only once.

How do I modify this to achieve the following:

  1. If SecondActivity is already running and a new usb device is attached, I must be able to use the device without relaunching the app. So I have written a broadcast receiver for the same as follows:

    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.
        }
    }    
    

But the problem is FirstActivity gets relaunched again when usb device is attached while SecondActivity is running. How do I avoid this ?

Will add more information if needed. Would be thankful for any help.


Solution

  • Try "remove" intent filter <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> from FirstActivity like in this question

    Update

    FirstActivity triggers on every USB_DEVICE_ATTACHED (even SecondActivity is running) because You set <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> filter for it in AndroidManifest.xml file. So You should disable this filter when SecondActivity running. You can do this by that way:

    1) add (e.g. AliasFirstActivity) in AndroidManifest.xml to your FirstActivity and move <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> filter to alias description (You should remove <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />from FirstActivity description) like that:

            <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) add this code to onCreate() (or to onResume()) of SecondActivity

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

    to suppress intent filter USB_DEVICE_ATTACHED for FirstActivity. You should have in SecondActivity something like that:

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

    That should solve Your issue. 3) if it is needed, You can restore <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> filter for FirstActivity in onDestroy() (or in onPause()) of SecondActivity by using this code:

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