17 votes

Comment communiquer avec un périphérique USB ?

J'essaie d'établir une communication USB en tant qu'hôte. Je suis les exemples suivants http://developer.Android.com/guide/topics/usb/host.html mais je n'arrive pas à le faire fonctionner. Voici mon code :

private static final String ACTION_USB_PERMISSION = "com.multitools.andres.LCView";
    UsbDevice device;
    //Pide permisos al usuario para comunicacion con el dispositivo USB
    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        if(device != null){
                            //call method to set up device communication
                        }
                    } 
                    else {
                        Log.d(TAG, "permission denied for device " + device);
                    }
                }
            }
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(DEBUG) Log.i(TAG, "onCreate() -> MainMenu");

        actionBar = getActionBar();                     //obtengo el ActionBar
        actionBar.setDisplayHomeAsUpEnabled(true);      //el icono de la aplicacion funciona como boton HOME
        //Menu
        setListAdapter(new ArrayAdapter<String>(MainMenu.this, android.R.layout.simple_list_item_1, MenuNames));

        //USB
        if(DEBUG) Log.i(TAG, "Setting UsbManager -> MainMenu");
        UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        PendingIntent mPermissionIntent;

        if(DEBUG) Log.i(TAG, "Setting PermissionIntent -> MainMenu");
        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
        if(DEBUG) Log.i(TAG, "Setting IntentFilter -> MainMenu");
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        if(DEBUG) Log.i(TAG, "Setting registerReceiver -> MainMenu");
        registerReceiver(mUsbReceiver, filter);
        if(DEBUG) Log.i(TAG, "Setting requestPermission -> MainMenu");
        mUsbManager.requestPermission(device, mPermissionIntent);

    }

J'obtiens la boîte de dialogue "Forcer la fermeture" lorsque je décompose la ligne mUsbManager.requestPermission(device, mPermissionIntent); Si je le commente, je n'obtiens pas la fermeture forcée, mais cela ne fonctionne pas. Je pense que le problème est dans :

private static final String ACTION_USB_PERMISSION = "com.multitools.andres.LCView";

Sur l'exemple de Google, c'est comme :

private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

Mais je ne sais pas ce que je dois y mettre exactement et je n'ai pas trouvé d'explication à ce sujet. Qu'est-ce que je dois mettre ici ou où est mon erreur ? Voici le LogCat que j'obtiens lorsque je démarre mon application :

04-17 00:57:50.944: I/dalvikvm(1362): threadid=3: reacting to signal 3
04-17 00:57:51.331: I/dalvikvm(1362): Wrote stack traces to '/data/anr/traces.txt'
04-17 00:57:51.981: I/(1362): onCreate() -> MainMenu
04-17 00:57:52.013: I/dalvikvm(1362): threadid=3: reacting to signal 3
04-17 00:57:52.151: I/dalvikvm(1362): Wrote stack traces to '/data/anr/traces.txt'
04-17 00:57:52.570: I/dalvikvm(1362): threadid=3: reacting to signal 3
04-17 00:57:52.731: I/dalvikvm(1362): Wrote stack traces to '/data/anr/traces.txt'
04-17 00:57:53.122: I/dalvikvm(1362): threadid=3: reacting to signal 3
04-17 00:57:53.231: I/dalvikvm(1362): Wrote stack traces to '/data/anr/traces.txt'
04-17 00:57:53.390: I/(1362): Setting UsbManager -> MainMenu
04-17 00:57:53.451: I/(1362): Setting PermissionIntent -> MainMenu
04-17 00:57:53.470: I/(1362): Setting IntentFilter -> MainMenu
04-17 00:57:53.470: I/(1362): Setting registerReceiver -> MainMenu
04-17 00:57:53.511: I/(1362): Setting requestPermission -> MainMenu
04-17 00:57:53.660: I/dalvikvm(1362): threadid=3: reacting to signal 3
04-17 00:57:53.791: I/dalvikvm(1362): Wrote stack traces to '/data/anr/traces.txt'
04-17 00:57:54.311: I/dalvikvm(1362): threadid=3: reacting to signal 3
04-17 00:57:54.401: I/dalvikvm(1362): Wrote stack traces to '/data/anr/traces.txt'
04-17 00:57:54.531: I/(1362): onCreateOptionsMenu() -> MainMenu
04-17 00:57:54.683: I/dalvikvm(1362): threadid=3: reacting to signal 3
04-17 00:57:54.772: I/dalvikvm(1362): Wrote stack traces to '/data/anr/traces.txt'
04-17 00:57:55.186: I/dalvikvm(1362): threadid=3: reacting to signal 3
04-17 00:57:55.291: I/dalvikvm(1362): Wrote stack traces to '/data/anr/traces.txt'
04-17 00:57:55.661: I/dalvikvm(1362): threadid=3: reacting to signal 3
04-17 00:57:55.751: I/dalvikvm(1362): Wrote stack traces to '/data/anr/traces.txt'
04-17 00:57:55.791: D/gralloc_goldfish(1362): Emulator without GPU emulation detected.
04-17 01:11:47.323: I/dalvikvm(1459): threadid=3: reacting to signal 3
04-17 01:11:47.720: I/dalvikvm(1459): Wrote stack traces to '/data/anr/traces.txt'
04-17 01:11:48.124: I/dalvikvm(1459): threadid=3: reacting to signal 3
04-17 01:11:48.291: I/dalvikvm(1459): Wrote stack traces to '/data/anr/traces.txt'
04-17 01:11:48.452: I/(1459): onCreate() -> MainMenu
04-17 01:11:48.691: I/dalvikvm(1459): threadid=3: reacting to signal 3
04-17 01:11:48.813: I/dalvikvm(1459): Wrote stack traces to '/data/anr/traces.txt'
04-17 01:11:49.172: I/dalvikvm(1459): threadid=3: reacting to signal 3
04-17 01:11:49.321: I/dalvikvm(1459): Wrote stack traces to '/data/anr/traces.txt'
04-17 01:11:49.653: I/dalvikvm(1459): threadid=3: reacting to signal 3
04-17 01:11:49.821: I/dalvikvm(1459): Wrote stack traces to '/data/anr/traces.txt'
04-17 01:11:49.901: I/(1459): Setting UsbManager -> MainMenu
04-17 01:11:49.931: I/(1459): Setting PermissionIntent -> MainMenu
04-17 01:11:50.021: I/(1459): Setting IntentFilter -> MainMenu
04-17 01:11:50.031: I/(1459): Setting registerReceiver -> MainMenu
04-17 01:11:50.051: I/(1459): Setting requestPermission -> MainMenu
04-17 01:11:50.071: D/AndroidRuntime(1459): Shutting down VM
04-17 01:11:50.133: W/dalvikvm(1459): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
04-17 01:11:50.231: I/dalvikvm(1459): threadid=3: reacting to signal 3
04-17 01:11:50.331: I/dalvikvm(1459): Wrote stack traces to '/data/anr/traces.txt'
04-17 01:11:50.401: E/AndroidRuntime(1459): FATAL EXCEPTION: main
04-17 01:11:50.401: E/AndroidRuntime(1459): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.multitools.andres/com.multitools.andres.MainMenu}: java.lang.NullPointerException
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.app.ActivityThread.access$600(ActivityThread.java:123)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.os.Looper.loop(Looper.java:137)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.app.ActivityThread.main(ActivityThread.java:4424)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at java.lang.reflect.Method.invokeNative(Native Method)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at java.lang.reflect.Method.invoke(Method.java:511)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at dalvik.system.NativeStart.main(Native Method)
04-17 01:11:50.401: E/AndroidRuntime(1459): Caused by: java.lang.NullPointerException
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.os.Parcel.readException(Parcel.java:1333)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.os.Parcel.readException(Parcel.java:1281)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.hardware.usb.IUsbManager$Stub$Proxy.requestDevicePermission(IUsbManager.java:535)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.hardware.usb.UsbManager.requestPermission(UsbManager.java:361)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at com.multitools.andres.MainMenu.onCreate(MainMenu.java:80)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.app.Activity.performCreate(Activity.java:4465)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
04-17 01:11:50.401: E/AndroidRuntime(1459):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
04-17 01:11:50.401: E/AndroidRuntime(1459):     ... 11 more
04-17 01:11:50.751: I/dalvikvm(1459): threadid=3: reacting to signal 3
04-17 01:11:50.851: I/dalvikvm(1459): Wrote stack traces to '/data/anr/traces.txt'
04-17 01:11:51.331: I/dalvikvm(1459): threadid=3: reacting to signal 3
04-17 01:11:51.403: I/dalvikvm(1459): Wrote stack traces to '/data/anr/traces.txt'
04-17 01:11:51.774: I/dalvikvm(1459): threadid=3: reacting to signal 3
04-17 01:11:51.961: I/dalvikvm(1459): Wrote stack traces to '/data/anr/traces.txt'

