2014-10-22 5 views
0

의 Android UsbHost 문제 응용 프로그램이 이미 열려 있고 USBDevice가 연결되어있는 경우 응용 프로그램이 때때로 장치와 통신 할 수 있으며 때때로 그렇지 않습니다. 내가받는 오류는 매번 다를 수 있습니다. 상수는 삼성 Galaxy 휴대 전화 인 Nexus 7, Nexus 10에서 예상대로 작동합니다. 연결되는 기기에서 애플리케이션이 시작되면 대부분의 경우 예상대로 작동합니다. , 응용 프로그램이 이미 열려 있으면Android 갤럭시 탭 S 10.5 및 Unity

// Get the device that woke up the activity 
UsbDevice connectedDevice = (UsbDevice)getIntent() 
     .getParcelableExtra(UsbManager.EXTRA_DEVICE); 

if (connectedDevice != null) { 
    UsbManager manager = (UsbManager)getSystemService(Context.USB_SERVICE); 
    UsbDevice device = connectedDevice; 
    writeDeviceInfo(device); 
    initDataTransferThread(manager, device); 

} 

:

매니페스트는 내가하여 응용 프로그램이 의도에서 시작되었다 있는지 확인하지 OnCreate

<uses-feature android:name="android.hardware.usb.host" /> 
<uses-feature android:name="android.hardware.usb.UsbInterface" /> 

<activity android:label="@string/app_name" 
    android:screenOrientation="fullSensor" android:launchMode="singleTask" 
    android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale" 
    android:name="com.realart.Beatmaker.UnityPlayerNativeActivity"> 

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

    <!-- USB Connect List --> 
    <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" 
     android:resource="@xml/device_filter" /> 

    <intent-filter> 
     <action android:name="android.intent.action.VIEW" /> 
     <category android:name="android.intent.category.DEFAULT" /> 
     <category android:name="android.intent.category.BROWSABLE" /> 
    </intent-filter> 

    <meta-data android:name="unityplayer.UnityActivity" android:value="true" /> 
    <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />  

</activity> 

그래서

처럼 설정 launchModesingleTask이므로 onNewIntent 메서드를 재정의했습니다.

@Override 
public void onNewIntent(Intent intent) { 
    final String DEVICE_CONNECTED = "android.hardware.usb.action.USB_DEVICE_ATTACHED"; 

    String action = intent.getAction(); 
    if (action.equals(DEVICE_CONNECTED)) { 
     Log.d(TAG, "Device connected"); 
     final UsbManager manager = (UsbManager)getSystemService(Context.USB_SERVICE); 

     try { 
      final UsbDevice connectedDevice = (UsbDevice)intent 
        .getParcelableExtra(UsbManager.EXTRA_DEVICE); 

      if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { 
       if (connectedDevice != null) { 
        writeDeviceInfo(connectedDevice); 
        initDataTransferThread(manager, connectedDevice); 
       } else { 
        Log.d(TAG, "Device null"); 
       } 
      } else { 
       Log.d(TAG, "Permission denied"); 
       Log.d(TAG, "Asking for permission and trying again..."); 
       manager.requestPermission(connectedDevice, permissionIntent); 
      } 
     } catch (Exception e) { 
      Log.d(TAG, "Exception throw: " + e.toString()); 
      e.printStackTrace(); 
     } 
    } 
} 
(210)

그리고 그것은 거의 항상 권한이 방법으로 다른 블록을 거부 안타 그래서 그때과 같이 설정 한 권한 체크 방송 수신기로 이동 :

// Attach Events 
attachReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d(TAG, "Permissions receiver hit"); 
     String action = intent.getAction(); 
     Log.d(TAG, "Action requested: " + action); 
     UsbManager manager = (UsbManager)getSystemService(Context.USB_SERVICE); 
     if (intent.getAction().equals("com.realart.Beatmaker.USB_PERMISSION")) { 

      // Thread still running? 
      if (arduino != null) { 
       if (arduino.pipeline != null) { 
        Message msg = Message.obtain(); 
        msg.what = Change.USB_DISCONNECTED; 
        arduino.pipeline.sendMessage(msg); 
       } 
       arduino = null; 
      } 

      synchronized (this) { 
       Log.d(TAG, "Checking permissions from user..."); 
       UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); 
       boolean permissionGranted = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false); 
       Log.d(TAG, "Permissions granted: " + permissionGranted); 
       if (permissionGranted) { 
        if (device != null) { 
         writeDeviceInfo(device); 
         initDataTransferThread(manager, device); 
        } else { 
         Log.d(TAG, "Device null"); 
        } 
       } else { 
        Log.d(TAG, "Permission denied from user"); 
       } 
      } 
     } 
    } 
}; 

permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent("com.realart.Beatmaker.USB_PERMISSION"), 0); 
IntentFilter attachFilter = new IntentFilter("com.realart.Beatmaker.USB_PERMISSION"); 
registerReceiver(attachReceiver, attachFilter); 

그 과정이 원인이 될 것 같지 않습니다 모든 오류 및 장치 정보가 매번 기록됩니다. 때로는 두 개의 인터페이스를 열거하기도합니다. 때로는 0입니다. 이상한 점은 무엇이며, 왜 그렇게 할 수 있는지 모르겠습니다.

V/UsbHostManager(2733): USB HOST UEVENT: {SUBSYSTEM=host_notify, STATE=ADD, DEVNAME=usb_otg, DEVPATH=/devices/virtual/host_notify/usb_otg, SEQNUM=18860, ACTION=change} 
D/UsbHostManager(2733): turnOnLcd :: 
D/UsbHostNotification(2733): setUsbObserverNotification : cancel id = 998563545, device = UsbDevices 
D/UsbHostNotification(2733): setUsbObserverNotification : notify id = 998563545, device = UsbDevices, title = USB connector connected. 
D/UsbHostNotification(2733): send the timeout : current 1413981920804, vailed = -2999, displayed = 1413981920803 
D/UsbHostNotification(2733): setUsbObserverNotification : cancel id = 998563545, device = UsbDevices 
D/UsbHostManager(2733): usbDeviceAdded : device :: /dev/bus/usb/002/077 [2341h:003dh] [02h,00h,00h] (CDC Control) 
D/UsbHostManager(2733): usbDeviceAdded : interface :: /dev/bus/usb/002/077 [2341h:003dh] [02h,02h,01h] (CDC Control) 
D/UsbHostManager(2733): usbDeviceAdded : interface :: /dev/bus/usb/002/077 [2341h:003dh] [0ah,00h,00h] (CDC Data) 
D/UsbSettingsManager(2733): deviceAttached: /dev/bus/usb/002/077 def package com.realart.Beatmaker 
D/UsbSettingsManager(2733): deviceAttached, send intent Intent { act=android.hardware.usb.action.USB_DEVICE_ATTACHED flg=0x10000000 (has extras) } 
D/UsbSettingsManager(2733): deviceAttached, call to resolveActivity started, Intent { act=android.hardware.usb.action.USB_DEVICE_ATTACHED flg=0x10000000 (has extras) } 
D/UsbSettingsManager(2733): resolveActivity : matches count = 1, defaultPackage = com.realart.Beatmaker 
D/UsbSettingsManager(2733): resolveActivity : defaultRI = ResolveInfo{425e9ad0 com.realart.Beatmaker/.UnityPlayerNativeActivity m=0x108000} 
D/UsbSettingsManager(2733): grantDevicePermission: UsbDevice[mName=/dev/bus/usb/002/077,mVendorId=9025,mProductId=61,mClass=2,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.hardware.usb.UsbInterface;@42d33850] for 10212 
D/UsbSettingsManager(2733): grantDevicePermission: mDevicePermissionMap put UsbDevice[mName=/dev/bus/usb/002/077,mVendorId=9025,mProductId=61,mClass=2,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.hardware.usb.UsbInterface;@42d33850] for {} 
D/UsbSettingsManager(2733): resolveActivity : permissionsGranted to ResolveInfo{425e9ad0 com.realart.Beatmaker/.UnityPlayerNativeActivity m=0x108000} 
D/UsbSettingsManager(2733): deviceAttached, call to resolveActivity ended, Intent { act=android.hardware.usb.action.USB_DEVICE_ATTACHED flg=0x10000000 cmp=com.realart.Beatmaker/.UnityPlayerNativeActivity (has extras) } 
D/Unity (30871): Device connected 
D/Unity (30871): Permission denied 
D/Unity (30871): Asking for permission and trying again... 
D/UsbSettingsManager(2733): requestPermission:/dev/bus/usb/002/077 ,pi PendingIntent{42169a08: PendingIntentRecord{42c42748 com.realart.Beatmaker broadcastIntent}} 
D/UsbSettingsManager(2733): Request Permission for Device vendorId: 9025, productId: 61, package: com.realart.Beatmaker 
D/UsbSettingsManager(2733): hasPermission++ 
D/UsbSettingsManager(2733): hasPermission: UsbDevice[mName=/dev/bus/usb/002/077,mVendorId=9025,mProductId=61,mClass=2,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.os.Parcelable;@4360cc38]for {10212=true} 
D/UsbSettingsManager(2733): requestPermission:/dev/bus/usb/002/077 has permissions 
D/Unity (30871): Permissions receiver hit 
D/Unity (30871): Action requested: com.realart.Beatmaker.USB_PERMISSION 
D/Unity (30871): Checking permissions from user... 
D/Unity (30871): Permissions granted: true 
D/Unity (30871): Device name: /dev/bus/usb/002/077 
D/Unity (30871): Vender id: 9025 
D/Unity (30871): Product id: 61 
D/Unity (30871): Class: class android.hardware.usb.UsbDevice 
D/Unity (30871): Sub-class: 0 
D/Unity (30871): Protocol: 0 
D/Unity (30871): Num Interfaces: 2 
D/Unity (30871): Device hash: 263427216 
D/Arduino (30871): USB Interface claimed: false 
D/Arduino (30871): Trying again with kernel driver 
D/Arduino (30871): Unable to claim interface. 
D/UsbSettingsManager(2733): checkPermission: /dev/bus/usb/002/077 
D/UsbSettingsManager(2733): hasPermission++ 
D/UsbSettingsManager(2733): hasPermission: UsbDevice[mName=/dev/bus/usb/002/077,mVendorId=9025,mProductId=61,mClass=2,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.hardware.usb.UsbInterface;@42d33850]for {10212=true} 

