Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android backward code compatibility

I'm developing an app that uses

android.hardware.Camera.parameters.getSupportedPictureSizes()

This is only available from SDK version 8 and I would like to be compatible with SDK 4, so I've done this:

if(Build.VERSION.SDK_INT >=8){...}

But on the emulator, it seams that it tries to check the reference to this function, and it fails:

02-02 11:20:10.930: ERROR/dalvikvm(1841): Could not find method android.hardware.Camera$Parameters.getSupportedPictureSizes, referenced from method com.test.demo.CameraCustom.takeAPicture

Any idea about how to solve this backward compatibility issue?

I've tried to use inkocation with this piece of code inside surfaceChanged. Obviously, the code works directly without invokation:

try{
    windowmanager_defaultdisplay_Rotation = getWindowManager().getDefaultDisplay().getClass().getMethod("getRotation");
    Log.v(MainMenu.TAG, "getRotation exist");
}catch(Exception e){
    Log.v(MainMenu.TAG, "getRotation dont exist");
}

try{
    windowmanager_defaultdisplay_Rotation.invoke(null, null);
    Log.v(MainMenu.TAG, "getRotation invoking ok, rotation ");
}catch(Exception e){
    Log.v(MainMenu.TAG, "exception invoking getRotation "+e.toString());
}

I get "getRotation exist" but then "exception invoking getRotation java.lang.NullPointerException.

Any idea?

like image 794
zegnus Avatar asked Feb 02 '11 11:02

zegnus


People also ask

Does Android have backwards compatibility?

Backward CompatibilityThe Android SDK is by default forward compatible but not backward compatible — this means that an app that is built with and supports a minimum SDK version of 3.0 can be installed on any device running Android versions 3.0 and upwards — but not on devices running Android versions below 3.0.

How can Android help developers ensure backward compatibility in their apps?

In order to provide backward compatibility, developers can check at runtime the platform version and use a new API on newer versions of the platform and old API on older versions or, depending on the case, using some static libraries which offer backward compatibility.

Why backwards and forward compatibility is needed in Android development?

Forward compatibility is important because many Android-powered devices receive over-the-air (OTA) system updates. The user may install your application and use it successfully, then later receive an OTA update to a new version of the Android platform.

What is backward compatibility example?

A backward compatible system is newer hardware that is backward compatible with older hardware versions of the same model. For example, PlayStation 3 (PS3) is backward compatible with PlayStation 1 (PS1) and most PlayStation 2 (PS2) systems. Hardware that is backward compatible can vary with the model and version.


2 Answers

You cannot load code containing calls to getSupportedPictureSizes() on API level 7 and before. Hence, you need to make your decision based upon Build before you load the code containing the version-dependent statement.

Your options include:

  • Disable the menu choice, button, or whatever that leads to the activity that uses getSupportedPictureSizes(), based upon API level
  • Use conditional class loading or similar techniques to load a suitable implementation based upon API level, where the "suitable implementation" uses getSupportedPictureSizes() only on API level 8 or higher

An example of the latter technique can be seen in this sample project, where I support forward-facing cameras on API level 9, yet still can run on older versions of Android.

like image 126
CommonsWare Avatar answered Nov 03 '22 14:11

CommonsWare


Ok, the answer provided by Commonsware is correct, especially if you study the excellent sample project he provided. Also, zegnus was on the right track when he pointed to http://developer.android.com/resources/articles/backward-compatibility.html

The key to this though, which is not clear from the other answer, is that you need to compile with the API that supports the features that you need. Otherwise you get errors. In Commonsware's example forward-facing cameras is first supported in API level 9 and this is what you must specify in your project to get it to compile. Then you can use the other techniques described above to test whether the OS where the app is running actually supports the classes and/or methods that you are trying to use. If your app is running on an older version of the OS the calls will generate an exception which you can trap and take the appropriate action for the older OS.

For the sake of completeness, here is the code that I used to be compatible with API 7 even though I compiled with API 8, which includes ThumbnailUtils.

import com.Flashum.util.WrapThumbnailUtils;

   public static Bitmap createVideoThumbnail(String filePath, int kind) {
      try {
         WrapThumbnailUtils.checkAvailable(); // will cause exception if ThumbnailUtils not supported
         return WrapThumbnailUtils.createVideoThumbnail(filePath, kind);
      } catch (Exception e) {
         return null;
      }
   }

package com.Flashum.util;

import android.graphics.Bitmap;
import android.media.ThumbnailUtils;

// To be compatible with Android 2.1 need to create
// wrapper class for WrapThumbnailUtils.
public class WrapThumbnailUtils {
   /* class initialization fails when this throws an exception */
   static {
      try {
         Class.forName("android.media.ThumbnailUtils");
      } catch (Exception ex) {
         throw new RuntimeException(ex);
      }
   }

   /* calling here forces class initialization */
   public static void checkAvailable() {}

   public static Bitmap createVideoThumbnail(String filePath, int kind) {
      return ThumbnailUtils.createVideoThumbnail(filePath, kind);
   }
}
like image 28
charles young Avatar answered Nov 03 '22 13:11

charles young