I have application using Android 2.1 which utilize LocationManager to get the altitude. But now, I need to obtain the altitude using SensorManager which requires API Level 9 (2.3).
How can I put the SensorManager.getAltitude(float, float)
in my 2.1 android application by putting a condition and calling it by a function name (possible in normal Java)?
Thank you in advance
UPDATE 1 If you have noticed that my application need to be compiled using Android 2.1. That's why I'm looking for a way to call the function by name or in any other way that can be compiled.
When the question is "Do I have this class or method at the current API level?" then use branching like:
For this you need to use an Android library that is Gingerbread or above. Otherwise the code won't compile with the classes added in Gingerbread.
This solution is MUCH more cleaner than the disgusting reflection stuff. Note that the dalvik will log a (not-lethal) error stating that he cannot find the classes added in GINGERBREAD when trying to load SomeClass but the app won't crash. It would only crash if we would try to USE that specific class and enter the IF branch - but we don't do that (unless we are on GINGERBREAD or later).
Note that the solution also works when you have a class that were there forever but a new method was added in Gingerbread. In runtime if you are running on pre-Gingerbread you just don't enter the IF branch and don't call that method thus the app will not crash.
You need to build against the highest api you require and then code alternate code paths conditionally for other levels you want to support
To check current API level at execution time, the latest recommendation from the Android docs is to do something like this:
Once you introduce this complexity though, you have to be very careful. There isn't currently an automatic way to check all code paths to make sure that all api level calls above the minSdkVersion have alternative calls to support all versions. Maybe someone can chime in if there exists a unit testing tool that might do something like this.
Here how you do it using reflection (Calling StrictMode class from the level where it is not available:
I haven't tried it - but it should be possible, using some code generation, to create a proxy library (per API level) that will wrap the entire native android.jar and whose implementation will try to invoke the methods from android.jar.
This proxy lib will use either the above mentioned internal-static-class way or reflection to make the dalvikvm lazily link to the requested method.
It will let the user access all the API she wants (assuming she'll check for correct API level) and prevent the unpleasant dalvikvm log messages. You could also embed each method's API level and throw a usable exception (BadApiLevelException or something)
(Anyone knows why Google/Android don't already do something like that?)
You can call the method using reflection and fail gracefully in case of errors (like missing class or methods). See java.lang.reflect
Other option is to compile code in level 9 but surround with try/catch to catch errors that would arise from execution on lower level. It could be fairly error prone, though, and I'd think twice about doing it.
Update
Here is test code
Results:
2.3
2.2
Skipped stack trace
Skipped more stack trace
You can take advantage of how class isn't loaded until it is accessed for an easy work around that doesn't require reflection. You use an inner class with static methods to use your new apis. Here is a simple example.