Saturday, 7 September 2013

VirtualBox OS X Host Ubuntu Guest - USB device captured but not mounting/showing - One workaround

Problem:

I am using VirtualBox 4.2.x on OS X 10.7.x running an Ubuntu Guest. When I try to plug in a USB device, such as a USB drive, USB MIDI keyboard such as the Keystation 88-es, etc., VirtualBox shows the device as captured (with a checkmark in the USB devices list), yet Ubuntu can't find it. I've already tried things such as installing VirtualBox Guest Additions, setting proper user permissions, etc.

One Workaround:

If you've managed to mount and capture the USB device but it's still not showing, you've probably already made it past most How-To's Googling will offer. One bug fix that seems harder to come across is this: Set the number of virtual CPUs to 1.

Apparently after VirtualBox version 3.2.0, a bug has caused USB devices to not show up in some Linux-based guests when the number of virtual CPUs is set to more than 1.

If this obscure bug fix doesn't help, check out the references below to lots of other potential solutions to the USB-won't-mount problem.

Good luck!

Notes:

I realize that this post isn't complete, however it was this one somewhat obscure bug that caused many hours of attempted debugging and Googling until it was found. So to save others the trouble of finding it buried in a page full of instructions and fixes, I opted to highlight only this one bug, and link to other pages full of good solutions.

Hopefully by the time you've reached this blog page Oracle, VirtualBox, Apple, or some others have managed to fix the problem!

This workaround is version specific so your mileage may vary depending on the version of OS X, VirtualBox, VirtualBox Guest Additions, Linux, etc., that you are running.

References:

Friday, 6 September 2013

Facebook Android SDK v3.5 tutorial workaround for error regarding android.support.v4.content.LocalBroadcastManager.getInstance

Problem:

In the very first Facebook SDK tutorial, when I finish the final steps to get a MainActivity.java that looks like the tutorial, instead of getting the message "Hello !" the app crashes and gives an error like "Could not find method android.support.v4.content.LocalBroadcastManager.getInstance, referenced from method com.facebook.Session.postActiveSessionAction", then followed by a bunch of exceptions, starting with "java.lang.NoClassDefFoundError: android.support.v4.content.LocalBroadcastManager".

My code looks exactly like the tutorial found at https://developers.facebook.com/docs/android/getting-started/facebook-sdk-for-android/. (For reference, the tutorial code as of September 6, 2013 is below, as it could be revised by now:)

package com.firstandroidapp;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.widget.TextView;
import com.facebook.*;
import com.facebook.model.*;

public class MainActivity extends Activity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // start Facebook Login
    Session.openActiveSession(this, true, new Session.StatusCallback() {

      // callback when session changes state
      @Override
      public void call(Session session, SessionState state, Exception exception) {
        if (session.isOpened()) {

          // make request to the /me API
          Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {

            // callback after Graph API response with user object
            @Override
            public void onCompleted(GraphUser user, Response response) {
              if (user != null) {
                TextView welcome = (TextView) findViewById(R.id.welcome);
                welcome.setText("Hello " + user.getName() + "!");
              }
            }
          });
        }
      }
    });
  }

  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
  }

}

Please Note First:

This problem and its workaround appears to be version specific. Your mileage may vary if the error isn't exactly the same as the one encountered. The versions of things used when this error was encountered were Android ADT v22, facebook-android-SDK-3.5, with a build target set to Android 4.2.2. All source code, tool, etc., were unmodified from the versions downloaded from Google and Facebook. This problem was worked around September 6, 2013, so hopefully someone from Facebook or Google's Android team has already made the appropriate fixes (making this post no longer needed =p).

Workaround:

This problem is caused by a missing method that the Facebook SDK is expecting to find in android.support.v4, but cannot find in the current version of the Android libraries. A hint to this is a strange error (which you may or may not have seen when importing the Facebook SDK demos into Eclipse) mentions that the versions of android.support.v4 do not match. The demos seem to run properly when compiled, however the very first Facebook SDK program you write yourself does not.

To work around this problem, the Facebook SDK version 3.5 includes a jar file you need to link to your project, located in "/path/to/facebook-android-sdk-3.5/libs/android-support-v4.jar".

One way to do this is as follows:

  • Go to your project's properties in Eclipse, then go to "Java Build Path"
  • Click on the "Libraries" tab
  • Click on either "Add JARs..." or "Add External JARs...", depending on which of the two you'd like to do
  • Add the android-support-v4.jar that comes with the Facebook Android SDK v3.5
  • Click on the "Order and Export" tab
  • Check the newly-imported android-support-v4.jar
  • Clean the project (Project->Clean...) (this step is important as attempting to re-run the project without cleaning it first or altering its code will simply run the existing binary again, which will give the error once more)

Additional Notes:

There's also another change in the tutorial which you may want to make. The function "Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {....});" is deprecated in the v3.5 SDK. You can get rid of the "deprecated method" warning in Eclipse by changing the above code to "Request.newMeRequest(session, new Request.GraphUserCallback() {...}).executeAsync();".

Hopefully this post helped someone out there. I realize it's a pretty basic problem to debug for experienced coders, but I decided to post this anyway in case it came in handy.