2015-06-04 12 views
19

Sto cercando di ottenere un dispositivo USB per la connessione a un dispositivo Android 5.1.1. Precedentemente avevo usato libusb regolare per KitKat, ma Lollipop ha aumentato la sicurezza e questo non funziona più.libusb_open_device_with_vid_pid non riuscito durante il tentativo di accesso al dispositivo USB

Questo è ben documentato, richiede root per impostare il livello SELinux. Non voglio dover eseguire il root del dispositivo per collegare il dispositivo USB.

Dopo aver guardato in giro, mi sono imbattuto in this answer e ho provato this libusb fork, ma ora sto ottenendo un nuovo errore

libusb_open_device_with_vid_pid (29c2) failed. 
Failed to setup USB 
usb_setup: -1 

Non ho cambiato alcun codice, solo la libreria.

Si tratta ancora di un problema di autorizzazione o c'è qualcosa che mi manca che farà funzionare?

risposta

14

I seguenti passaggi possono essere utilizzati per risolvere i problemi citati.

Il processo di montaggio del dispositivo come memoria di massa USB è incoerente su dispositivi diversi e specifici del produttore. Alcuni dispositivi come il Nexus S offrono "Attiva memoria USB" quando colleghi il dispositivo al desktop tramite cavo USB. Altri dispositivi come il Galaxy S3 richiedono ora un'app per avviare il dispositivo come memoria di massa. In entrambi i casi, i dispositivi Android in genere offrono tale funzionalità e dovrai creare un file che corrisponda alle specifiche del produttore del dispositivo.

è necessario aggiungere al file manifesto dell'applicazione prima di lavorare con le API host USB:

  • Poiché non tutti i dispositivi basati su Android sono garantiti per supportare le API host USB, includono un elemento che dichiara che il vostro l'applicazione utilizza la caratteristica android.hardware.usb.host.
  • Se si desidera che l'applicazione venga avvisata di un dispositivo USB collegato, specificare una coppia di elementi per l'intento android.hardware.usb.action.USB_DEVICE_ATTACHED nell'attività principale.

Add USB_DEVICE_ATTACHED al file manisfest:

<manifest ...> 
    <uses-feature android:name="android.hardware.usb.host" /> 
    <uses-sdk android:minSdkVersion="12" /> 
    ... 
    <application> 
     <activity ...> 
      ... 
      <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> 

per aiutare il vostro APP scoprire un particolare dispositivo USB è possibile utilizzare il filtro intento:

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

È inoltre necessario specificare il vostro dispositivo e ID venditore:

<?xml version="1.0" encoding="utf-8"?> 

<resources> 
    <usb-device vendor-id="1234" product-id="5678" /> 
</resources> 

Questa risposta Potrebbe essere sufficiente per gestire la tua connessione USB host.Ora chiamare USB:

int LIBUSB_CALL libusb_open2(libusb_device *dev, libusb_device_handle **handle, int fd); 

Utilizzare il descrittore per aprire il collegamento alla usb device - ad esempio:

UsbManager myUsbManager = (UsbManager) 
getSystemService(Context.USB_SERVICE); 
UsbAccessory myUsbAccessory = (myUsbManager.getAccessoryList())[0]; 
ParcelFileDescriptor pfd = myUsbManager.openAccessory(myUsbAccessory); 
FileDescriptor fileDescriptor = pfd.getFileDescriptor(); 
FileInputStream myFileInputStream = new FileInputStream(fileDescriptor); 
FileOutputStream myFileOutputStream = new FileOutputStream(fileDescriptor); 

Se avete ancora problemi con il livello SELinux, qui si hanno alcune modifiche che è possibile utilizzare per rendere il vostro programma di eseguire senza problemi:

// default.prop 
ro.secure=1    -----------------> ro.secure=0 
ro.adb.secure=1  -----------------> ro.adb.secure=0 

//init.rc 
setsebool debugfs 1 --------> setsebool debugfs 0 
setenforce 0 
setprop selinux.reload_policy 1 -------> setprop selinux.reload_policy 0 

// init.target.rc 
setprop selinux.reload_policy 1 -----> setprop selinux.reload_policy 0 

Come SELinux è di default impostato per far rispettare la massima sicurezza, e si desidera concedere un accesso client al tuo devi Android ce tramite USB.

enter image description here

A seconda della marca e il modello Android, provare a scollegare il cavo USB che collega il dispositivo e il desktop, e ricollegarlo a. Si dovrebbe essere richiesto di "Turn on USB" stoccaggio. In tal caso, andare avanti e provare a cercare su Impostazioni → Altro ... su Android e cercare un'opzione di archiviazione di massa USB.

http://www.pocketables.com/images/old/6a00d83451c9ec69e201675f40c44a970b-500wi.png

alternativa cercano il processo di archiviazione di massa USB consigliato dal produttore del dispositivo. Quando attivi la memoria USB, il dispositivo ti informa che alcune app si interromperanno, proseguiranno e OK. Ora spostati sul tuo computer desktop e cerca il tuo supporto di archiviazione di massa USB, spesso chiamato NO NAME se non lo hai rinominato. Fai clic sul tuo dispositivo di archiviazione di massa e, proprio lì nella cartella del piede, trova un file chiamato data.tsv.

enter image description here