Merci à vous :)

20voto

chandsie Points 1003

Cette chaîne n'est qu'un marqueur qui vous permet de reconnaître l'intention renvoyée lorsque vous appelez registerReceiver(mUsbReceiver, filter); . Le problème n'est pas là.

Je pense que le problème est là :

UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

Cette ligne est censée vous permettre d'obtenir votre gestionnaire USB, mais si je me souviens bien, tous les téléphones ne doivent pas prendre en charge l'API des accessoires USB d'Android. Cette ligne ne fait probablement qu'assigner null a mUsbManager ce qui vous amène à NullPointerException lorsque vous appelez une méthode plus loin dans le code. En essayant de vérifier si ce n'est pas null avant de passer un appel.

Pour plus d'informations, consultez ces liens :

  1. http://developer.Android.com/guide/topics/usb/index.html
  2. http://developer.Android.com/guide/topics/usb/accessory.html

EDIT :

Je crois que je vois maintenant où est le problème. Vous avez raison, ce n'est pas le gestionnaire USB. C'est l'objet UsbDevice ( device ). Il n'est jamais initialisé dans votre code. Dans cette ligne :

mUsbManager.requestPermission(device, mPermissionIntent);

vous lancez une intention pour demander à l'utilisateur s'il est d'accord pour que vous travailliez avec le périphérique représenté par l'objet UsbDevice device . Cependant, lorsque cet appel est lancé device n'a pas encore été initialisé (et a donc la valeur par défaut de null ). Ainsi, lorsque vous essayez de demander une autorisation, vous obtenez un message de type NullPointerException au lieu du résultat attendu. Pour résoudre ce problème, vous devez déterminer le périphérique auquel vous souhaitez vous connecter et l'assigner à device . Regarder dans aquí sous "Enumerating devices" pour découvrir les différentes manières de procéder. Une façon, si vous connaissez le nom du périphérique auquel vous voulez vous connecter, est de faire les appels suivants après avoir récupéré l'Usb Manager :

HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
device = deviceList.get("<deviceName>");

(Il est évident que vous remplaceriez <deviceName> avec le nom réel de l'appareil.

3voto

dajun Points 31

minSdkVersion doit >= 12

Pour activer la prise en charge de l'API hôte USB, vous devez ajouter un fichier nommé Android.hardware.usb.host.xml et contenant les lignes suivantes :

<permissions>
 <feature name="android.hardware.usb.host"/>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X