Search This Blog

13 December 2011

LVL Testing

 In the beginning, my phone was setup with a Google Apps account (to cut down on the general spam).  When using the Market, it was billing my gmail account for the purchases.

A few months back, the Android Market updated itself from a tabbed list of applications to a Windows-8 combination of application links and general advertisements.  During that change, they enabled the ability to use multiple accounts with the Google Market.  Initially, I was very excited by this prospect.

Unfortunately, while applications were still being purchased with the gmail account - they were now divided into two accounts.  The old ones tied to the App account (which was not allowed to purchase anything anymore due to Google Checkout not being available to the Google Apps users) and the new ones tied to the Gmail account itself.  Why all apps weren't tied to the account that actually paid for them, I have no idea.  I contacted Google about this issue and they suggested that I contact all 184 old application developers and ask them politely to change the email address associated with my purchase.  As an app developer that has no idea how to do this myself, I wasn't about to do that.

Enough back story... onto the issue at hand... the Android Market Licensing...

If you have ever published "Copy Protected" apps in Android, you know that Google started suggesting (with bright red warnings) that you switch to the new LVL approach as the old one was going to go away.  Ok, that makes sense.  I look through the docs (which are a little overwhelming considering what is actually happening) and decided that the best thing I could do is try the sample LVL application first - then worry about securing it after I had it working.

Grabbing the LVL library and sample code from the SDK, I build it and test it.  Results were not very good.  Here are some things I ran into:
  • Sometimes it said it was not compatible with my Atrix... then randomly decided to start saying it was compatible.
  • When publishing an updated version, both the device and the emulator reported (for about 10 minutes) that licensing was not managed by the market.
  • When on a device tied to multiple accounts, it only counted as licensed if the primary account (first one used on the phone) is the one that bought the application.
  • If you want to delete the primary account so you can change the order, you have to factory reset the device.
  • Oh, and of course, it can't be used on Free applications - which leads to lots of Market entries for demos and keys and trials.
So what to do?  Google says we have to quit using the copy protection scheme. Using LVL will break hundreds if not thousands of my users.  Doesn't sound like there are many options, does it?

11 December 2011

Publishing for GoogleTV

Yesterday I received the 3.1 update to my Logitech Revue box.  Definitely better than it was, if for no other reason than the Market is finally there.  So what's a developer to do besides install their own apps?

Unfortunately, FetLife wasn't available in the Market.  Luckily, I had already expected that.  I head over to the migrating page and try to figure out what all I need to change.

Turns out, the only thing I had to do for it to show up in the Market (for GoogleTV) was add this one line to my manifest.

    <uses-feature android:name="android.hardware.touchscreen" android:required="false">*lt;/uses-feature>

This effectively makes the market quit filtering it out.  After republishing, I go back to my GoogleTV and check the Market.  Yep, there it is. (Note: the Market DOES allow multiple user accounts, so if you are using an account other than the one you purchased the app with; you have to add that account as well, or repurchase).

Now, at first, while it showed up, it said it was incompatible.  I looked around online for a bit, then found this excellent resource on how to use ADB with my GoogleTV.  You can walk through the article, but the jist of it is:

  1. Tell GoogleTV that your dev box is going to be the debugging IP
  2. adb connect googletv-ip-address
  3. adb devices/logcat/etc
So, I fire up logcat, relaunch the Market and... oh, it will let me install it now.  It appears that it just takes a little while (15 minutes?) before the Market has analyzed it?

Anyways, app published and installed on the big screen.  Now to disable things like camera and vibrate and....

24 August 2011

IntelliJ IDEA and the Android Source tree

It can be quite annoying to develop in the Android source tree if you don't have your IDE properly configured.  I thought I'd share a few notes from my testing IDEA with the repo sync'd tree...

  • When initially making your project, make sure it is a fresh checkout or do a 'make clean'.  Otherwise, all the *_intermediates turn into separate modules.

  • When it auto-detects the Android Facets, uncheck them all. If the Android Facet is setup, you will resolve classes to android-x.jar instead of your module source.
    • It can also auto-generate gen/ directories which cause duplicate clases during builds if the Android Facet is chosen.

  • Since we are not using the Android Facets, the files become a problem.  To correct this, create a new module (and make it a dependency of any module needing the resolution):
