我有一个使用专有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>
答案 0 :(得分:0)
我相信这是最好的解决方案......如果有人发表评论,我很乐意听到它,因为在android中处理Usb一直很头疼!
我使用这篇文章作为参考USB device access pop-up supression?
我创建了以下活动
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>