È possibile anche controllare data.tsv aprendolo in un editor di testo. Troverai due colonne ben separate da una tabulazione; in ogni riga, troverai una coppia di valori interi. Questo è perfettamente sufficiente per il nostro progetto. I progetti di dati più complessi richiedono in genere un identificatore univoco per ogni riga, una riga in una tabella per puntare a un record specifico in un'altra.

enter image description here

Secondo il vostro development environment, si hanno anche per regolare le impostazioni di conseguenza. Se stai sviluppando su Windows, segui l'installazione del driver USB instructions available. Se stai sviluppando su Linux, segui le istruzioni per il setting up dispositivo per lo sviluppo.

enter image description here

Inoltre, è anche la pena di ricordare che molti dispositivi Android rilasciati in precedenza sono solo in grado di agire come un dispositivo USB e non possono avviare connessioni con i dispositivi esterni USB. Il supporto Android Open Accessory (AOA) supera questa limitazione e consente di creare accessori che possono interagire con un assortimento di dispositivi Android consentendo all'accessorio di avviare lo connection. Un esempio di utilizzo comune di Android Open Accessory si può trovare nel progetto: registrazione e riproduzione audio usando USB host mode - che ovviamente richiede la modalità USB per essere attivo e funzionante.

enter image description here

Mettere Android per comunicare attraverso USB con Arduino microcontroller è anche un tipo di implementazione che ha mostrato a diventare un grande successo più di recente, in quanto consente di estendere le vostre capacità Android integra funzionalità aggiuntive attraverso un multi-dispositivo approccio alla soluzione. Un tipico Arduino Sketch per consentire la comunicazione con il dispositivo USB Android sarebbe simile a questa:

// the USB Host libraries 
#include <Max3421e.h> 
#include <Usb.h> 
// the AOA library 
#include <AndroidAccessory.h> 

void setup(); 
void loop(); 

void setup() 
{ // start serial debugging 
    Serial.begin(115200); 
    Serial.print("\r\nADK has run setup()."); 
    Serial.println("Ready to start USB communication..."); 
} 

void loop() 
{ // example - read the voltage from a sensor 
    uint16_t val; 
    val = analogRead(TEMP_SENSOR); // or any sort of input 
    Serial.println(val,HEX); 
    Serial.write(val); 
    // Delay for 100 milliseconds. 
    delay(100); 
} 

Tutti i progetti Arduino devono avere un setup() e un metodo loop() ha dichiarato altrimenti l'Android non comunicare correttamente.

Ricordate anche che un elenco di requisiti minimi necessari per utilizzare AOA:

  • un dispositivo Android compatibile con AOA. Per testare la compatibilità prima di provare questo esempio, fai riferimento alla sezione "Dispositivi Android supportati" per i collegamenti alle app dimostrative AOA di Microchip disponibili su Google Play.
  • Una scheda microcontroller compatibile. L'Arduino Mega ADK sarebbe un'opzione facile se non sei sicuro.

enter image description here

Possibilità di dispositivi Android tramite USB sono sorprendenti, e la domanda di applicazioni innovative che sono in grado di sfruttare appieno tali caratteristiche è destinato ad aumentare notevolmente.

+1

Funziona per 'UsbDevice' e' UsbAccessory'? –

+0

Sì, funziona. Ma per UsbAccessry devi usare l'intento USB_ACCESSORY_ATTACHED. – Avanz

1

vostro errore non è correlato alle autorizzazioni è legato alla I/O, l'errore -1 è equivalente a

LIBUSB_ERROR_IO - Input/output error. 

È possibile modifiy il JNI interface di mettere libusb in modalità debug chiamare libusb_set_debug(), penso che sia il unico modo per sapere cosa sta realmente accadendo.

In ogni caso, prima controllare VID/PID per assicurarsi che sia presente nell'elenco dei dispositivi collegati.

0

Su Android, non è possibile utilizzare libusb_open_device_with_vid_pid senza root. Per accedere a un dispositivo USB, è necessario utilizzare l'API Android di UsbDeviceManager.

L'unico esempio che conosco di codice sorgente pubblico che collega libusb per Android senza radice è: https://github.com/martinmarinov/rtl_tcp_andro-/

Non si potrà mai ottenere l'accesso in lettura/scrittura a/dev/bus/usb/xxx/yyy. Il modo in cui lo fa Android è un servizio di sistema che ti invia, tramite binder, un descrittore di file già aperto sul dispositivo/dev/bus/usb/xxx/yyy specifico che hai richiesto.

Ci sono già molte documentazioni su come gestire UsbHost da java in Android, quindi rimanderò a ciò che è rimasto dopo.

  • Hai bisogno di un libusb rattoppata (quello in rtl_tcp_andro- farà), che può prendere un filedescriptor invece di un nome di dispositivo/pid/vid
  • È necessario chiamare libusb_open2 (è così che questa nuova funzione con fd è chiamato a libusb di rtl_tcp_andro) con la fd potrai recuperare con UsbDeviceConnection.getFileDescriptor()

Edit: sto vedendo rtl_tcp_andro- anche aggiunto un libusb_init2, io sono non capisco perché bancomat, ma il commit dice che è per il supporto L, quindi immagino sia anche necessario.

0

quella patch usb menzionato in questione opera nel prossimo modo:

  1. è necessario aprire dispositivo UsbManager
  2. aperta da libusb
  3. vicinanze libusb
  4. vicinanze UsbManager

esattamente quell'ordine funzionerà.