Package net.tawacentral.roger.secrets

Source Code of net.tawacentral.roger.secrets.OS

// Copyright (c) 2009, Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package net.tawacentral.roger.secrets;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

/**
* This class wraps OS-specific APIs behind Java's reflection API so that the
* application can still run on OSs that don't support the given API.  This
* class is used as a backward compatibility layer so that I don't need to
* build different versions of the application for different OSs.
*
* The root of the problem is the dalvik class verifier, which rejects classes
* that depend on system classes or interfaces that are not present on the
* device, causing the application to force exit.  Instead of statically
* depending on OS-specific classes, this code uses reflection to dynamically
* discover if a class is available or not, in order to get around the verifier.
* This is the "correct" way to support different OS versions.
*
* @author rogerta
*
*/
public class OS {
  /** Tag for logging purposes. */
  public static final String LOG_TAG = "Secrets";

  private static int sdkVersion;
  static {
    try {
      sdkVersion = Integer.parseInt(android.os.Build.VERSION.SDK);
    } catch (Exception ex) {
    }
  }

  /** Does the device support the froyo (Android 2.2) APIs? */
  public static boolean isAndroid22() {
    return sdkVersion >= 8;
  }

  /** Does the device support the Gingerbread (Android 2.3) APIs? */
  public static boolean isAndroid23() {
    return sdkVersion >= 9;
  }

  /** Does the device support the Honeycomb (Android 3.0) APIs? */
  public static boolean isAndroid30() {
    return sdkVersion >= 11;
  }

  /** Hide the soft keyboard if visible. */
  public static void hideSoftKeyboard(Context ctx, View view) {
    InputMethodManager manager = (InputMethodManager)
        ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
    if (null != manager)
      manager.hideSoftInputFromWindow(view.getWindowToken(), 0);
  }

  /**
   * Creates a backup manager for handling app backup in Android 2.2 and later.
   * Returns an Object so that that this function can be called from any
   * version of Android.
   *
   * @param context Application context for the backup manager.
   * @return A backup manager on Android 2.2 and later, null otherwise.
   */
  public static Object createBackupManager(Context context) {
    Object bm = null;

    if (isAndroid22()) {
      try {
        Class<?> clazz = Class.forName("android.app.backup.BackupManager");
        Constructor<?> c = clazz.getConstructor(Context.class);
        bm = c.newInstance(context);
        Log.d(LOG_TAG, "createBackupManager");
      } catch (Exception ex) {
        Log.e(LOG_TAG, "Should have found backup manager", ex);
      }
    }

    return bm;
  }

  /**
   * Calls dataChanged() on the backup manager on Android 2.2 and later, or
   * does nothing on previous versions of Android.
   *
   * @param bm Backup manager.  Can be null.
   */
  public static void backupManagerDataChanged(Object bm) {
    if (isAndroid22() && bm != null) {
      try {
        Class<?> clazz = Class.forName("android.app.backup.BackupManager");
        Method m = clazz.getMethod("dataChanged");
        m.invoke(bm);
        Log.d(LOG_TAG, "backupManagerDataChanged");
      } catch (Exception ex) {
        Log.e(LOG_TAG, "backupManagerDataChanged", ex);
      }
    }
  }

  /**
   * Invalidates the option menu so that it is recreated.  This is needed
   * for Honeycomb so that the action bar can be updated when switching to
   * and from editing mode.
   *
   * @param activity The activity containing the option menu.
   */
  public static void invalidateOptionsMenu(Activity activity) {
    if (!isAndroid30())
      return;

    try {
      Method m = activity.getClass().getMethod("invalidateOptionsMenu");
      m.invoke(activity);
    } catch (Exception ex) {
      Log.e(LOG_TAG, "invalidateOptionMenu", ex);
    }
  }

  /**
   * Configures a SearchView if this is Android 3.0 or later.
   *
   * @param activity The activity containing the search view.
   */
  public static void configureSearchView(Activity activity, Menu menu) {
    if (!isAndroid30())
      return;

    try {
      SearchManager sm = (SearchManager) activity.getSystemService(
          Context.SEARCH_SERVICE);
      if (null == sm)
        return;

      Method m = sm.getClass().getMethod("getSearchableInfo",
          android.content.ComponentName.class);
      Object si = m.invoke(sm, activity.getComponentName());

      MenuItem item = menu.findItem(R.id.list_search);
      m = item.getClass().getMethod("getActionView");
      View widget = (View) m.invoke(item);

      m = widget.getClass().getMethod("setSearchableInfo", si.getClass());
      m.invoke(widget, si);

      m = widget.getClass().getMethod("setIconifiedByDefault", boolean.class);
      m.invoke(widget, false);

      m = widget.getClass().getMethod("setSubmitButtonEnabled", boolean.class);
      m.invoke(widget, true);
    } catch (Exception ex) {
      Log.e(LOG_TAG, "configureSearchView", ex);
    }
  }

  /** Does the device support a scroll wheel or trackball? */
  public static boolean supportsScrollWheel() {
    // This API is only support in Android 2.3 and later.  If this is an
    // earlier version of Android, then assume we have a scroll wheel.
    if (!isAndroid23())
      return true;

    try {
      Class<?> clazz = Class.forName("android.view.InputDevice");
      Method m = clazz.getMethod("getDeviceIds");
      Field f = clazz.getField("SOURCE_TRACKBALL");
      final int trackballId = f.getInt(null);
      f = clazz.getField("SOURCE_DPAD");
      final int dpadId = f.getInt(null);

      Method mGetDevice = clazz.getMethod("getDevice", int.class);
      Method mGetSources = clazz.getMethod("getSources");
      int[] ids = (int[]) m.invoke(null);
      for (int id : ids) {
        Object device = mGetDevice.invoke(null, id);
        Integer sources = (Integer) mGetSources.invoke(device);
        if (0 != (sources.intValue() & (trackballId | dpadId)))
          return true;
      }
    } catch (Exception ex) {
      Log.e(LOG_TAG, "supportsScrollWheel", ex);
      return true;
    }

    return false;
  }
}
TOP

Related Classes of net.tawacentral.roger.secrets.OS

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.