Several iterations of updates below:
Update 1: This procedure works on the zxing-1.4.zip source base. I’m trying to figure out why it doesn’t want to work easily with the most current SVN code (e.g., rev 1217 or 1220). I thought it was just some preloading weirdness that caused the Java Stack Overflow errors, then I thought it was Subversion related, but now… now I’m not sure what’s going on but I’ll let you know if I figure it out.
Update 2: Eclipse does NOT like the new version of /android/default.properties at all. After you create the project folders but before you try creating the project in Eclipse, edit /android/default.properties and change
target=Google Inc.:Google APIs:4
That seems to prevent the whole Stack Overflow problem. I’m not sure why this changed or what the more correct thing to do it but there’s some apparently relevant discussion here. Curiously, despite my reversion of this change I do not see any problem in my test builds here, whether in Eclipse or when using the command-line build as outlined previously.
Update 3: If you comment out the target= line in that file entirely (using “#”) the problem also goes away – be sure to select an SDK level >= 4 though. Eclipse still forces you to select a Google APIs target, but if you double-click one of the “un-selectable” Android targets (click the text NOT the checkbox!) just right it’ll apparently take the setting and work OK. Who knows if that works in general – probably not. With an Android target launching the AVD also goes much more smoothly!
Question is, what is it that makes Eclipse insist this is an APIs project when default.properties is not giving it any hints? Or is it a quirk of the SDK? What triggers this, and is it more readily resolved than by doing this?
Update 4: Last update for tonight. Once a project is in Eclipse you can go to Properties -> Android for that project and select a suitable Android target. As long as you don’t have dependencies on Google APIs it should be fine. If you /android/AndroidManifest.xml and remove the android:minSdkVersion setting that problem goes away as well (again, select Android 1.6 SDK level 4 to ensure proper operation).
Either it’s Eclipse 3.5.1 or the ADT plugin that’s messing up here. Regardless, it doesn’t seem to be any flaw in ZXing. It’s rather annoying to see Eclipse acting like this… are other people seeing this sort of bug?
To summarize: to avoid all these painful problems just plain remove default.properties and edit AndroidManifest.xml before you create a new Eclipse project based on the latest source. Ensure you select Android 1.6 SDK level 4 for best results.
Also, when you run the app it’s best to just start the AVD first, wiping user data, (or at least uninstalling the old version of your app) and being at the home screen before you “Run As”. Otherwise, the app’s display ends up rather funky.
Finally, “Build Automatically” may be more trouble than it’s worth, at least for a larger project such as this. Consider this if your head starts making dents in the wall as you struggle to make sense of Eclipse’s random “out of memory” errors. 🙂
In my previous post I referred to a Knol that tells you how to build ZXing for Android (the Barcode Scanner) using the Eclipse IDE. There are pros and cons to doing this, given that ZXing is normally built from the command line using Ant (and during that build it is optimized using Proguard).
However, my goal is to learn more about Android programming in general and to make it even more interesting, I’m doing it from Windows. Having the project working in an IDE is preferable for me when it comes to unraveling functional connections and learning how a (quite useful!) Android app is put together.
First of all, that Knol isn’t all that bad. It helps if you read it carefully (I kept screwing up a particular step), however some of the steps are unclear apparently because the SDK has changed rather substantially since it was first written. I’ve tried to be ridiculously detailed here so as to eliminate any possible confusion for the novice.
Second, it’s not clear that you need to install anything other than the Eclipse Classic 3.5.1 IDE and the Android SDK to perform this experiment. I have the JDK, Ant and Proguard as well but they aren’t in my system paths nor is JAVA_HOME set system-wide yet. Therefore I suspect none of that other stuff is getting referenced in this experiment. You should have the IDE installed, the Android SDK installed and up-to-date, and the ADT Plugin for Eclipse (found on the SDK page).
Initialize the project in Eclipse
- Obtain the ZXing source tree via zip or SVN as described in the previous posts. We are only interested in the /android and the /core/src trees. The rest of the paths and components may be ignored for the purpose of building the Barcode Scanner app for Android.
- Place these in a working area. For this example I used D:\workspace\zxing
- An important note: the Android SDK Content loader doesn’t immediately start in Eclipse until you attempt to use or create an Adroid project, and it takes a while to load. Therefore quickly creating a new Android project based on another Android project while the SDK is loading can have unwanted consequences – particularly, Stack Overflows – which is apparently due to a race condition (if the Android SDK Content Loader is still processing when you pick the “based on” tree, bad, bad things happen). It was a very distracting problem until I realized what was going on.
- Start the Eclipse IDE
- Close any open projects!
- Note that Project -> Build Automatically is selected
- From the menu select File -> New -> Project…
- In the new window select Android -> Android Project
- If Build targets are NOT populated at all and there’s activity in the progress tab:
- Close the New Project window.
- Wait for the Android SDK Content Loader activity to complete (watch the progress tab!)
- From the menu select File -> New -> Project… again
- In the new window select Android -> Android Project again
- At this point the Build Targets should be properly populated and the progress tab should be idle/empty.
- Give the project a name. For this example I used “BarExample” and will refer to that going forward.
- Select Create project from existing source
- Browse to where you put the zxing source tree (this will become your workspace!)
- Select the /android subfolder and click OK
- The Build Target will automatically be selected as Google APIs 1.6
- I’m not entirely sure why this happens – you cannot select Android alone either. I think this is why you are later warned when trying to launch it that there are no compatible devices.
- The Application name will be auto-filled as CaptureActivity
- Click Finish
Allow it to prebuild. At this point you’ll have some 250+ errors but the next step should resolve them!
Add the /core/src code to your project:
Hard way #1:
Hard way #2:
A somewhat easier way to do this (avoiding the extra copy) is to put /core/src under /android (thus creating /android/core/src) before you initialize the project! Then, after you initialize the project you can pick the src folder under the core entry in the project items and select Build Path -> Use as a Source Folder to have the desired effect (it’ll crete an entry called core/src). I would expect a symlink, correctly applied, would also have the desired effect. As you can see, the android folder itself is really superfluous here. [I still think there’s got to be an even easier way to gather this all together, without moving ANYTHING around.]
The best way to add /core/src to your project! No symlinks required (and being Windows it’s possible but not easy and besides this is even more minimalist) and it should work seamlessly even if you’re doing thing with Subversion-controlled code.
You’ve already created a project area called zxing (or whatever) and in it are the /android tree and the /core/src tree. Rather than manually or automatically move ANY code, simply do this:
- In the Package Exp tab, right click on the project name (“BarExample”) and select Build Path -> Link Source…
- Browse to and select the src folder in core.
- Change Folder name to srccore (or any other not-in-use folder name you prefer).
- Select Finish
- Let it rebuild automagically
If you were successful, you should see a whole mess of warnings (I see over 170) – but no errors!
To install and test this on the Android Virtual Device:
- Go to the Android SDK and AVD Manager and start your test device
- I previously created a Droid-compatible device configured as Platform 2.0.1 API Level 6, with a WVGA854 display and a 32M SD card.
- Select the device and click Start…
- To avoid weirdness I elected to run with a clean slate and so I selected the “Wipe user data” option
- The virtual device should start up.
- You can (and probably should) close the AVD Manager at this point. Leaving the manager on led to an odd “GC overhead limit exceeded” error.
- Wait patiently for the main screen to appear (it seems to take quite a while and a lot of CPU – is it just me?)
- You shouldn’t have any other versions of this Barcode app installed at this point. If you DO you should probably uninstall them first!
- Now, back to Eclipse!
- In your project, select Run As -> Android Application
- At this point I get an AVD error telling me “No compatible targets were found”.
- I selected “No” (I don’t want to create a new target – I already have one!)
- In the Device Chooser that follows I selected my running 2.0.1 emulator and clicked OK.
- (I don’t know why this happens – it’s probably the mismatch between my 2.0.1. AVD and the original APIs 1.6 target.)
- The app should upload, install and execute on the virtual device.
- Be sure to rotate your local gravitational reference clockwise by 90° for the optimum viewing experience. See the January, 2153 quantum multicast of Make: The Virtual Magazine for info on how to construct a portable graviton generator for this purpose.
- It’s not terribly interesting at this point but should work and look normal (not wiping user data and/or letting it launch the app before the screen is “unlocked” had something to do with the display looking rather weird – I’m not sure what was going wrong).
- (Really, why doesn’t the AVD have a rotate function? It seems pretty fundamental. Likewise some way to fake camera input – do tell if I’m missing a simple way to do either!)
Like I’ve mentioned, I got various odd little IDE errors as I made my way through all this… perhaps I’m doing something that’s not entirely right or the Eclipse IDE / Android SDK combination isn’t very stable.
But will it blend? That is, will it work on a physical device? Heck yeah!
To install and test this on an Android physical device:
- First, uninstall the current Barcode Scanner from your phone (you shouldn’t need to do it each time you cycle through your private test builds, but you DEFINITELY need to if you are switching between the officially signed to the unsigned or debug signed versions! In short: if you get an installation error uninstall the app and try intalling it again!
- Note: for some bizarre reason after installation the Barcode app may be out of order alphabetically in the Manage applications dialog! Closing the dialog and going back to it via Settings rectifies this.
- Copy the application’s APK from /android/bin to your phone
- Install the application
- Run the Barcode Scanner!
That’s about it! I’d expect this to work just as well from a Linux host but I haven’t tested it.
- Proguard isn’t being used in this configuration AFAIK. Therefore, things aren’t optimized (I’m not yet clear on why that’s necessary – presumably for performance reasons though it seemed to work OK when I tried it).
- AFAIK this is NOT how the ZXing project is normally developed, so if you plan to submit changes to it or otherwise assist with the project you should defer to the project’s standards and procedures.
- This procedure worked fine for me but it may or may not work as well for you, and there may be unexpected side-effects (I haven’t seen any yet but you never know).