Archive for the ‘Android ADK’ Category

Android ADK Background Service

Posted by Erin, the RobotGrrl on Tuesday, November 29th, 2011

I was playing around with the ADK and wondering how it would be possible to make the connection work while the app was in the background. The first way I tried was to not close the connection in onPause(). This worked, since the file input and output streams were able to continue … until they were garbage collected. When other Android apps run in the background, they use a Service. I tried this out with the ADK, and it works! Check out the video demonstration below.



Watch video on YouTube

The initialization and opening of the ADK is still done in the main activity. We use the Application class as a friendly singleton to transfer the streams, file descriptor, and usb accessory over to the Service.

  1. private void enableControls(boolean b) {
  2.         ((ServiceADKApplication) getApplication()).setInputStream(mInputStream);
  3.         ((ServiceADKApplication) getApplication()).setOutputStream(mOutputStream);
  4.         ((ServiceADKApplication) getApplication()).setFileDescriptor(mFileDescriptor);
  5.         ((ServiceADKApplication) getApplication()).setUsbAccessory(mAccessory);
  6.         // … snip …
  7. }

Creating the Service is rather straight forward. In ServiceADKActivity:

onCreate()

  1. startService(new Intent(this, ADKService.class));

onPause()

  1. try {
  2.         ADKService.self.startUpdater();
  3. } catch(Exception e) {
  4.         Log.d(TAG, "Starting the updater failed");
  5. }

onResume()

  1. try {
  2.         ADKService.self.stopUpdater();
  3. } catch(Exception e) {
  4.         Log.d(TAG, "Stopping the updater failed");
  5. }

When the Service is started, it creates an Updater thread, which runs every second.

  1. if (!updater.isRunning()) {
  2.         Log.d(TAG, "updater not running");
  3.         updater = new Updater();
  4.         updater.start();
  5. } else {
  6.         Log.d(TAG, "updater running");
  7. }

In background, this can run for a very long time. I let it be for 12 hours before I stopped it.

However… there is a very bizarre bug. Sometimes when the app returns to foreground, it can’t reconnect to the ADK. The main problem is with the USB Manager trying to open the accessory for some reason. The app has permissions to the accessory, and it prints out the connected accessory correctly. Here is my trace of the bug:

  1. @Override
  2.         public void onResume() {
  3.        
  4.         Log.v(TAG, "onResume");
  5.  
  6. // —- onResume is called —-
  7.        
  8.                 super.onResume();
  9.                
  10.                 try {
  11.                         ADKService.self.stopUpdater();
  12.                 } catch(Exception e) {
  13.                         Log.d(TAG, "Stopping the updater failed");
  14.                 }
  15.                
  16. // —- updater is indeed stopped —-
  17.  
  18.                 Intent intent = getIntent();
  19.                
  20.                 if (mInputStream != null && mOutputStream != null) {
  21.                         Log.v(TAG, "input and output stream weren’t null!");
  22.                         enableControls(true);
  23.                         return;
  24.                 }
  25.  
  26. // —- the file i&o streams are null —-
  27.                
  28.                 UsbAccessory[] accessories = mUsbManager.getAccessoryList();
  29.                
  30.                 Log.v(TAG, "all the accessories: " + accessories);
  31.  
  32. // —- shows the connected accessory —-
  33.                
  34.                 UsbAccessory accessory = (accessories == null ? null : accessories[0]);
  35.                 if (accessory != null) {
  36.                         if (mUsbManager.hasPermission(accessory)) {
  37.  
  38. // —- there is permission, going to open the accessory —-
  39.  
  40.                                 Log.v(TAG, "mUsbManager does have permission");
  41.                                 openAccessory(accessory);
  42.                         } else {
  43.                                 Log.v(TAG, "mUsbManager did not have permission");
  44.                                 synchronized (mUsbReceiver) {
  45.                                         if (!mPermissionRequestPending) {
  46.                                                 mUsbManager.requestPermission(accessory,
  47.                                                                 mPermissionIntent);
  48.                                                 mPermissionRequestPending = true;
  49.                                         }
  50.                                 }
  51.                         }
  52.                 } else {
  53.                         Log.d(TAG, "mAccessory is null");
  54.                 }
  55.                
  56.                
  57.         }
  58.  
  59.  
  60. private void openAccessory(UsbAccessory accessory) {
  61.                
  62.                 Log.e(TAG, "openAccessory: " + accessory);
  63.                
  64.                 Log.d(TAG, "this is mUsbManager: " + mUsbManager);
  65.                
  66. // —- prints out the address of usb manager fine —-
  67.  
  68.                 mFileDescriptor = mUsbManager.openAccessory(accessory);
  69.                
  70. // —- Error in log from UsbService: E/UsbService( 110): could not open /dev/usb_accessory
  71.  
  72.                 Log.d(TAG, "Tried to open");
  73.                
  74.                 if (mFileDescriptor != null) {
  75.                         mAccessory = accessory;
  76.                         FileDescriptor fd = mFileDescriptor.getFileDescriptor();
  77.                         mInputStream = new FileInputStream(fd);
  78.                         mOutputStream = new FileOutputStream(fd);
  79.                         mThread = new Thread(null, this, "DemoKit"); // meep
  80.                         mThread.start(); // meep
  81.                         Log.d(TAG, "accessory opened");
  82.                         enableControls(true);
  83.                 } else {
  84.                         Log.d(TAG, "accessory open fail");
  85.                         enableControls(false);
  86.                 }
  87. }

