/** * Copyright (C) 2009 Michael A. MacDonald */ package com.iiordanov.android.bc; import android.content.Context; /** * Create interface implementations appropriate to the current version of the SDK; * implementations can allow use of higher-level SDK calls in .apk's that will still run * on lower-level SDK's * @author Michael A. MacDonald */ public class BCFactory { private static BCFactory _theInstance = new BCFactory(); private IBCActivityManager bcActivityManager; private IBCGestureDetector bcGestureDetector; private IBCHaptic bcHaptic; private IBCMotionEvent bcMotionEvent; private IBCStorageContext bcStorageContext; /** * This is here so checking the static doesn't get optimized away; * note we can't use SDK_INT because that is too new * @return sdk version */ int getSdkVersion() { try { return Integer.parseInt(android.os.Build.VERSION.SDK); } catch (NumberFormatException nfe) { return 1; } } /** * Return the implementation of IBCActivityManager appropriate for this SDK level * @return */ public IBCActivityManager getBCActivityManager() { if (bcActivityManager == null) { synchronized (this) { if (bcActivityManager == null) { if (getSdkVersion() >= 5) { try { bcActivityManager = (IBCActivityManager)getClass().getClassLoader().loadClass("com.iiordanov.android.bc.BCActivityManagerV5").newInstance(); } catch (Exception ie) { bcActivityManager = new BCActivityManagerDefault(); throw new RuntimeException("Error instantiating", ie); } } else { bcActivityManager = new BCActivityManagerDefault(); } } } } return bcActivityManager; } /** * Return the implementation of IBCGestureDetector appropriate for this SDK level * * Since we dropped support of SDK levels < 3, there is only one version at the moment. * @return */ public IBCGestureDetector getBCGestureDetector() { if (bcGestureDetector == null) { synchronized (this) { if (bcGestureDetector == null) { try { bcGestureDetector = (IBCGestureDetector)getClass().getClassLoader().loadClass("com.iiordanov.android.bc.BCGestureDetectorDefault").newInstance(); } catch (Exception ie) { throw new RuntimeException("Error instantiating", ie); } } } } return bcGestureDetector; } /** * Return the implementation of IBCHaptic appropriate for this SDK level * * Since we dropped support of SDK levels prior to 3, there is only one version at the moment. * @return */ public IBCHaptic getBCHaptic() { if (bcHaptic == null) { synchronized (this) { if (bcHaptic == null) { try { bcHaptic = (IBCHaptic)getClass().getClassLoader().loadClass("com.iiordanov.android.bc.BCHapticDefault").newInstance(); } catch (Exception ie) { throw new RuntimeException("Error instantiating", ie); } } } } return bcHaptic; } /** * Return the implementation of IBCMotionEvent appropriate for this SDK level * @return */ public IBCMotionEvent getBCMotionEvent() { if (bcMotionEvent == null) { synchronized (this) { if (bcMotionEvent == null) { if (getSdkVersion() >= 5) { try { bcMotionEvent = (IBCMotionEvent)getClass().getClassLoader().loadClass("com.iiordanov.android.bc.BCMotionEvent5").newInstance(); } catch (Exception ie) { throw new RuntimeException("Error instantiating", ie); } } else { try { bcMotionEvent = (IBCMotionEvent)getClass().getClassLoader().loadClass("com.iiordanov.android.bc.BCMotionEvent4").newInstance(); } catch (Exception ie) { throw new RuntimeException("Error instantiating", ie); } } } } } return bcMotionEvent; } @SuppressWarnings("unchecked") static private Class[] scaleDetectorConstructorArgs = new Class[] { Context.class, OnScaleGestureListener.class }; /** * Return an instance of an implementation of {@link IBCScaleGestureDetector} appropriate to the SDK of this device. * This will work very much like android.view.ScaleGestureDetector on SDK >= 5. For previous * SDK versions, it is a dummy implementation that does nothing and will never call the listener. * <p> * Note that unlike the other methods in this class, the returned interface instance is not * stateless. * @param context The context to which the detector is applied * @param listener The listener to which the implementation will send scale events * @return The gesture detector */ public IBCScaleGestureDetector getScaleGestureDetector(Context context, OnScaleGestureListener listener) { IBCScaleGestureDetector result; if (getSdkVersion() >= 5) { try { result = (IBCScaleGestureDetector)getClass().getClassLoader(). loadClass("com.iiordanov.android.bc.ScaleGestureDetector"). getConstructor(scaleDetectorConstructorArgs).newInstance(new Object[] { context, listener }); } catch (Exception e) { throw new RuntimeException("Error instantiating ScaleGestureDetector", e); } } else { result = new DummyScaleGestureDetector(); } return result; } /** * * @return An implementation of IBCStorageContext appropriate for the running Android release */ public IBCStorageContext getStorageContext() { if (bcStorageContext == null) { synchronized (this) { if (bcStorageContext == null) { if (getSdkVersion() >= 8) { try { bcStorageContext = (IBCStorageContext)getClass().getClassLoader().loadClass("com.iiordanov.android.bc.BCStorageContext8").newInstance(); } catch (Exception ie) { throw new RuntimeException("Error instantiating", ie); } } else { try { bcStorageContext = (IBCStorageContext)getClass().getClassLoader().loadClass("com.iiordanov.android.bc.BCStorageContext7").newInstance(); } catch (Exception ie) { throw new RuntimeException("Error instantiating", ie); } } } } } return bcStorageContext; } /** * Returns the only instance of this class, which manages the SDK specific interface * implementations * @return Factory instance */ public static BCFactory getInstance() { return _theInstance; } }