开发者

Android backward code compatibility

开发者 https://www.devze.com 2023-02-08 06:23 出处:网络
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 don

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 inv开发者_如何转开发oking 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?


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.


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);
   }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消