Android Usb主机,singleInstance,onCreate不断被Usb连接调用



我有一个使用专有USB设备的应用程序(主机模式下的android)。

我有一个BroadcastReceiver,我在构造函数中注册它

// this block is in the constructor
usbConnectionReceiver = new UsbConnectionReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
context.registerReceiver(usbConnectionReceiver, filter);

public class UsbConnectionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) onDeviceAttached(device);
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) onDeviceDetached(device);
}
}
}
public void onDeviceAttached(UsbDevice device) {
usbDevice = device;
intf = usbDevice.getInterface(0);
endpoint = intf.getEndpoint(0);
if (usbManager.hasPermission(usbDevice)) {
usbDeviceConnection = usbManager.openDevice(usbDevice);
boolean status = usbDeviceConnection.claimInterface(intf, true);
if (status) {
startPollingThread();
}
} else {
// I used to have code here that would programmatically prompt for permissions.
}
}

一切都很好,只是每次分离和重新连接设备时,都会提示最终用户输入权限。"默认情况下用于此USB设备"复选框被完全忽略。

经过一些研究,如果我通过代码请求权限,情况确实如此。

因此,我已将我的活动切换为使用意向过滤器。在第一次之后,我不再获得权限框,因此复选框正在工作。相反,每次重新连接设备时,它都会调用我的应用程序的onCreate(),使其崩溃

我有launchMode="singleInstance"(事实上,我已经尝试了所有的变体),当应用程序启动并运行并在屏幕上显示时,会调用onCreate()而不是onNewIntent()(文档似乎建议应该这样做)。

我还读到我需要设置android:launchMode="singleInstance"我还读到我需要设置android:taskAffinity=""

一切都无济于事。我知道有很多类似的帖子,但似乎都不起作用。欢迎提出任何建议。

这是我的AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.me.myapp" >
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"
android:launchMode="singleInstance" >
<activity
android:name=".MainActivity"
android:taskAffinity=""
android:label="@string/app_name"
android:configChanges="keyboard" >
<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>
</application>
</manifest>

我相信这是最好的解决方案。。。如果有人有意见,我很乐意听到,因为在android中处理Usb一直是一个令人头疼的问题!

我用这篇文章作为参考USB设备访问弹出式抑制?

我创建了以下活动

public class UsbActivity extends Activity {
private static final String TAG = "UsbActivity";
@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))
{
Logger.lc(TAG,"ACTION_USB_DEVICE_ATTACHED");
UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
Logger.lc(TAG,"UsbDevice");
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
Logger.lc(TAG,"UsbManager");
if (usbDevice != null && usbManager != null && !usbManager.hasPermission(usbDevice)) {
Logger.lc(TAG,"openDevice");
usbManager.openDevice(usbDevice);
}
}
}
finish();
}
}

并将其添加到清单中

<activity
android:name="com.myapp.UsbActivity"
android:label="MyApp"
android:theme="@style/Theme.Transparent"
android:noHistory="true"
android:excludeFromRecents="true"
android:taskAffinity="com.myapp.taskAffinityUsbReceiver"
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/device_filter" />
</activity>

使用以下style.xml

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

最新更新