Support deprecated and new API - android

Is there any way I can support both deprecated and new API in the same method call for Android? I'm using the camera API which seems to be deprecated for the Lollipop version, so I tried to handle it like this:
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
{
//Before Lollipop, use the Camera API since it still supported.
}
else
{
//Use the CameraManager
try
{
for (int i= 0; i < _camera.getCameraIdList().length; i++)
{
System.out.println("Camera= " + _camera.getCameraIdList()[i]);
}
}
catch (CameraAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
But this does however just give me the error Call requires API level 21 (current min is 15): android.hardware.camera2.CameraManager#getCameraIdList
I tried SupressLint and TargetApi but that only made the device running an earlier (before Lollipop) Android version crash when creating an class instance of this type.
Thanks for any help!

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//handler lollipop and higher
} else {
//earlier api calls
}

Simply having code in a class does not crash any Android 2.0+ device - code actually needs to run for it to crash. Check to make sure all of your Lollipop specific code is wrapped in version checks.

Related

NEXT_ALARM_FORMATTED is deprecated

Since API 21 / Android 5.0
The field Settings.System.NEXT_ALARM_FORMATTED is deprecated
What is the alternative for doing this? I saw http://developer.android.com/reference/android/app/AlarmManager.html#getNextAlarmClock()
But I really don't know how to implement it.
You should upgrade android to api level 21 and your device also should be compatible with that,
you can remove try..catch block also but it is better if in your manifest.xml android:minSdkVersion is less than 21.
try {
AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
am.getNextAlarmClock();
Log.d("Nextalarm", am.getNextAlarmClock().toString());
} catch (NoSuchMethodError e) {
e.printStackTrace();
}
getNextAlarmClock() is a public method in AlarmManager class which was introduced in API level 21. You need to install API level 21 in order to use this method. Also, make necessary changes in Android Project Build Target.
I needed some code to simply test if any alarms exist, so I can update a graphic on a full screen app. Thank you to everyone who contributed. Based on all that, here is what I ended up implementing:
private void testAlarms() {
String nextAlarm = null;
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
am.getNextAlarmClock();
try {
nextAlarm = am.getNextAlarmClock().toString();
} catch (Exception e) {
e.printStackTrace();
}
} else {
nextAlarm = Settings.System.getString(getContentResolver(),Settings.System.NEXT_ALARM_FORMATTED);
}
if(TextUtils.isEmpty(nextAlarm)) {
hideAlarm();
} else {
showAlarm();
}
}

Android - InputManager.InputDeviceListener NewApi exception

I want to catch events from keys and motion events from joystick connected to my Android.
I'm using InputManager.InputDeviceListener but the minimal API level supported is 14 and InputManager.InputDeviceListener requires API level 16.
Do you know a solution supported by API level 14 ?
Code that not compiling :
public class MyActivity extends Activity implements InputManager.InputDeviceListener {
#Override
public void onResume() {
inputManager.registerInputDeviceListener(this, null);
// Query all input devices.
// We do this so that we can see them in the log as they are enumerated.
int[] ids = inputManager.getInputDeviceIds();
for (int i = 0; i < ids.length; i++)
{
getInputDeviceState(ids[i]);
}
}
#Override
protected void onPause()
{
inputManager.unregisterInputDeviceListener(this);
}
public InputDeviceState getInputDeviceState(int deviceId)
{
InputDeviceState state = inputDeviceStates.get(deviceId);
if (state == null)
{
final InputDevice device = inputManager.getInputDevice(deviceId);
if (device == null)
{
return null;
}
state = new InputDeviceState(device);
inputDeviceStates.put(deviceId, state);
}
return state;
}
}
Code is from Android samples.
Just looking at your code ...
You will get Exceptions because you left out super.onResume(); and super.onPause();
You can find sample code about how to support input device listeners across Android Android Versions here:
http://developer.android.com/training/game-controllers/compatibility.html#newer
In essence the solution is to provide new class and interface for the InputManager and the InputDeviceListener, which on API level 16 and higher are implemented as wrappers of the SDK classes, and on API level 9 to 15 they implement tracking and notifications for the connected input devices. At runtime the app should select the appropriate implementation by comparing Build.VERSION.SDK_INT to Build.VERSION_CODES.JELLY_BEAN.

Why does removeOnGlobalLayoutListener throw a NoSuchMethodError?

I have some code that compiles successfully using ViewTreeObserver#removeOnGlobalLayoutListener(...) and when it runs, this method throws NoSuchMethodError. Why?
There are two methods in ViewTreeObserver with almost the same name.
removeOnGlobalLayoutListener(ViewTreeObserver.OnGlobalLayoutListener victim)
(on then global) is a method that was added in API 16. It replaces
removeGlobalOnLayoutListener(ViewTreeObserver.OnGlobalLayoutListener victim)
(global then on) which has existed since API 1, but which is now deprecated.
Both methods can appear present at compile-time (if you're building against Jellybean or higher) but the newer one will fail on pre-Jellybean devices.
This code thwarts the error:
try {
thing.removeOnGlobalLayoutListener(victim);
} catch (NoSuchMethodError x) {
thing.removeGlobalOnLayoutListener(victim);
}
So does this code:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
thing.removeGlobalOnLayoutListener(victim);
} else {
thing.removeOnGlobalLayoutListener(victim);
}
I assume you are talking about removeOnGlobalLayoutListener from ViewTreeObserver class. This method was added in API level 16. My best guess is that you try to use it on a device running an old version of Android that's why it can't be found.
I have working code
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener){
if (Build.VERSION.SDK_INT < 16) {
v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
} else {
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
}

Why does this works (googleIO acionbarherlper?

So the code is following:
public static ActionBarHelper createInstance(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return new ActionBarHelperICS(activity);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
return new ActionBarHelperHoneycomb(activity);
} else {
return new ActionBarHelperBase(activity);
}
}
If my device is 2.3 (api 9) it shouldn't support Build.VERSION_CODES.ICE_CREAM_SANDWICH but yet it runs, why is that? If it had been a method I called it would have crashed. Is it because it is a public static final int and therefor added from to my code? Please give some general detail and not just a yes/no answer :)
As Stefan pointed out, the api level used to compile the code determines the constants visible at compile time. For my case this doesn't give any problems as I just compare simple values. This only give problems if you use a set method that uses different constants and you happent to use a constant that wasn't possible to handle for your api version.

can an android application check the version of the phone

I would like to write an application that uses live wallpapers for insatnce. this feature is supported only in version 7 and up. Is it posiible, that the application checks the version of the android phone and depending on that runs different code (e.g. uses live wallpaper or static background.)
Do you have a code example for that? Does that require special permissions?
Assuming you're requiring Android 1.6 or newer:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_MR1) {
...
}
Yes there is. Look at the Build class in Android. You can use it like so Build.VERSION.SDK_INT
public static final int ECLAIR_MR1 =7;
public static final int FROYO =8;
if(Build.VERSION.SDK_INT==FROYO){
Toast.makeText(getApplicationContext(), "Iam a FROYO-Phone", 1).show();
}else if(Build.VERSION.SDK_INT==ECLAIR_MR1){
Toast.makeText(getApplicationContext(), "Iam an ECLAIR-Phone", 1).show();
}
SDK_INT is not available on very early builds. So if your manifest has for instance:
android:minSdkVersion="1"
you can use something like this:
#TargetApi(Build.VERSION_CODES.DONUT)
static boolean getPreHoneyComb() {
try {
Build.VERSION.class.getField("SDK_INT");
}
catch (NoSuchFieldException e) {
return true;
}
return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
}

Categories

Resources