Does anyone know why this may be? I have tried to work around it numerous times but to no luck yet.

You can grab the code off of my GitHub to play around and test it.

It would be great if we could fix this bug!

Posted in: Android ADK.

Learning Pet – Thanks for voting!

Posted by Erin, the RobotGrrl on Friday, September 16th, 2011

Thanks everyone who voted for Learning Pet in the Open Hardware Summit Scholarship! It was much appreciated! We didn’t place in the top 3.

Here was a fantastic interview by Ian Cole, thanks so much Ian!



The future of Learning Pet is that there will be time spent on apps4arduino to make some money in order to be able to purchase some laser cut parts, 3d parts, and boards.

Here are some stats of the contest that I collected from the webpage:

- 51.9% had a prototype
- 48.1% showed a demo in their video
- 51.9% had a website
- 3.7% released their hardware files under a license for the open hardware definition
- 22.2% had their hardware files available
- 14.8% had a bom
- 5.6% released their source code under an osi license
- 22.2% had their code available
- 40.7% had documentation
- 22.2% had additional videos
- 59.3% said what they would do with the prize if they won
- 18.5% demoed while at the ohs

You can check out all the documentation for Learning Pet here:
http://robotgrrl.com/learningpet

Thanks again!

Learning Pet will be at the Maker Faire this weekend, so be sure to say hi! (or whatever hi is in robobrrd language)

Posted in: Android ADK, Projects, Robot.

Learning Pet – VOTE! (Open Hardware Summit Scholarship)

Posted by Erin, the RobotGrrl on Wednesday, September 14th, 2011

VOTE FOR LEARNING PET IN THE OPEN HARDWARE SUMMIT SCHOLARSHIP!

Introducing Learning Pet, a mini RoboBrrd with a very large theme- education! Learning Pet enriches lessons by creating a physical interface to interact with the virtual world.



We demonstrate a number sorting game, where the student interacts with the robot to blast virtual UFO’s with the lowest value. Correct answers are celebrated with a wing flap, and each level-up with a dance. We use the Accessory Development Kit to interface with mobile devices while away from the computer.



On LearningPet’s webpage, it has all the detailed information about the hardware, software and design. There is also a handy checklist at the top, so that at a glance you can quickly see the important facts.

It would be awesome if you could vote for Learning Pet in the Open Hardware Summit Scholarship! VOTE here!

Here is a YouTube playlist of all the videos!

Posted in: Android, Android ADK, Programming, Projects, RoboBrrd (thx Adafruit!), Robot.

Android ADK Robo-Wizard Project Progress

Posted by Erin, the RobotGrrl on Sunday, August 21st, 2011

Finally got an Android phone that works with the ADK!

The ADK is really pretty, except that you can’t really add on more things to it. I carefully soldered on some headers that will let me plug things in:

IMG_2764

Also added on some wires to extend the digital outs on the side. Actually, the piece of wire is from recycled e-waste!

IMG_2776

This is the app so far. Sensor readings at the top, and buttons in a circle.

IMG_2771

The buttons are used to create a spell. The more letters are in the spell, then the more magic power it has. The magic power is indicated by the LED lights in the above photo. The goal is to be able to use the phone as a magic wand, using the accelerometer, to compose the spells. To shoot the spell, you press the GO! button, or the gold Android on the ADK, or it auto-shoots when the magic power is at its highest.

I use this magic power to control RoboBrrd over the mesh network!

IMG_2779

You can see the video of it working, with an explanation of everything, on YouTube:

Isn’t it kind of crazy how there isn’t many Android ADK hacks out there yet? When I search the tag “android adk” on YouTube, there are only 157 results. Even more creepy, searching “adk” under Java on Github, there are only 11 repositories.

I’ll be making some tutorials for the Android ADK for the apps4arduino site soon! :)

Posted in: Android ADK.