Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to communicate with a USB device?

Tags:

android

usb

I am trying to establish USB communication as host. I am following the examples here http://developer.android.com/guide/topics/usb/host.html but I cannot get this working. Here is my 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);

    }

I get the Force Close dialog when I uncomment the line mUsbManager.requestPermission(device, mPermissionIntent); If I comment it, I don't get the force close but it doesnt work. I think the problem is in:

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

On Google's example it is as:

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

But I dont know what exactly I have to put there and i could not find any explanation about that. What i have to put there or where is my error ? Here is the LogCat i am getting when i start my 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'

Thanks you :)

like image 287
Andres Avatar asked Apr 17 '12 01:04

Andres


2 Answers

That string is just a marker so you recognize the intent that is returned when you call registerReceiver(mUsbReceiver, filter);. That isn't the problem.

I think the problem is here:

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

This line is supposed to get you your USB Manager, but as far as I recall not all phones have to support the Android USB Accessory API. This line is probably just assigning null to mUsbManager which then causes you NullPointerException when you call a method on it further down in the code. Trying checking if that isn't null before making a call on it.

For more info, checkout these links:

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

EDIT:

I think I see what the issue is now. You're right, it's not the USB Manager. It's the UsbDevice object (device). It is never initialized anywhere in your code. In this line :

mUsbManager.requestPermission(device, mPermissionIntent);

you're basically firing off an intent to ask the user if it's okay for you to work with the device represented by the UsbDevice object device. However when this call gets fired device has not yet been initialized (and therefore has the default value of null). So when you try to request permission you end up getting a NullPointerException instead of the expected result. To fix this you need to figure out which device you want to connect to and assign it to device. Look in here, under "Enumerating devices" to figure out different ways to do that. One way, if you know the name of the device you want to connect to, is to make the following calls after you retrieve the Usb Manager:

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

(Obviously, you would replace <deviceName> with the actual name of the device.

like image 72
chandsie Avatar answered Sep 28 '22 18:09

chandsie


minSdkVersion must >= 12

To enable USB host API support you should add a file named android.hardware.usb.host.xml and containing the following lines:

<permissions>
 <feature name="android.hardware.usb.host"/>
like image 44
dajun Avatar answered Sep 28 '22 17:09

dajun