Content Root: out/target/common/R
Module File Location: anywhere BUT out/*
  • You probably are not going to be working on every single module unless you work with Cyanogen.  Right click on a module and add it to your favorites.  In the top of the dock, click the pull down and choose to view your favorites.

  • Build from the command line.  You might be able to do it from within the IDE, but I haven't tried that.

Thank you to the JetBrains support team; and a special thanks to Serge Baranov who put up with me long enough to get some of these issues resolved.

07 July 2011

Altering system.img, userdata.img and persist.img

If you have started building the Android source tree yourself, you have undoubtedly wondered how to modify the image files.  In this post, we'll look specifically at system.img.  This is based on the work found here.

Let's pretend our directories are:
~/work/android: directory where you did your git, envbuild, lunch/choosecombo from.
~/work/tmp: empty directory for us to play in
~/bin: directory on your path

If you have already done a build, you will find out/target/product/generic/system.img.  This is a YAFFS2 file.


In my case, I did not have a way to mount yaffs2 filesystems.  I am sure I could have done some insmods and such; but instead, I chose to just compile this unyaffs.

~/work/tmp$ wget
~/work/tmp$ wget
~/work/tmp$ gcc -o unyaffs unyaffs.c
~/work/tmp$ cp unyaffs ~/bin
~/work/tmp$ rm *

Extracting system.img

~/work/tmp$ cp ~/work/android/out/target/product/generic/system.img .
~/work/tmp$ mkdir tmp2
~/work/tmp$ cd tmp2
~/work/tmp/tmp2$ unyaffs ../system.img

((modify files... for example, etc/

Rebuilding system.img

~/work/tmp$ rm system.img
~/work/tmp$ ~/work/android/out/host/linux-x86/bin/mkyaffs2image tmp2 system.img

Now you should be able to use the new system.img with your emulator =)

userdata.img and persist.img

These are handled in exactly the same way, just change the filenames.

Altering ramdisk.img

If you have started building the Android source tree yourself, you have undoubtedly wondered how to modify the image files.  In this post, we'll look specifically at ramdisk.img. This is based on the work found here.

Let's pretend our directories are:
~/work/android: directory where you did your git, envbuild, lunch/choosecombo from.
~/work/tmp: empty directory for us to play in

If you have already done a build, you will find out/target/product/generic/ramdisk.img.  This is a gzipped cpio file.
Extracting ramdisk.img

~/work/tmp$ cp ~/work/android/out/target/product/generic/ramdisk.img ./ramdisk.cpio.gz
~/work/tmp$ gzip -d ramdisk.cpio.gz
~/work/tmp$ mkdir tmp2
~/work/tmp$ cd tmp2
~/work/tmp/tmp2$ cpio -i -F ../ramdisk.cpio
((modify files... for example, init.rc or init.goldfish.rc))

Rebuilding ramdisk.img

~/work/tmp/tmp2$ cpio -i -t -F ../ramdisk.cpio | cpio -o -H newc -O ../ramdisk2.cpio
~/work/tmp/tmp2$ cd ..
~/work/tmp$ gzip -c ramdisk2.cpio > ramdisk.img

Now you should be able to use the new ramdisk.img with your emulator =)

05 March 2011

adb does not have permission to access my Atrix?

The Atrix does not have the option to allow installing from unknown (ie: non-Market) locations.  As such, I was unsure what I would see when I tried to install APKs from the command line...

malachi@onyx:~$ adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
????????????    no permissions
Not good... but, surely there is a way around that...?

Turns out it is quite simple really....

1. Stop the existing ADB server.
malachi@onyx:~$ adb kill-server

2. Start adb's server as root.  You could try sudo adb instead, but I didn't...
malachi@onyx:~$ sudo su - root
root@onyx:~# adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
root@onyx:~# exit

3. Run adb again... this time, with root running the server, it will work.
malachi@onyx:~$ adb devices
List of devices attached
TA20704PWJ    device

04 March 2011

Motorola Atrix

After having to pull the battery on my N1 repeatedly today, I decided to take the plunge and upgrade. I'll let you know what I think after I have had some time to play around with it.

Repository has moved

In Galatea - A Maven/Android Archetype, I showed how to use the maven archetype to create a basic Android app.  The server hosting the Nexus repository has been replaced by services from  As such, the instructions to generate an artifact from the repository have changed.

malachi@onyx:~/work/test2$ mvn archetype:generate -DarchetypeCatalog=
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] >>> maven-archetype-plugin:2.0:generate (default-cli) @ standalone-pom >>>
[INFO] <<< maven-archetype-plugin:2.0:generate (default-cli) @ standalone-pom <<<
[INFO] --- maven-archetype-plugin:2.0:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: -> ardor3d-archetype (-)
2: -> galatea-archetype (-)
3: -> kryten-archetype (-)
Choose a number: : 2

24 February 2011

Upgrading NexusOne from 2.2.2 to 2.3.3

An old coworker, Scott Hooper, pointed out this site for me so I finally managed to get Gingerbread onto my N1 =) Yay me :)  Now let's hope it fixes some of those annoying issues (like the repeated need to pull the battery).

23 February 2011

One of my apps has hit 1000 users!

Just thought I would share the great news that my FetLife for Android app (recently acquired by Golden Spiral Software) has hit 1000 users!

27 January 2011

NexusOne with Docking Station?

I was looking for a docking station for my Asus G73J Ubuntu laptop when I ran across the Plugable docking station.  Normally, I would not have considered a USB-based docking station, but since this laptop does not come with an ExpressCard, I have little choice.

What initially caught my attention about this universal docking station was that, unlike most of the others, it supported Linux in addition to Mac and Windows.  What sealed the deal for me though was seeing it attached to a Nexus One :)