2016-12-30 111 views
1

我有一个应用程序使用专有的USB设备(android在主机模式)。Android的USB主机,singleInstance,onCreate不断调用USB附加

我有一个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

我相信这是最好的解决办法...如果任何人有意见,我很乐意听到它,因为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(); 
    } 
} 

而且它具有以下style.xml添加到清单

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