다음 줄이 로그 캣 인쇄 후 눈에 띄는 시간 제한이있는 것 같습니다 :

private boolean initSerialBus() { 
    try { 
     // Open device 
     connection = usbManager.openDevice(arduino); 
     if (connection == null) { 
      Log.d(TAG, "Opening device failed"); 
      return false; 
     } 

     // Get serial interface 
     usbInterface = arduino.getInterface(1); 
     boolean interfaceClaimed = connection.claimInterface(usbInterface, FORCE_CLAIM); 
     Log.d(TAG, "USB Interface claimed: " + interfaceClaimed); 
     if (!interfaceClaimed) { 
      Log.d(TAG, "Trying again with kernel driver"); 
      interfaceClaimed = connection.claimInterface(usbInterface, false); 
      if (!interfaceClaimed) { 
       Log.d(TAG, "Unable to claim interface."); 
       return false; 
      } 
     } 

     // Arduino USB serial converter setup 
     Log.d(TAG, "Data Transfter setup"); 

     // Line state 
     int lineState = connection.controlTransfer(0x21, 0x22, 0, 0, null, 0, 0); 
     if (lineState < 0) { 
      Log.d(TAG, "Line state control transfer failed."); 
      Log.d(TAG, "Return value: " + lineState); 
      releaseUsbResources(); 
      arduinoState.onArduinoError(new Exception("Control frame transfer error")); 
      return false; 
     } 
     Log.d(TAG, "Line state control frame: OK return: " + lineState); 

     // Line encoding (9600 Baud) 
     final byte[] lineEncoding = { 
       (byte) 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 
     }; 
     int lineEncode = connection.controlTransfer(0x21, 0x20, 0, 0, lineEncoding, 7, 0); 
     if (lineEncode < 0) { 
      Log.d(TAG, "Line encoding control transfer failed."); 
      Log.d(TAG, "Return value: " + lineEncode); 
      releaseUsbResources(); 
      arduinoState.onArduinoError(new Exception("Control frame transfer error")); 
      return false; 
     } 
     Log.d(TAG, "Line encoding control frame: OK return: " + lineEncode); 

     // I/O Endpoints 
     for (int i = 0; i < usbInterface.getEndpointCount(); i++) { 
      UsbEndpoint endpoint = usbInterface.getEndpoint(i); 
      if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { 
       if (endpoint.getDirection() == UsbConstants.USB_DIR_IN) { 
        arduinoIn = usbInterface.getEndpoint(i); 
       } else { 
        arduinoOut = usbInterface.getEndpoint(i); 
       } 
      } 
     } 

     // Ensure we found the endpoints 
     if (arduinoIn == null || arduinoOut == null) { 
      releaseUsbResources(); 
      arduinoState.onArduinoError(new Exception("No usb endpoints found")); 
      return false; 
     } 
     Log.d(TAG, "I/O Enpoints found"); 
     arduinoConnected = true; 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return arduinoConnected; 
} 

이 일반적인 로그 캣 출력은 다음과 같습니다

내가 장치를 초기화하고 방법입니다 :

D/UsbHostNotification(2733): send the timeout : current 1413981920804, vailed = -2999, displayed = 1413981920803 
D/UsbHostNotification(2733): setUsbObserverNotification : cancel id = 998563545, device = UsbDevices 

나머지 응용 프로그램이 충분히 빠르지 만 문제가 발생하지 않는 경우 하지만 그 단계에서 몇 초 동안 멈 추면 매번 실패합니다. 그러나 항상 같은 지점에있는 것은 아닙니다. 때로는 인터페이스를 요청하려고 할 때가끔 제어 전송을 전송할 때가 있고 때로는 실패 메시지도 전송되지 않지만 데이터가 수신되지 않는 경우가 있습니다. 응용 프로그램이 시작됩니다

의 로그 캣 출력은 다음과 같습니다

응용 프로그램이 시작됩니다
--------- beginning of /dev/log/system 
D/UsbHostNotification(2733): setUsbObserverNotification : cancel id = 998563545, device = UsbDevices 
--------- beginning of /dev/log/main 
V/UsbHostManager(2733): USB HOST UEVENT: {SUBSYSTEM=host_notify, STATE=ADD, DEVNAME=usb_otg, DEVPATH=/devices/virtual/host_notify/usb_otg, SEQNUM=19659, ACTION=change} 
D/UsbHostManager(2733): turnOnLcd :: 
D/UsbHostNotification(2733): setUsbObserverNotification : cancel id = 998563545, device = UsbDevices 
D/UsbHostNotification(2733): setUsbObserverNotification : notify id = 998563545, device = UsbDevices, title = USB connector connected. 
D/UsbHostNotification(2733): send the timeout : current 1413982261198, vailed = -2991, displayed = 1413982261189 
D/UsbHostManager(2733): usbDeviceAdded : device :: /dev/bus/usb/002/081 [2341h:003dh] [02h,00h,00h] (CDC Control) 
D/UsbHostManager(2733): usbDeviceAdded : interface :: /dev/bus/usb/002/081 [2341h:003dh] [02h,02h,01h] (CDC Control) 
D/UsbHostManager(2733): usbDeviceAdded : interface :: /dev/bus/usb/002/081 [2341h:003dh] [0ah,00h,00h] (CDC Data) 
D/UsbSettingsManager(2733): deviceAttached: /dev/bus/usb/002/081 def package com.realart.Beatmaker 
D/UsbSettingsManager(2733): deviceAttached, send intent Intent { act=android.hardware.usb.action.USB_DEVICE_ATTACHED flg=0x10000000 (has extras) } 
D/UsbSettingsManager(2733): deviceAttached, call to resolveActivity started, Intent { act=android.hardware.usb.action.USB_DEVICE_ATTACHED flg=0x10000000 (has extras) } 
D/UsbSettingsManager(2733): resolveActivity : matches count = 1, defaultPackage = com.realart.Beatmaker 
D/UsbSettingsManager(2733): resolveActivity : defaultRI = ResolveInfo{42458358 com.realart.Beatmaker/.UnityPlayerNativeActivity m=0x108000} 
D/UsbSettingsManager(2733): grantDevicePermission: UsbDevice[mName=/dev/bus/usb/002/081,mVendorId=9025,mProductId=61,mClass=2,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.hardware.usb.UsbInterface;@4259eeb8] for 10212 
D/UsbSettingsManager(2733): grantDevicePermission: mDevicePermissionMap put UsbDevice[mName=/dev/bus/usb/002/081,mVendorId=9025,mProductId=61,mClass=2,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.hardware.usb.UsbInterface;@4259eeb8] for {} 
D/UsbSettingsManager(2733): resolveActivity : permissionsGranted to ResolveInfo{42458358 com.realart.Beatmaker/.UnityPlayerNativeActivity m=0x108000} 
D/UsbSettingsManager(2733): deviceAttached, call to resolveActivity ended, Intent { act=android.hardware.usb.action.USB_DEVICE_ATTACHED flg=0x10000000 cmp=com.realart.Beatmaker/.UnityPlayerNativeActivity (has extras) } 
D/UsbHostManager(2733): onUEvent(device) :: action = add, devtype = usb_interface, device = null, product = 2341/3d/1, type = 2/0/0, interface = 2/2/1, devpath = /devices/platform/exynos-dwc3.0/exynos-xhci.0/usb2/2-1/2-1:1.0 
D/UsbHostManager(2733): onUEvent(device) :: action = add, devtype = usb_interface, device = null, product = 2341/3d/1, type = 2/0/0, interface = 10/0/0, devpath = /devices/platform/exynos-dwc3.0/exynos-xhci.0/usb2/2-1/2-1:1.1 
D/Unity (31983): Device name: /dev/bus/usb/002/081 
D/Unity (31983): Vender id: 9025 
D/Unity (31983): Product id: 61 
D/Unity (31983): Class: class android.hardware.usb.UsbDevice 
D/Unity (31983): Sub-class: 0 
D/Unity (31983): Protocol: 0 
D/Unity (31983): Num Interfaces: 2 
D/Unity (31983): Device hash: 263427241 
D/Arduino (31983): USB Interface claimed: true 
D/Arduino (31983): Data Transfter setup 
D/Arduino (31983): Line state control frame: OK return: 0 
D/Arduino (31983): Line encoding control frame: OK return: 7 
D/Arduino (31983): I/O Enpoints found 
D/Arduino (31983): Arduino bus initialized 
D/UsbSettingsManager(2733): checkPermission: /dev/bus/usb/002/081 
D/UsbSettingsManager(2733): hasPermission++ 
D/UsbSettingsManager(2733): hasPermission: UsbDevice[mName=/dev/bus/usb/002/081,mVendorId=9025,mProductId=61,mClass=2,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.hardware.usb.UsbInterface;@4259eeb8]for {10212=true} 
D/Arduino (31983): Receiver thread started 
D/Unity (31983): onArduinoReady 
D/Arduino (31983): resetArduino 
V/Unity (31983): sending message to unity = reset 
V/Unity (31983): sending message to unity = onArduinoReady 

이 장치가 연결하고, onNewIntent 방법은 권한 거부 블록이 공격 할 때마다 공격하지만, 권한을 묻는 프롬프트가 표시되지 않습니다.

이 태블릿에서이 동작이 이상한 이유가 누구에게 있습니까?

모델 : SM-T800

안드로이드 버전 : 4.4.2

커널 버전 : 3.4.39-2010469

빌드 번호 : 경우 사람에 KOT49H.T800XXU1ANFB

답변

0

같은 문제로이 안타,의 메인 섹션 응용 프로그램은 Unity와 함께 만들어졌으며 의도에 반응 한 스폰 된 스레드와 UsbInterfac을 잡는 Unity 간의 경쟁 조건이었습니다 이자형. 부팅시 Unity가 아직 초기화되지 않았기 때문에 생성 된 스레드는 99 %의 인터페이스를 캡처 할 수 있었지만 Unity가 이미 생성 된 후 JNI를 통한 Untiy이 인터페이스를 먼저 요구할 수있었습니다. 왜이 태블릿의 센서라고 주장했는지 모르겠지만 다른 것들은 아니지만 아마도 Exynos 5 Octa 5420 칩셋과 관련이 있으며 유니티 (Unity)가 센서라고 결정하는 방식과 관련이있을 것입니다.