Friday, January 14, 2011

Adding suport for Android SDK <2.2

 Making your application work across multiple Android SDK versions can be non-trivial if you are using features that depend on newly introduced API. One such example is the YuvImage class in SDK v2.2 (Froyo). We use YuvImage.compressToJpeg method to convert YUV data obtained from the Android camera, to a Jpeg image which you can save to disk, dispatch over the network, pickle it, or what you will. However, for API version <2.2, we need to do something else:

int[] rgb = new int[previewWidth * previewHeight]; 
// This method decodes YUV to RGB.
// imageData is byte[] obtained from the Camera.
decodeYUV(rgb, imageData, previewWidth, previewHeight);
Bitmap bm = Bitmap.createBitmap(rgb, previewWidth, previewHeight, Config.RGB_565);
bm.compress(Bitmap.CompressFormat.JPEG, mPreviewQuality, out);

However, to produce an app that works across different platform versions, this is not enough. We still want to use the speed of native Jpeg compression done by YuvImage in 2.2+ SDK. With the target SDK version of the app set to 2.1, we need to use reflection in order to use the YuvImage class.

Class<?>[] yuvArgsClass = new Class[] {
  byte[].class, int.class, int.class, int.class, int[].class };
Class<?> yuvParamTypes[] = new Class[] { Rect.class, int.class, OutputStream.class};
Class<?> c = Class.forName("");
Constructor<?> yuvImageConstructor = c.getConstructor(yuvArgsClass);
Object[] args = new Object[] {
  imageData, previewFormat, previewWidth, previewHeight, null};
Object yuvImage = yuvImageConstructor.newInstance(args);
Object params[] = new Object[] {previewRect, mPreviewQuality, out};
Method compress = c.getMethod("compressToJpeg", yuvParamTypes);
compress.invoke(yuvImage, params);

In the above code, imageData is the byte[] data obtained from the Camera. previewFormat, previewWidth, and previewHeight are obtained from Camera.getParameters().
previewRect = new Rect(0, 0, previewWidth, previewHeight);

We were unable to get the Java-based YUV -> Bitmap conversion to work on the G1 phones due to OutOfMemory problems. G1 phones have a 16 MB heap which seems to run out pretty quick.

Sunday, January 2, 2011

ProGuard Issues

Android recommends using ProGuard to obfuscate the APKs. However, sometimes ProGuard ends up obfuscating something the app needs, thus causing crashes with exceptions as ClassNotFoundException, NoClassDefFound and such. I ran into this issue recently while releasing the Baby Monitor app.

As suggested here, adding -keep to the progcfg.txt file works. The trick to figure out which classes to keep from obfuscating. If your app implements a Service, make sure that the interfaces are not obfuscated. To do this, add the following line to progcfg.txt:

-keep public interface * extends android.os.IInterface

Thursday, December 30, 2010

Bungat Baby Monitor

Bungat Labs is pleased to announce its first product - Bungat Baby Monitor, available for purchase on the Android Market. A free demo version of the app is also available. It currently supports Android >2.2 phones, but we are actively working on making it work on older devices. The Bungat Baby Monitor provides following features:

  • Sound monitoring
    • Adjustable sensitivity
  • Receive alerts on the specified phone number
  • Rich configuration options
  • Secure remote access
  • Remote video preview
    • Compact video preview mode
    • Adjustable video quality
  • Remote video recording
    • Adjustable video quality
    • Downloadable videos
  • Remote music player
    • Volume controls
    • Play/Pause/Resume
    • Remote music upload

Give Bungat Baby Monitor a spin and send us your feedback and suggestions. We will be constantly striving to make our products better.