8

我的应用程序中有 2 个活动。说FirstActivitySecondActivityFirstActivity是 MAIN 和 LAUNCHER 活动。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. 每当连接 USB 设备(在 xml 中提到)时启动 FirstActivity 是应用程序尚未打开。
  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。我该如何避免这种情况?

如果需要,将添加更多信息。将感谢任何帮助。

4

3 回答 3

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)添加(例如AliasFirstActivityAndroidManifest.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_ATTACHEDFirstActivity。你应该有这样的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)如果需要,您可以使用以下代码恢复in (或 in )的<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />过滤器:FirstActivityonDestroy()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);
于 2016-10-21T17:31:57.323 回答
2

但问题是在运行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都只会启动。如果SecondActivityis already runningandroid:launchMode="singleTask" ,则由于为指定的属性,它将不会再次(或多次)启动SecondActivity。如果您有兴趣,可以在此处阅读有关不同启动模式的更多信息。

由于您在清单中声明SecondActivity应在插入 USB 设备时启动,Android 系统将询问您以下问题:

USB 对话框

勾选“默认使用此 USB 设备”复选框后,它不会再询问您。现在,每次您插入 USB 设备时,您的设备SecondActivity都会启动,它也会自动获得所需的 USB 权限。

让我知道这是否回答了您的问题。

于 2016-10-24T10:39:16.513 回答
1

这个答案可能会有所帮助: 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();
    }
}
于 2016-10-30T16:45:53.740 回答