Android Open Source - javocsoft-toolbox Tool Box






From Project

Back to project page javocsoft-toolbox.

License

The source code is released under:

GNU General Public License

If you think the Android project javocsoft-toolbox listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2010-2014 - JavocSoft - Javier Gonzalez Serrano
 * http://javocsoft.es/proyectos/code-libs/android/javocsoft-toolbox-android-library
 * /* w w  w  . j  a v a 2 s  . c o  m*/
 * This file is part of JavocSoft Android Toolbox library.
 *
 * JavocSoft Android Toolbox library is free software: you can redistribute it 
 * and/or modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation, either version 3 of the License, 
 * or (at your option) any later version.
 *
 * JavocSoft Android Toolbox library is distributed in the hope that it will be 
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with JavocSoft Android Toolbox library.  If not, see 
 * <http://www.gnu.org/licenses/>.
 * 
 */
package es.javocsoft.android.lib.toolbox;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Application;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.content.res.AssetFileDescriptor;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.ExifInterface;
import android.media.MediaPlayer;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.os.PowerManager;
import android.provider.Settings.Secure;
import android.support.v7.app.ActionBarActivity;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.HitBuilders.EventBuilder;
import com.google.android.gms.analytics.Logger.LogLevel;
import com.google.android.gms.analytics.Tracker;

import es.javocsoft.android.lib.toolbox.encoding.Base64;
import es.javocsoft.android.lib.toolbox.io.IOUtils;


/**
 * This class will hold utility functions related with Android.
 * 
 * @author JavocSoft 2013
 * @since  2012
 */
public final class ToolBox {
  
  /** Enables or disables log */
  public static boolean LOG_ENABLE = true;
  /** Shared Preferences file under some data is saved by the Android Toolbox Library */
  public static final String PREF_FILE_NAME = "prefs_toolbox";
  
  /** Http Method type for a request. */
  public static enum HTTP_METHOD{POST,DELETE,GET};
  
  public static final String TAG = "javocsoft-toolbox: ToolBox";
  
  private static final int CONNECTION_DEFAULT_TIMEOUT = 5000; // 5 sgs.
  private static final int CONNECTION_DEFAULT_DATA_RECEIVAL_TIMEOUT = 10000; // 10 sgs.
  
  private static final int HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10 MiB
  
  public static final String NETWORK_OPERATOR_EMU = "Android";
  public static final String NETWORK_OPERATOR_NOSIM = "NO_SIM";

  public static enum ApiLevel {
    
    LEVEL_1(1), LEVEL_2(2), LEVEL_3(3), LEVEL_4(4), LEVEL_5(5), LEVEL_6(6),
    LEVEL_7(7), LEVEL_8(8), LEVEL_9(9), LEVEL_10(10), LEVEL_11(11), LEVEL_12(12),
    LEVEL_13(13), LEVEL_14(14), LEVEL_15(15), LEVEL_16(16), LEVEL_17(17), LEVEL_18(18);

    private int value;

    ApiLevel(int value) {
      this.value = value;
    }

    public int getValue() {
      return value;
    }    
  }
  
  public static enum NETWORK_PROVIDER {
    MOVISTAR, YOIGO, VODAFONE, ORANGE, EMU, NOSIM, UNKNOWN
  };
      
  public static enum SCREEN_ORIENTATION {PORTRAIT, LANDSCAPE, SQUARE};
  
  public static enum HASH_TYPE{md5,sha1};
  
  /** The type of device by screen. */
  public static enum DEVICE_BY_SCREEN {DP320_NORMAL, DP480_TWEENER, DP600_7INCH, DP720_10INCH};
  
  /** The type of resolution that is using the device. */
  public enum DEVICE_RESOLUTION_TYPE {ldpi, mdpi, hdpi, xhdpi, xxhdpi};
  
  private static PowerManager.WakeLock wakeLock = null;
  
  private static Random random = null;
  
  private static Set<String> systemAppsList = null;
  
  
  private ToolBox(){}
  
  
  //--------------- ANALYTICS ------------------------------------------------------------------------
  
  /**
   * Gets a new Analytics v4 tracker.
   * 
   * See: https://developers.google.com/analytics/devguides/collection/android/v4/
   * 
   * @param context        
   * @param analyticsTrackingId
   * @param debugMode  If enabled, GA operations will not be sent to Analytics but
   *           are logged.  
   * @return
   */
  public static synchronized Tracker analytics_getTracker(Context context, String analyticsTrackingId, boolean debugMode) {
    GoogleAnalytics analytics = GoogleAnalytics.getInstance(context);
    
    if(debugMode) {
      // When dry run is set, hits will not be dispatched, but will still be logged as
      // though they were dispatched.
      analytics.setDryRun(true);
      //Enable logging for GA.
      analytics.getLogger().setLogLevel(LogLevel.VERBOSE);
    }
      
    return analytics.newTracker(analyticsTrackingId);
  }
  
  /**
   * Sends to Google Analytics an event.
   * 
   * @param tracker    The analytics tracker to use when sending the 
   *             event.
   * @param eventCategory  Category of the event
   * @param eventAction  Action of the event
   * @param eventlabel  label of the event
   */
  public static void analytics_sendEvent (Tracker tracker, String eventCategory, String eventAction, String eventlabel, Long eventValue) {
    
    EventBuilder eBuilder = new HitBuilders.EventBuilder();
    eBuilder.setCategory(eventCategory)
        .setAction(eventAction)
        .setLabel(eventlabel);
    
    if(eventValue!=null) {
      eBuilder.setValue(eventValue);      
    }
    
    tracker.send(eBuilder.build());
  }

  /**
   * Sends to Google Analytics a screen view event.
   * 
   * @param tracker    The analytics tracker to use when sending the 
   *             event.
   * @param screenName  The screen name.
   */
  public static void analytics_sendScreenName (Tracker tracker, String screenName) {
    tracker.setScreenName(screenName);
    tracker.send(new HitBuilders.AppViewBuilder().build());
  }
  
  
  
  
  //--------------- SYSTEM ---------------------------------------------------------------------------
  
  /**
   * Tells if an application is installed or not.
   * 
   * @param context    Your application context
   * @param appPackage  The application package.  
   * @return
   */
  public static boolean system_isAppInstalled(Context context, String appPackage) {
        PackageManager pm = context.getPackageManager();
        boolean app_installed = false;
        try {
            pm.getPackageInfo(appPackage, PackageManager.GET_ACTIVITIES);
            app_installed = true;
        }catch (PackageManager.NameNotFoundException e) {
            app_installed = false;
        }
        
        return app_installed ;
    }
  
  /**
   * Gets the list of system applications.
   * 
   * @return  The list. If error the list will be empty.
   */
  public static Set<String> system_getSystemApplicationList(Context context) {
    Set<String> systemApps = new HashSet<String>();
    
    
    try {
      final PackageManager pm = context.getPackageManager();
      final List<ApplicationInfo> installedApps = pm.getInstalledApplications(PackageManager.GET_META_DATA);      
      for ( ApplicationInfo app : installedApps ) {
        if(system_isSystemPackage(app)){
          systemApps.add(app.packageName);
        }
      }    
      
    }catch(Exception e){
      if(LOG_ENABLE){
        Log.e(TAG, "Error getting system application list [" + e.getMessage() + "]", e);
      }
    }
    
    return systemApps;
  }
  
  /**
   * Checks if an application is a system application.
   * 
   * @param appPackage
   * @return
   */
  public static boolean system_isSystemApplication(Context context, String appPackage) {
    boolean res = false;
    
    if(systemAppsList==null){
      systemAppsList = system_getSystemApplicationList(context);
    }     
    for(String sysAppPackage:systemAppsList){
      if(appPackage.equals(sysAppPackage)){
        res = true;
        break;
      }
    }
    
    return res;
  }
  
  /**
   * Return whether the given PackgeInfo represents a system package or not.
   * User-installed packages should not be denoted as system packages.
   * 
   * @param appInfo
   * @return
   */
  public static boolean system_isSystemPackage(ApplicationInfo appInfo) {
      return ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ? true : false;
  }
  
  
  /**
   * This function allows to know if there is an application that responds to
   * the specified action.
   * 
   * @param context
   * @param action  Action that requires an application.
   * @return
   */
  public static boolean system_isIntentAvailable(Context context, String action) {
      final PackageManager packageManager = context.getPackageManager();
      final Intent intent = new Intent(action);
      List<ResolveInfo> list =
              packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
      return list.size() > 0;
  }
  
  
  //--------------- ADDMOB ---------------------------------------------------------------------------
  
  /**
   * This disables correctly the AdMob ads.
   * 
   * @param activity
   * @param adLayout  The AdView view.
   */
  public static void adMob_hideAds(Activity activity, final AdView adLayout) {
      activity.runOnUiThread(new Runnable() {
          @Override
          public void run() {
              adLayout.setEnabled(false);
              adLayout.setVisibility(View.GONE);
          }
      });
  }
  
  /**
   * This enables again the AdMob ads.
   * 
   * @param activity
   * @param adLayout  The AdView view.
   */
  public static void adMob_showAds(Activity activity, final AdView adLayout) {
      activity.runOnUiThread(new Runnable() {
          @Override
          public void run() {
              adLayout.setEnabled(true);
              adLayout.setVisibility(View.VISIBLE);

                AdRequest.Builder adBuilder = new AdRequest.Builder()
                        .addTestDevice(AdRequest.DEVICE_ID_EMULATOR);

          adLayout.loadAd(adBuilder.build());
          }
      });
  }
  
  /**
   * This enables again the AdMob ads.
   * 
   * @param activity
   * @param adLayout
   * @param excludedDevices
   */
  public static void adMob_showAds(Activity activity, final AdView adLayout, final List<String> excludedDevices) {
      activity.runOnUiThread(new Runnable() {
          @Override
          public void run() {
              adLayout.setEnabled(true);
              adLayout.setVisibility(View.VISIBLE);

                AdRequest.Builder adBuilder = new AdRequest.Builder()
                        .addTestDevice(AdRequest.DEVICE_ID_EMULATOR);
          
          for(String dev:excludedDevices){
                    adBuilder.addTestDevice(dev);
          }
          
          adLayout.loadAd(adBuilder.build());
          }
      });
  }
  
  //--------------- APPLICATIONS RELATED -------------------------------------------------------------
  
  /**
   * gets the application icon.
   * 
   * @param context
   * @param packageName
   * @return
   */
  public static Drawable appInfo_getIconFromPackageName(Context context, String packageName)
    {
        PackageManager pm = context.getPackageManager();       
        ApplicationInfo appInfo = null;
        try{
            appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
        }catch (NameNotFoundException e){
            return null;
        }

        return appInfo.loadIcon(pm);
    }
  
  /**
   * Gets the size of an APK.
   * 
   * @param installPath
   * @return
   */
  public static String appInfo_getSize(String installPath){
    File file = new File(installPath);
     
    String unit = "Bytes";
    double sizeInUnit = 0d;
     
    if (file.exists()) {
      double size = (double) file.length();
    
      if (size > 1024 * 1024 * 1024) { // Gigabyte
        sizeInUnit = size / (1024 * 1024 * 1024);
        unit = "GB";
      } else if (size > 1024 * 1024) { // Megabyte
        sizeInUnit = size / (1024 * 1024);
        unit = "MB";
      } else if (size > 1024) { // Kilobyte
        sizeInUnit = size / 1024;
        unit = "KB";
      } else { // Byte
        sizeInUnit = size;
      }
    }
     
    // only show two digits after the comma
    return new DecimalFormat("###.##").format(sizeInUnit) + " " + unit;
  }
  
  /**
   * Creates a application informative dialog with options to
   * uninstall/launch or cancel.
   * 
   * @param context
   * @param appPackage
   */
  public static void appInfo_getLaunchUninstallDialog(final Context context, String appPackage){
    
    try{
    
      final PackageManager packageManager = context.getPackageManager();
      final PackageInfo app = packageManager.getPackageInfo(appPackage, PackageManager.GET_META_DATA);
      
      
      AlertDialog dialog = new AlertDialog.Builder(context).create();
      
      dialog.setTitle(app.applicationInfo.loadLabel(packageManager));
      
      String description = null;
      if(app.applicationInfo.loadDescription(packageManager)!=null){
        description = app.applicationInfo.loadDescription(packageManager).toString();
      }      
      
      String msg = app.applicationInfo.loadLabel(packageManager) + "\n\n" +
        "Version " + app.versionName + " (" + app.versionCode + ")" +
         "\n" + (description!=null?(description+ "\n"):"") +
         app.applicationInfo.sourceDir + "\n" + appInfo_getSize(app.applicationInfo.sourceDir);
      dialog.setMessage(msg);
      
      dialog.setCancelable(true);    
      dialog.setButton(AlertDialog.BUTTON_NEUTRAL, "Cancel",
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            dialog.dismiss();          
          }
      });          
      dialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Uninstall",
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            Intent intent = new Intent(Intent.ACTION_DELETE);
            intent.setData(Uri.parse("package:" + app.packageName));
            context.startActivity(intent);          
          }
      });    
      dialog.setButton(AlertDialog.BUTTON_POSITIVE, "Launch",
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            Intent i = packageManager.getLaunchIntentForPackage(app.packageName);
            context.startActivity(i);                    
          }
      });
      
      dialog.show();
    }catch(Exception e){
      if(LOG_ENABLE){
        Log.e(TAG, "Dialog could not be made for the specified application '" + appPackage + "'. [" + e.getMessage() + "].", e);
      }
    }
  }
  

    /**
     * Allows to install a new icon for the application.
     *
     * This method need two additional permissions in the application:
     *
     * <code>
     *  <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
     * </code>
     *
     * @param context       The application context.
     * @param appMain       The application main class
     * @param appName       The application name
     * @param appIcon       The bitmap of the application icon. Can be null. If null, the
     *                      appIconResId must be provided.
     * @param appIconResId  Specify this only if no bitmap is set in the call to this method.
     */
    public static void application_shortcutAdd(Context context, Class appMain, String appName,
                                                  Bitmap appIcon, int appIconResId,
                                                  boolean removeCurrent) {

        // Intent launcher of the application
        Intent shortcutIntent = new Intent("android.intent.action.MAIN");
        shortcutIntent.addCategory("android.intent.category.LAUNCHER");
        shortcutIntent.setClass(context, appMain);
        shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        //Intent to add the new application icon.
        //
        // Decorate the shortcut
        Intent addIntent = new Intent();
        addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
        addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, appName);

        if(appIcon!=null) {
            addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, appIcon);
        }else if(appIconResId!=0) {
            addIntent.putExtra(
                    Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
                    Intent.ShortcutIconResource.fromContext
                            (
                                    context.getApplicationContext(),
                                    appIconResId
                            )
            );
        }

        // Inform launcher to create shortcut
        addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
        context.sendBroadcast(addIntent);
    }

    /**
     * Deletes a application desktop shortcut icon.
     *
     * This method need two additional permissions in the application:
     *
     * <code>
     *  <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
     * </code>
     *
     * @param context   The application context.
     * @param appClass  Shortcut's  activity class.
     * @param appName   The shortcut's name
     */
    public static void application_shortcutRemove_method1(Context context, Class appClass, String appName) {
        Intent shortcutIntent = new Intent(context, appClass);
        shortcutIntent.setAction(Intent.ACTION_MAIN);

        Intent delIntent = new Intent();
        delIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
        delIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, appName);

        // Inform launcher to remove shortcut
        delIntent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
        context.sendBroadcast(delIntent);
    }

    /**
     * Deletes a application desktop shortcut icon.
     *
     * Note:
     *  Manual way.
     *
     *  This method need two additional permissions in the application:
     *
     * <code>
     *  <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
     * </code>
     *
     * @param context   The application context.
     * @param appClass  Shortcut's  activity class.
     */
    public static void application_shortcutRemove_method2(Context context, Class appClass, String appName) {
        Intent intent = new Intent();
        String oldShortcutUri = "#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;package="+ appClass.getPackage().getName() + ";component=" + appClass.getPackage().getName() + "/." + appClass.getSimpleName() + ";end";
        try {
            Intent altShortcutIntent  = Intent.parseUri(oldShortcutUri,0);
            intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, altShortcutIntent);
            intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, appName);
            //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            //intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        } catch (URISyntaxException e) {}
        intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
        context.sendBroadcast(intent);
    }

    /**
     * Disables the component status of an Activity. If the activity has the
     * android.intent.category.LAUNCHER intent, it will remove the launcher icon
     * in the applications menu.
     *
     * @param context   The application context
     * @param appClass  Class of the activity
     */
    public static void application_activityDisable (Context context, Class appClass) {
        application_activityStatusSwitch(context, appClass, PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
    }

    /**
     * Enables the component status of an Activity. If the activity has the
     * android.intent.category.LAUNCHER intent, it will add the launcher icon
     * in the applications menu.
     *
     * @param context   The application context
     * @param appClass  Class of the activity
     */
    public static void application_activityEnable (Context context, Class appClass) {
        application_activityStatusSwitch(context, appClass, PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
    }

    /*
     * Enables or disables an activity component status.
     *
     * @param context   The application context
     * @param appClass  Class of the activity
     * @param status    The desired status.
     */
    private static void application_activityStatusSwitch (Context context, Class appClass, int status) {
        ComponentName component = new ComponentName(appClass.getPackage().getName(), appClass.getName());

        if(status == PackageManager.COMPONENT_ENABLED_STATE_DISABLED &&
                (context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_ENABLED ||
                 context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)) {
            context.getPackageManager().setComponentEnabledSetting(
                    component,
                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                    PackageManager.DONT_KILL_APP);

        }else if(status == PackageManager.COMPONENT_ENABLED_STATE_ENABLED &&
                (context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_DISABLED ||
                 context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)) {
            context.getPackageManager().setComponentEnabledSetting(
                    component,
                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                    PackageManager.DONT_KILL_APP);
        }
    }

    /**
     * Enables the component status of an Activity Alias. If the activity alias points to an
     * Activity with android.intent.category.LAUNCHER intent, it will add the launcher icon
     * in the applications menu.
     *
     * @param context
     * @param appClass
     * @param appLaunchAlias
     */
    public static void application_activityAliasEnable (Context context, Class appClass, String appLaunchAlias) {
        application_activityAliasStatusSwitch(context, appClass, appLaunchAlias, PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
    }

    /**
     * Disables the component status of an Activity Alias. If the activity alias points to an
     * Activity with android.intent.category.LAUNCHER intent, it will remove the launcher icon
     * in the applications menu.
     *
     * @param context           The application context
     * @param appClass          Class of the activity alias
     * @param appLaunchAlias    The android:name of the activity-alias entry in the manifest.
     */
    public static void application_activityAliasDisable (Context context, Class appClass, String appLaunchAlias) {
        application_activityAliasStatusSwitch(context, appClass, appLaunchAlias, PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
    }

    /**
     * Switches the component status of an Activity Alias. Use this to enable or disable it. If the
     * activity alias points to an Activity with android.intent.category.LAUNCHER intent, it will
     * remove/add the launcher icon in the applications menu.
     *
     * @param context           The application context
     * @param appClass          Class of the activity alias
     * @param appLaunchAlias    The android:name of the activity-alias entry in the manifest.
     */
    public static void application_activityAliasSwitchStatus (Context context, Class appClass, String appLaunchAlias) {
        ComponentName component = new ComponentName(appClass.getPackage().getName(), appClass.getPackage().getName() + "." + appLaunchAlias);
        if(context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
            application_activityAliasStatusSwitch(context, appClass, appLaunchAlias, PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
        }else if(context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_DISABLED){
            application_activityAliasStatusSwitch(context, appClass, appLaunchAlias, PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
        }
    }

    /*
     * Enables or disables an activity alias component status.
     *
     * @param context           The application context
     * @param appClass          Class of the activity alias
     * @param appLaunchAlias    The android:name of the activity-alias entry in the manifest.
     * @param status            The desired status.
     */
    private static void application_activityAliasStatusSwitch (Context context, Class appClass,
                                                               String appLaunchAlias, int status) {
        ComponentName component = new ComponentName(appClass.getPackage().getName(), appClass.getPackage().getName() + "." + appLaunchAlias);

        if(status == PackageManager.COMPONENT_ENABLED_STATE_DISABLED &&
                (context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_ENABLED ||
                context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)) {
            context.getPackageManager().setComponentEnabledSetting(
                    component,
                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                    PackageManager.DONT_KILL_APP);

        }else if(status == PackageManager.COMPONENT_ENABLED_STATE_ENABLED &&
                (context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_DISABLED ||
                context.getPackageManager().getComponentEnabledSetting(component)==PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)){
            context.getPackageManager().setComponentEnabledSetting(
                    component,
                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                    PackageManager.DONT_KILL_APP);
        }
    }

  /**
   * This method reads the info form the App. Manifest file.
   * 
   * @return
   */
  public static boolean application_isAppInDebugMode(Context context){
    boolean res=false;
    
    try{
      PackageInfo info = context.getPackageManager().getPackageInfo(context.getApplicationInfo().packageName, 0);
         
      int flags=info.applicationInfo.flags;
      if ((flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
          // development mode
        res=true;
      } else {
          // release mode
      }
    }catch(Exception e){
      if(LOG_ENABLE)
        Log.e("IS_DEBUG_MODE:ERROR",e.getMessage(),e);
    }
    
    return res;
  }
  
  /**
    * This method reads the info form the App. Manifest file.
    * 
    * @return
    */
   public static String application_getVersion(Context context){
    String res=null;
    
    try{
      PackageInfo info = context.getPackageManager().getPackageInfo(context.getApplicationInfo().packageName, 0);
         
      res = info.versionName;
    }catch(Exception e){
      if(LOG_ENABLE)
        Log.e("GET_APP_VERSION:ERROR",e.getMessage(),e);
    }
    
    return res;
   }
   
   /**
    * This method reads the info form the App. Manifest file.
    * 
    * @return
    */
   public static int application_getVersionCode(Context context){
    int res=-1;
    
    try{
      PackageInfo info = context.getPackageManager().getPackageInfo(context.getApplicationInfo().packageName, 0);
         
      res = info.versionCode;
    }catch(Exception e){
      if(LOG_ENABLE)
        Log.e("GET_APP_VERSION:ERROR",e.getMessage(),e);
    }
    
    return res;
   }
   
   public static boolean application_isCallable(Activity activity, Intent intent) {
      List<ResolveInfo> list = activity.getPackageManager().queryIntentActivities(intent,PackageManager.MATCH_DEFAULT_ONLY);
      return list.size() > 0;
   }

   
   /**
   * Returns a list with the current signatures of the 
   * application.
   * 
   * @param context  Application context
   * @param appPackageName  The package name of the application.
   * @return  A list or null if no signatures are found or error.
   */
  public static List<String> application_getSignatures (Context context, String appPackageName) {
    List<String> appSignatures = null;
    
    try {
      if(appPackageName!=null && appPackageName.length()>0) {
            PackageInfo info = context.getPackageManager().getPackageInfo(
                appPackageName, PackageManager.GET_SIGNATURES);
            appSignatures = new ArrayList<String>();
            String signatureString = null;
            for (Signature signature : info.signatures) {
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(signature.toByteArray());
                signatureString = android.util.Base64.encodeToString(md.digest(), android.util.Base64.DEFAULT);
                Log.d(ToolBox.TAG, "KeyHash (" + appPackageName + "): " + signatureString);
                appSignatures.add(signatureString);
            }
      }else{
        Log.d(ToolBox.TAG, "No package name to get signaturs from.");
      }
      } catch (NameNotFoundException e) {
        Log.e(ToolBox.TAG, "Error getting application (" + appPackageName + ") signatures. Package not found [" + e.getMessage() + "].", e);
      } catch (NoSuchAlgorithmException e) {
        Log.e(ToolBox.TAG, "Error getting application (" + appPackageName + ") signatures. Algorithm SHA not found [" + e.getMessage() + "].", e);
      }
    
    return appSignatures;
  }

    //-------------------- ACTIVITY-----------------------------------------------------------------------

    /**
     * This method changes the ActionBar Icon.
     *
     * Requires API level 14 or higher.
     *
     * @param context
     * @param activity  Should be a ActionBarActivity of support compatibility pack.
     * @param iconResourceId
     */
   public static void activity_actionBar_changeIcon(Context context, ActionBarActivity activity, int iconResourceId){
        activity.getSupportActionBar().setIcon(iconResourceId);
   }

    /**
     * Converts the ActionBar icon to Back icon mode. Must be used
     * in the onCreate method.
     *
     * Requires API level 14 or higher.
     *
     * @param context
     * @param activity  Should be a ActionBarActivity of support compatibility pack.
     * @param iconResourceId
     */
   public static void activity_actionBar_enableBackButton(Context context, ActionBarActivity activity, int iconResourceId){
        activity.getSupportActionBar().setHomeButtonEnabled(true);
        activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
   }


  //-------------------- DIALOGS ------------------------------------------------------------------------
   
   /**
    * creates an exit popup dialog.
    * 
    * @param context
    * @param title
    * @param message
    * @param yesLabel
    * @param cancelLabel
    */
   public static void dialog_showExitConfirmationDialog(final Context context, 
                            int title, int message, int yesLabel, int cancelLabel){
     new AlertDialog.Builder(context)
          .setIcon(android.R.drawable.ic_dialog_alert)
          .setTitle(context.getResources().getString(title))
          .setMessage(context.getResources().getString(message))
          .setPositiveButton(context.getResources().getString(yesLabel), new DialogInterface.OnClickListener()
      {
          
          public void onClick(DialogInterface dialog, int which) {
            ((Activity)context).finish();    
          }

      })
      .setNegativeButton(context.getResources().getString(cancelLabel), null)
      .show();
   }
   
   /**
    * Creates an alert with an OK button.
    * 
    * @param context
    * @param msgResourceId
    */
   public static void dialog_showAlertOkDialog(Context context, int titleResourceId, int msgResourceId){
     AlertDialog.Builder builder = new AlertDialog.Builder(context);
      builder.setMessage(context.getResources().getString(msgResourceId))
             .setCancelable(false)
             .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int id) {
                      dialog.cancel();
                 }
             });
      
      if(titleResourceId!=0){
        builder.setTitle(context.getResources().getString(titleResourceId));
      }
      
      AlertDialog alert = builder.create();
      alert.show();
   } 
   
   /**
    * Creates an alert with an OK button.
    * 
    * @param context
    * @param message
    */
   public static void dialog_showAlertOkDialog(Context context, String tittle, String message){
     AlertDialog.Builder builder = new AlertDialog.Builder(context);
      builder.setMessage(message)
             .setCancelable(false)
             .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                 public void onClick(DialogInterface dialog, int id) {
                      dialog.cancel();
                 }
             });
      
      if(tittle!=null && tittle.length()>0){
        builder.setTitle(tittle);
      }
      
      AlertDialog alert = builder.create();
      alert.show();
   }
   
   /**
    * Creates and shows a custom Alert dialog that will execute
    * the actions specified for positive, negative and 
    * neutral buttons.
    * 
    * @param context
    * @param title
    * @param message
    * @param positiveBtnActions  Can be null. When null button is not shown.
    * @param negativeBtnActions  Can be null. When null button is not shown.
    * @param neutralBtnActions  Can be null.
    */
   public static void dialog_showCustomActionsDialog(Context context, String title, String message, 
       String positiveBtnText, final Runnable positiveBtnActions, 
       String negativeBtnText, final Runnable negativeBtnActions, 
       String neutralBtnText, final Runnable neutralBtnActions){
     
    AlertDialog dialog = new AlertDialog.Builder(context).create();
      
    dialog.setTitle(title);      
    dialog.setMessage(message);
    
    dialog.setCancelable(true);      
    dialog.setButton(AlertDialog.BUTTON_NEUTRAL, neutralBtnText,
    new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
          if(neutralBtnActions!=null){
            neutralBtnActions.run();
          }
          dialog.dismiss();          
        }
    });    
    
    if(negativeBtnActions!=null){
      dialog.setButton(AlertDialog.BUTTON_NEGATIVE, negativeBtnText,
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            negativeBtnActions.run();          
          }
      });    
    }
    
    if(positiveBtnActions!=null){
      dialog.setButton(AlertDialog.BUTTON_POSITIVE, positiveBtnText,
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            positiveBtnActions.run();                    
          }
      });
    }
    
    dialog.show();
   }
   
   /**
    * Opens a url in an alert dialog.
    * 
    * @param context
    * @param title
    * @param url
    */
   public static void dialog_showUrlInDialog(Context context, String title, String url){
     AlertDialog.Builder alert = new AlertDialog.Builder(context);
     alert.setTitle(title);
     WebView wv = new WebView(context);
     wv.loadUrl(url);
     wv.setHorizontalScrollBarEnabled(false);
     alert.setView(wv);
     alert.setNegativeButton("Close", null);
     alert.show();
   }
   
   /**
    * "Coach mark" (help overlay image)
    * 
    * @param context
    * @param coachMarkLayoutId  Is "Help overlay" layout id in UX talk :-) 
    *         [coach_mark.xml is your coach mark layout]
    * @param coachMarkMasterViewId  is the id of the top most view in coach_mark.xml
    */
   public static void dialog_onCoachMark(Context context, int coachMarkLayoutId, int coachMarkMasterViewId, int bgColor){

      final Dialog dialog = new Dialog(context);
      dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
      dialog.getWindow().setBackgroundDrawable(new ColorDrawable(bgColor));
      dialog.setContentView(coachMarkLayoutId);
      dialog.setCanceledOnTouchOutside(true);
      
      //for dismissing anywhere you touch
      View masterView = dialog.findViewById(coachMarkMasterViewId);
      masterView.setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View view) {
              dialog.dismiss();
          }
      });
      
      dialog.show();
  }
   
   /**
    * Shows a Toast alert.
    * 
    * @param context
    * @param message
    * @param centerOnScreen  Set to TRUE to center on the screen.
    */
   public static void dialog_showToastAlert(Context context, String message, boolean centerOnScreen) {
     Toast msg = Toast.makeText(context, message, Toast.LENGTH_SHORT);
     if(centerOnScreen){
       msg.setGravity(Gravity.CENTER, msg.getXOffset() / 2, msg.getYOffset() / 2);
     }
     msg.show();
   }
  
  //-------------------- GRAPHICS ----------------------------------------------------------------------
   
   public static Bitmap graphics_addWaterMarkToImage(Bitmap src, String watermark, Point location, int size, boolean underline) {
     Bitmap result = null;
     
     try{
       int w = src.getWidth();
        int h = src.getHeight();
        result = Bitmap.createBitmap(w, h, src.getConfig());
     
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(src, 0, 0, null);
     
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        //paint.setAlpha(alpha);
        paint.setTextSize(size);
        paint.setAntiAlias(true);
        paint.setUnderlineText(underline);
        canvas.drawText(watermark, location.x, location.y, paint);
     }catch(Exception e){
       result = null;
       if(LOG_ENABLE) 
            Log.e(TAG, "ERROR: graphics_addWaterMarkToImage() [" + e.getMessage()+"]", e);
     }
     
     return result;
  }
   
   
   
   
  //-------------------- VIEWS -------------------------------------------------------------------------
   
   public static void view_showAboutDialog(Context context, int titleResourceId, int aboutLayout, int okButtonId){    
    final Dialog dialog = new Dialog(context);
    dialog.setContentView(aboutLayout);
    dialog.setTitle(titleResourceId);
    
    Button dialogButton = (Button) dialog.findViewById(okButtonId);
    dialogButton.setOnClickListener(new OnClickListener() {
      
      public void onClick(View v) {
        dialog.dismiss();
      }
    });

    dialog.show();  
  }
  
  //SYSTEM NOTIFICATIONS ---------------------------------------------------------------------------------------------------------------------
  
  /**
   * Creates a system notification.
   *    
   * @param context        Context.
   * @param notSound        Enable or disable the sound
   * @param notSoundRawId      Custom raw sound id. If enabled and not set 
   *                 default notification sound will be used. Set to -1 to 
   *                 default system notification.
   * @param multipleNot      Setting to True allows showing multiple notifications.
   * @param groupMultipleNotKey  If is set, multiple notifications can be grupped by this key.
   * @param notAction        Action for this notification
   * @param notTitle        Title
   * @param notMessage      Message
   * @param notClazz        Class to be executed
   * @param extras        Extra information
   * 
   */
    public static void notification_generate(Context context, 
        boolean notSound, int notSoundRawId, 
        boolean multipleNot, String groupMultipleNotKey, 
        String notAction, 
        String notTitle, String notMessage, 
        Class<?> notClazz, Bundle extras,
        boolean wakeUp) {
        
    try {
      int iconResId = notification_getApplicationIcon(context);      
      long when = System.currentTimeMillis();
                              
          Notification notification = new Notification(iconResId, notMessage, when);
          
          // Hide the notification after its selected
          notification.flags |= Notification.FLAG_AUTO_CANCEL;  
          
          if(notSound){   
            if(notSoundRawId>0 ){
              try {           
                notification.sound = Uri.parse("android.resource://" + context.getApplicationContext().getPackageName() + "/" + notSoundRawId);
              }catch(Exception e){
                if(LOG_ENABLE){
                  Log.w(TAG, "Custom sound " + notSoundRawId + "could not be found. Using default.");
                }
                notification.defaults |= Notification.DEFAULT_SOUND;
                notification.sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
              }
            }else{
              notification.defaults |= Notification.DEFAULT_SOUND;
              notification.sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            }
          }
          
          Intent notificationIntent = new Intent(context, notClazz);
          notificationIntent.setAction(notClazz.getName()+"."+notAction);
          if(extras!=null){
            notificationIntent.putExtras(extras);
          }          
                   
          //Set intent so it does not start a new activity
          //
          //Notes:
          //  - The flag FLAG_ACTIVITY_SINGLE_TOP makes that only one instance of the activity exists(each time the
          //     activity is summoned no onCreate() method is called instead, onNewIntent() is called.
          //  - If we use FLAG_ACTIVITY_CLEAR_TOP it will make that the last "snapshot"/TOP of the activity it will 
          //    be this called this intent. We do not want this because the HOME button will call this "snapshot". 
          //    To avoid this behaviour we use FLAG_ACTIVITY_BROUGHT_TO_FRONT that simply takes to foreground the 
          //    activity.
          //
          //See http://developer.android.com/reference/android/content/Intent.html          
          notificationIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
          
          
          PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
          
          int REQUEST_UNIQUE_ID = 0;
          if(multipleNot){
            if(groupMultipleNotKey!=null && groupMultipleNotKey.length()>0){
              REQUEST_UNIQUE_ID = groupMultipleNotKey.hashCode();
            }else{
              if(random==null){
                random = new Random();
              }
              REQUEST_UNIQUE_ID = random.nextInt();
            }
            PendingIntent.getActivity(context, REQUEST_UNIQUE_ID , notificationIntent, PendingIntent.FLAG_ONE_SHOT);
          }
                          
          notification.setLatestEventInfo(context, notTitle, notMessage, intent);
          
          //This makes the device to wake-up is is idle with the screen off.
          if(wakeUp){
            powersaving_wakeUp(context);
          }
          
          NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
          
          //We check if the sound is disabled to enable just for a moment
          AudioManager amanager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
          int previousAudioMode = amanager.getRingerMode();;
          if(notSound && previousAudioMode!=AudioManager.RINGER_MODE_NORMAL){            
            amanager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
          }
          
          notificationManager.notify(REQUEST_UNIQUE_ID, notification);
          
          //We restore the sound setting
          if(previousAudioMode!=AudioManager.RINGER_MODE_NORMAL){
            //We wait a little so sound is played
            try{
              Thread.sleep(3000);
            }catch(Exception e){}            
          }
          amanager.setRingerMode(previousAudioMode);
      
          Log.d(TAG, "Android Notification created.");
          
    } catch (Exception e) {
      if(LOG_ENABLE)
        Log.e(TAG, "The notification could not be created (" +e.getMessage() + ")", e);
    }        
    }
    
    /*
     * Gets the application Icon.
     *  
     * @param context
     * @return
     * @throws ApplicationPackageNotFoundException
     */
    private static int notification_getApplicationIcon(Context context) throws Exception{
      try {
      ApplicationInfo app = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
      return app.icon;
      
    } catch (NameNotFoundException e) {
      if(LOG_ENABLE)
        Log.e(TAG, "Application package not found!.");
      
      throw e;
    }
    }
   
  
    // Power saving ----------------------------------------------------------------------------------------------------------------------------
    
    /*
     * Makes the device to wake-up. yeah!
     * 
     * Requires the permission android.permission.WAKE_LOCK
     *  
     * @param ctx
     */
    public static void powersaving_wakeUp(Context ctx) {
            
      if (wakeLock != null) wakeLock.release();

        PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
                PowerManager.ACQUIRE_CAUSES_WAKEUP |
                PowerManager.ON_AFTER_RELEASE, "javocsoft_library_wakeup");
        wakeLock.acquire();
    }
    
  // Net Related -----------------------------------------------------------------------------------------------------------------------------
  
  /**
   * Makes a Http operation.
   * 
   * This method set a parameters to the request that avoid being waiting 
   * for the server response or once connected, being waiting to receive 
   * the data.
   * 
   * @param method    Method type to execute. @See HTTP_METHOD.
   * @param url      Url of the request.
   * @param jsonData    The body content of the request (JSON). Can be null.
   * @param headers    The headers to include in the request.
   * @return The content of the request if there is one.
   * @throws Exception
   */
  public static String net_httpclient_doAction(HTTP_METHOD method, String url, String jsonData, Map<String, String> headers) throws ConnectTimeoutException, SocketTimeoutException, Exception{
      String responseData = null;
    
    DefaultHttpClient httpclient = new DefaultHttpClient();
      
      // The time it takes to open TCP connection.
    httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_DEFAULT_TIMEOUT);
        // Timeout when server does not send data.
    httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, CONNECTION_DEFAULT_DATA_RECEIVAL_TIMEOUT);
        // Some tuning that is not required for bit tests.
    //httpclient.getParams().setParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false);
    httpclient.getParams().setParameter(CoreConnectionPNames.TCP_NODELAY, true);
      
      HttpRequestBase httpMethod = null;      
      switch(method){
      case POST:
        httpMethod = new HttpPost(url);
        //Add the body to the request.
          StringEntity se = new StringEntity(jsonData);
          ((HttpPost)httpMethod).setEntity(se);
        break;
      case DELETE:
        httpMethod = new HttpDelete(url);
        break;
      case GET:
        httpMethod = new HttpGet(url);
        break;
      }
      
      //Add the headers to the request.
      if(headers!=null){
        for(String header:headers.keySet()){
          httpMethod.setHeader(header, headers.get(header));
        }        
      }
      
      HttpResponse response = httpclient.execute(httpMethod);
      if(LOG_ENABLE) {
        Log.d(TAG, "HTTP OPERATION: Read from server - Status Code: " + response.getStatusLine().getStatusCode());
        Log.d(TAG, "HTTP OPERATION: Read from server - Status Message: " + response.getStatusLine().getReasonPhrase());
    }
      
      //Get the response body if there is one.
      HttpEntity entity = response.getEntity();
      if (entity != null) {
        //responseData = EntityUtils.toString(entity, "UTF-8");
          
        InputStream instream = entity.getContent();
          responseData = IOUtils.convertStreamToString(instream);
          
          if(LOG_ENABLE)
            Log.i(TAG, "HTTP OPERATION: Read from server - return: " + responseData);
      }
      
      if (response.getStatusLine().getStatusCode() != 200) {
        throw new Exception("Http operation "+method.name()+" failed with error code " + 
            response.getStatusLine().getStatusCode() + "("+ 
            response.getStatusLine().getReasonPhrase() +")");
      }
      
      return responseData;
    } 
   
   public static boolean net_isNetworkAvailable(Context context) {
         ConnectivityManager connectivityManager 
               = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
         NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
         return activeNetworkInfo != null && activeNetworkInfo.isConnected();
   }
   
   /**
   * Gets the network carrier.
   *
   * If the device is an emulator returns "EMU", if no SIM is present returns
   * NOSIM.
   *
   * @See NETWORK_PROVIDER.
   *
   * @param ctx
   * @return
   */
  public static NETWORK_PROVIDER net_getCurrentNetworkOperator(Context ctx) {
    final String emulatorDevice = "Android";
    final String noSIMDevice = "";

    // if(Debug.isDebuggerConnected()){}

    TelephonyManager tm = (TelephonyManager) ctx
        .getSystemService(Context.TELEPHONY_SERVICE);
    String networkOperator = tm.getNetworkOperatorName();
    if (emulatorDevice.equalsIgnoreCase(networkOperator)) {
      return NETWORK_PROVIDER.EMU;
    } else if (emulatorDevice.equalsIgnoreCase(noSIMDevice)) {
      return NETWORK_PROVIDER.NOSIM;
    } else {
      try {
        return NETWORK_PROVIDER.valueOf(networkOperator.toUpperCase());
      } catch (Exception e) {
        // Non expected network provider.
        return NETWORK_PROVIDER.UNKNOWN;
      }
    }
  }
   
  
  // Storage Related -----------------------------------------------------------------------------------------------------------------------------
  
  public static byte[] storage_readAssetResource(Context context, String fileName){
    
     try{
       InputStream asset = context.getAssets().open(fileName);
       
       ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
       
       byte[] buffer = new byte[asset.available()];
         
       asset.read(buffer);            
         byteArrayOutputStream.write(buffer);
         asset.close();
     
         return byteArrayOutputStream.toByteArray();
     }catch (Exception e){
       if(LOG_ENABLE)
         Log.e("TollBox_ERROR","storage_readRawResource() Error obtaining raw data: " + e.getMessage(),e);   
         return null;
     }
  }
  
   public static byte[] storage_readRawResource(Context context, String fileName){
     int resId = context.getResources().getIdentifier(fileName,"raw", context.getPackageName());
     
     try{
       InputStream raw = context.getResources().openRawResource(resId);
       
       ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
       
       byte[] buffer = new byte[raw.available()];
         
       raw.read(buffer);            
         byteArrayOutputStream.write(buffer);
         raw.close();
     
         return byteArrayOutputStream.toByteArray();
     }catch (Exception e){
       if(LOG_ENABLE)
         Log.e("TollBox_ERROR","storage_readRawResource() Error obtaining raw data: " + e.getMessage(),e);   
         return null;
     }
   }
   
   
   /**
    * This method returns the application external folder. All the stuff
    * saved in this folder is deleted when the application is uninstalled.
    * 
    * If the SD folder is not mounted null is returned.
    * 
    * @param app      Application context.
    * @param folder    The type of files directory to return. 
    *           May be null for the root of the app. data directory or 
    *           some folder value.
    * 
    * @return
    */
   public static File storage_getAppExternalStorageFolder(Application app, String folder){
     File res=null;
     if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
       res=app.getExternalFilesDir(folder);
     }
     return res;
   }
   
   /**
    * This function returns a File object pointing to the specified folder. If none is
    * specified, root dir of the SD is returned.
    * 
    * Returns null if the media is not mounted.    
    * 
    * @param folderType  The type of files directory to return. 
    *           May be null to get the root of the SD or 
    *           any of the Environment.DIRECTORY_ options.
      *
    * @return
    */
   public static File storage_getExternalFolder(String folderType){
     File res=null;
     if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
        res=new File(Environment.getExternalStorageDirectory(),folderType);
     }
     return res;
   }
      
   /**
    * This function returns a File object pointing to a public folder of the the specified 
    * type in the external drive.
    * 
    * User media is saved here. Be carefull.
    *     
    * Returns null if the media is not mounted.
    * 
    * @param folderType  The type of files directory to return. Use one of the avaliable
    *           Environment.DIRECTORY_ values.
    * @param folder    An specific folder in the public folder. May be null to get 
    *           the root of the public folder type.
    * @param createFolder  Set to TRUE to create the folder if it does not exists.  
    *           
    * @return
    */
   public static File storage_getExternalPublicFolder(String folderType, String folder, boolean createFolder){
     File res=null;
     if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
        res=new File(Environment.getExternalStoragePublicDirectory(folderType),folder);
        
        if(!res.exists()){
          //We create the folder if is desired.
          if(folder!=null && folder.length()>0 && createFolder){
           if(!res.mkdir()){
             res = null;
           }
          }else{
            res = null;
          }
        }
     }
     return res;
   }
    
   
    /**
     * Saves the content of the specified input stream into the outputFile.
     * 
     * @param is
     * @param outputFile
     * @param closeInput
     */
    public static void storage_saveInputData(InputStream is, File outputFile, boolean closeInput) throws Exception{
        try{
        OutputStream os = new FileOutputStream(outputFile);               
          storage_copyStream(is, os, 1024);
          os.close();
          if(closeInput){
            is.close();
          }
        }catch(Exception e){
          if(LOG_ENABLE)
            Log.e(TAG,"storage_saveInputData(): "+e.getMessage(),e);
          
          throw new Exception(TAG+"[storage_saveInputData()]: "+e.getMessage(),e);     
        }
    }
   
  /**
   * Gets the application internal storage path.
   * 
   * @param context
   * @param file
   * @return
   */
   public static File storage_getAppInternalStorageFilePath(Context context, String file){
     String filePath = context.getFilesDir().getAbsolutePath();//returns current directory.
     if(file==null){
       return new File(filePath);
     }else{
       return new File(filePath, file);
     }
   }
   
  /**
   * Reads a text file returning its contents as an string.
   *  
   * @param file
   * @return
   * @throws Exception
   */
  public static String storage_getTextFileContentAsString(String file, String encoding) throws Exception{
    String res;
    
    try{
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding));
      
      String read;
      StringBuilder builder = new StringBuilder("");
      
      while((read = bufferedReader.readLine()) != null){
        builder.append(read + "\n");
      }
      
      res = builder.toString();      
      bufferedReader.close();
      
    }catch(Exception e){
          if(LOG_ENABLE)
            Log.e(TAG,"storage_getTextFileContentAsString(): "+e.getMessage(),e);
          
          throw new Exception(TAG+"[storage_getTextFileContentAsString()]: "+e.getMessage(),e);     
        }
    
    return res;
  }
  
  /**
   * This method copies the input to the specified output.
   * 
   * @param is  Input source
   * @param os  Output destiny
   * @return    Total bytes read
   */
    public static int storage_copyStream(InputStream is, OutputStream os, int buffer_size) throws IOException{
      int readbytes=0;
      
        if(buffer_size<=0){
          buffer_size=1024;
        }
        
        try{
            byte[] bytes=new byte[buffer_size];
            for(;;){
              int count=is.read(bytes, 0, buffer_size);
              if(count==-1)
                  break;
              os.write(bytes, 0, count);
              readbytes+=count;
            }
        }catch(Exception e){
          throw new IOException("Failed to save data ("+e.getMessage()+").",e);
        }
        
        return readbytes;
    }
    
  /**
   * Saves data to the application internal folder.
   * 
   * @param context
   * @param fileName
   * @param data
   * @throws Exception
   */
  public static synchronized void storage_storeDataInInternalStorage(Context context, String fileName, byte[] data) throws Exception{
     try {
       /* We have to use the openFileOutput()-method
          * the ActivityContext provides, to
          * protect your file from others and
          * This is done for security-reasons.
          * We chose MODE_WORLD_READABLE, because
          *  we have nothing to hide in our file */             
          FileOutputStream fOut = context.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
         
          // Write the string to the file
          fOut.write(data);
  
          /* ensure that everything is really written out and close */
          fOut.flush();
          fOut.close();
          
     } catch (Exception e) {
        throw new Exception("Error saving data to '" + fileName + "' (internal storage) : "+ e.getMessage(),e);
     } 
   }
   
  /**
   * Reads data from the application internal storage data folder.
   * 
   * @param context
   * @param fileName
   * @return
   * @throws Exception
   */
  public static byte[] storage_readDataFromInternalStorage(Context context, String fileName) throws Exception{
    FileInputStream fIn;
    
    try {
      fIn = context.openFileInput(fileName);
      
      byte[] buffer = new byte[fIn.available()];
       
      fIn.read(buffer);
      fIn.close();
       
      return buffer;
      
    } catch (Exception e) {
      throw new Exception("Error reading data '" + fileName + "' (internal storage) : "+ e.getMessage(),e);
    }
   }
  
  /**
   * Deletes a file from the application internal storage private folder.
   * 
   * @param context
   * @param fileName
   * @throws Exception
   */
  public static void storage_deleteDataFromInternalStorage(Context context, String fileName) throws Exception{
      
     try {
      context.deleteFile(fileName);        
     } catch (Exception e) {
      throw new Exception("Error deleting data '" + fileName + "' (internal storage) : "+ e.getMessage(),e);
     }
   }
   
   /**
    * Checks if a file exists in the application internal private data folder.
    * 
    * @param context
    * @param fileName
    * @return
    */
   public static boolean storage_checkIfFileExistsInInternalStorage(Context context, String fileName){
    
      try {
        context.openFileInput(fileName);
        
        return true;
      } catch (FileNotFoundException e) {
        return false;
      }
   }
  
  /**
   * Saves an URL link into the external SD card of the Device.
   * 
   * @param dataUrl
   * @param fileName
   * @param bufferSize
   * @return
   * @throws Exception
   */
  public static String storage_saveUrlToExternal(String dataUrl, String fileName, int bufferSize) throws Exception{
    String res;
    
    InputStream input = null;
    OutputStream output = null;
    
    try {    
      URL url = new URL (dataUrl);
      input = url.openStream();
      
      //The sdcard directory '/sdcard' can be used directly but is
      //better and safety if we use "getExternalStorageDirectory()" :)
        File storagePath = Environment.getExternalStorageDirectory();
        File f = new File(storagePath, fileName);
        output = new FileOutputStream (f);
        
          byte[] buffer = new byte[bufferSize];
          int bytesRead = 0;
          while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
              output.write(buffer, 0, bytesRead);
          }
          
          res = f.getAbsolutePath();
    }catch(Exception e){
      throw new Exception("Error saving data in external storage : "+ e.getMessage(),e);
      } finally {
        try{
          input.close();
          output.close();
        }catch(Exception e){}
      }
     
    return res;
  }
  
  /**
   * Saves the Url link into the internal memory card in the application private zone.
   * 
   * @param context
   * @param dataUrl
   * @param bufferSize
   * @return
   * @throws Exception
   */
  public static String storage_saveUrlToInternal(Context context, String dataUrl, int bufferSize) throws Exception{
    String res = null;
    
    try{
      String filename = String.valueOf(dataUrl.hashCode()+
            dataUrl.substring(dataUrl.lastIndexOf("."),dataUrl.length()) );
      
      if(!storage_checkIfFileExistsInInternalStorage(context, filename)){
        
        URL url = new URL (dataUrl);
        InputStream input = url.openStream();
        
          ByteArrayOutputStream output = new ByteArrayOutputStream ();
          try {
              byte[] buffer = new byte[bufferSize];
              int bytesRead = 0;
              while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
                  output.write(buffer, 0, bytesRead);
              }
          } finally {
              output.close();
          }
          
          byte[] data = output.toByteArray();
          
          storage_storeDataInInternalStorage(context, filename, data);
      }
        
        res = filename;
    } catch (Exception e) {
      throw new Exception("Error saving data in internal storage : "+ e.getMessage(),e);
    }    
    
    return res;
  }
  
  /**
   * 
   * @param context
   * @param dataUrl
   * @param bufferSize
   * @param watermark
   * @param watermark_underlined
   * @return
   * @throws Exception
   */
  public static String storage_saveImageUrlToInternalAddingWatermark(Context context, String dataUrl, int bufferSize, String watermark, boolean watermark_underlined) throws Exception{
    String res = null;
    
    try{
      String filename = String.valueOf(dataUrl.hashCode()+
            dataUrl.substring(dataUrl.lastIndexOf("."),dataUrl.length()) );
      
      if(!storage_checkIfFileExistsInInternalStorage(context, filename)){
        
        URL url = new URL (dataUrl);
        InputStream input = url.openStream();
        
          ByteArrayOutputStream output = new ByteArrayOutputStream ();
          try {
              byte[] buffer = new byte[bufferSize];
              int bytesRead = 0;
              while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
                  output.write(buffer, 0, bytesRead);
              }
          } finally {
              output.close();
          }
          
          byte[] data = output.toByteArray();
          
          //Add watermark --------------------------------------------------------------------------------
          try{
            Bitmap image = BitmapFactory.decodeByteArray(data, 0, data.length);
            Bitmap imageW = graphics_addWaterMarkToImage(image, watermark, new Point(5,image.getHeight()-5), 
                24, watermark_underlined);
            if(imageW!=null){
              //Get modified image bytes to save it
              ByteArrayOutputStream stream = new ByteArrayOutputStream();
              imageW.compress(Bitmap.CompressFormat.PNG, 100, stream);
              data = stream.toByteArray();
              
              stream.close();
            }
          }catch(Exception e){} //Nothing needs to be done.
          //----------------------------------------------------------------------------------------------
                    
          storage_storeDataInInternalStorage(context, filename, data);
      }
        
        res = filename;
    } catch (Exception e) {
      throw new Exception("Error saving data in internal storage : "+ e.getMessage(),e);
    }    
    
    return res;
  }
  
  /**
   * Return a temporal empty file.
   * 
   * @param filePrefix
   * @param fileSuffix
   * @param outputDirectory
   * @return
   * @throws java.io.IOException
   */
  public static File storage_createUniqueFileName(String filePrefix, String fileSuffix, File outputDirectory) throws IOException {
      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
      String fileName = filePrefix + timeStamp;
      File filePath = File.createTempFile(fileName, fileSuffix, outputDirectory);
      if(filePath.exists()){
        return filePath;
      }else{
        return null;
      }      
  }
  
  
  //--------------- PREFS ---------------------------------------------------------------------------
  
  public static boolean prefs_savePreference(Context ctx, String prefName, String key, Class<?> valueType, Object value){
    boolean res = false;
    
    SharedPreferences prefs = ctx.getSharedPreferences(
        prefName, Context.MODE_PRIVATE);
    
    if(value==null){
      prefs.edit().remove(key).commit();
    }else{
      if(valueType == Long.class){
        res = prefs.edit().putLong(key, (Long)value).commit();
      }else if(valueType == Boolean.class){
        res = prefs.edit().putBoolean(key, (Boolean)value).commit();
      }else if(valueType == Float.class){
        res = prefs.edit().putFloat(key, (Float)value).commit();
      }else if(valueType == Integer.class){
        res = prefs.edit().putInt(key, (Integer)value).commit();
      }else if(valueType == String.class){
        res = prefs.edit().putString(key, (String)value).commit();
      }else if(valueType == Set.class){
        if(((Set<String>)value).size()==0){
          prefs.edit().remove(key).commit();
        }else{
          //res = prefs.edit().putStringSet(key, (Set<String>)value).commit(); //Only from 11 API level.
          res = saveSetListAsCommaSeparatedString(ctx, prefName, key, (Set<String>)value);
        }
      }
    }
    
    return res;
  }
  
  public static Object prefs_readPreference(Context ctx, String prefName, String key, Class<?> valueType){
    SharedPreferences prefs = ctx.getSharedPreferences(
        prefName, Context.MODE_PRIVATE);
    
    if(valueType == Long.class){
      return prefs.getLong(key, Long.valueOf(-1));
    }else if(valueType == Boolean.class){
      return prefs.getBoolean(key, Boolean.valueOf(false));
    }else if(valueType == Float.class){
      return prefs.getFloat(key, Float.valueOf(-1));
    }else if(valueType == Integer.class){
      return prefs.getInt(key, Integer.valueOf(-1));
    }else if(valueType == String.class){
      return prefs.getString(key, null);
    }else if(valueType == Set.class){
      //return prefs.getStringSet(key, null); //Only from 11 API level.
      return getSetListFromCommaSeparatedString(ctx, prefName, key);
    }    
    
    return null;
  }
  
  /**
   * Tells if the preferemce exists.
   * 
   * @param ctx
   * @param prefName
   * @param key
   * @return
   */
  public static Boolean prefs_existsPref(Context ctx, String prefName, String key){
    SharedPreferences prefs = ctx.getSharedPreferences(
        prefName, Context.MODE_PRIVATE);
    
    if(prefs.contains(key)){
      return true;
    }else{
      return false;
    }    
  }
    
  /*
   * This method is for compatibility mode because SharedPreferences only works with
   * Set data values starting at API Level 11.
   *  
   * @param context
   * @param prefName
   * @param key
   * @return
   */
  private static Set<String> getSetListFromCommaSeparatedString(Context context, String prefName, String key){
    Set<String> res = new HashSet<String>();
    String resString = (String)ToolBox.prefs_readPreference(context, prefName, key, String.class);
        if(resString!=null && resString.length()>0){
        res = new HashSet<String>(Arrays.asList(resString.split(",")));
        }
        
    return res;
  }
  
  /*
   * This method is for compatibility mode because SharedPreferences only works with
   * Set data values starting at API Level 11.
   * 
   * @param context
   * @param prefName
   * @param key
   * @param value
   * @return
   */
  private static boolean saveSetListAsCommaSeparatedString(Context context, String prefName, String key, Set<String> value){
    boolean res = false;
    
    if(value!=null && value.size()>0){
      StringBuffer buff = new StringBuffer();
      int pos = 0;
      for(String s:value){
        if(pos>0){
          buff.append(",");
        }
        buff.append(s);
        pos++;
      }
      
      String data = buff.toString();
      if(data!=null && data.length()>0){
        res = prefs_savePreference(context, prefName, key, String.class, data);
      }
    }
    
    return res;
  }
  
  //--------------- SHARE ---------------------------------------------------------------------------
  
  
  /**
   * Allows to create a share intent and it can be launched.
   * 
   * @param context
   * @param type    Mime type.
   * @param nameApp  You can filter the application you want to share with. Use "wha", "twitt", etc.
   * @param title    The title of the share.Take in account that sometimes is not possible to add the title.
   * @param data    The data, can be a file or a text.
   * @param isBinaryData  If the share has a data file, set to TRUE otherwise FALSE.
   */
  @SuppressLint("DefaultLocale")
  public static Intent share_newSharingIntent(Context context, String type, String nameApp, String title, String data, boolean isBinaryData, boolean launch) {
      
    Intent res = null;
    
      Intent share = new Intent(Intent.ACTION_SEND);
      share.setType(type);
      
      List<Intent> targetedShareIntents = new ArrayList<Intent>();
      List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(share, 0);
      if (!resInfo.isEmpty()){
          for (ResolveInfo info : resInfo) {
              Intent targetedShare = new Intent(Intent.ACTION_SEND);
              targetedShare.setType(type);

              if(title!=null){
                targetedShare.putExtra(Intent.EXTRA_SUBJECT, title);
                targetedShare.putExtra(Intent.EXTRA_TITLE, title);
                if(data!=null && !isBinaryData){
                  targetedShare.putExtra(Intent.EXTRA_TEXT, data);
                }
              }              
              if(data!=null && isBinaryData){
                targetedShare.putExtra(Intent.EXTRA_TEXT, title);
                targetedShare.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(data)));
              }        
              
              if(nameApp!=null){
                if (info.activityInfo.packageName.toLowerCase().contains(nameApp) || 
                        info.activityInfo.name.toLowerCase().contains(nameApp)) {
                    targetedShare.setPackage(info.activityInfo.packageName);                  
                    targetedShareIntents.add(targetedShare);
                }
              }else{
                targetedShare.setPackage(info.activityInfo.packageName);                  
                  targetedShareIntents.add(targetedShare);
              }
          }

          Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select app to share");
          chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[]{}));
          
          res = chooserIntent;
          
          if(launch){
            context.startActivity(chooserIntent);
          }
      }
      
      return res;
  }
  
  
  //--------------- IO RELATED -----------------------------------------------------------------------
   
   /**
     * Reads the data of an input stream to a String.
     * 
     * @param is
     * @return
     * @throws java.io.IOException
     */
    public static String io_convertStreamToString(InputStream is) throws IOException {
        /*
       * To convert the InputStream to String we use the
       * BufferedReader.readLine() method. We iterate until the BufferedReader
       * return null which means there's no more data to read. Each line will
       * appended to a StringBuilder and returned as String.
       */
      if (is != null) {
        StringBuilder sb = new StringBuilder();
        String line;
      
        try {
          BufferedReader reader = new BufferedReader(
              new InputStreamReader(is, "UTF-8"));
          while ((line = reader.readLine()) != null) {
            sb.append(line).append("\n");
          }
        } finally {
          is.close();
        }
        return sb.toString();
      } else {
        return "";
      }
    }  
   
   /**
    * Reads the byte data from a input stream.
    * 
    * @param input
    * @return
    * @throws java.io.IOException
    */
   public static byte[] io_inputStreamToByteArray(InputStream input) throws IOException{
     byte[] res = null;
     
     try{
       // this dynamically extends to take the bytes you read
       ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
    
       // this is storage overwritten on each iteration with bytes
       int bufferSize = 1024;
       byte[] buffer = new byte[bufferSize];
    
       // we need to know how may bytes were read to write them to the byteBuffer
       int len = 0;
       while (input.available()>0 && (len = input.read(buffer)) != -1) {
         byteBuffer.write(buffer, 0, len);
       }
    
       byteBuffer.flush();
       res = byteBuffer.toByteArray();
       
       byteBuffer.close();
     }catch(Exception e){
       throw new IOException("Failed to read byte data from the stream ("+e.getMessage()+").",e);
     } 
     
     return res;
   }
  
   //--------------- MARKET ---------------------------------------------------------------------------- 
   
   /**
    * Prepares an intent for the Android Market application. In an
    * error occurs a url is used.
    * 
    * @param appName
    * @return
    */
   public static Intent market_getMarketAppIntent(String appName){
    Intent i = new Intent(Intent.ACTION_VIEW);
    try {
      i.setData(Uri.parse("market://details?id="+appName));
    } catch (android.content.ActivityNotFoundException anfe) {
      i.setData(Uri.parse("http://play.google.com/store/apps/details?id="+appName));
    }
    return i;
  } 
   
  //--------------- SCREEN ----------------------------------------------------------------------------
   
  /**
   * Sets LinearLayout parameters using density points.
   * 
   * @param context
   * @param container
   * @param viewId
   * @param height
   * @param width
   * @param weight
   */
  public static void screen_setLinearLayoutParams(Context context, View container, int viewId, float height, float width, float weight){
    
    container.findViewById(viewId).setLayoutParams(
        new LinearLayout.LayoutParams(
            screen_getDensityPoints(context, width),
                    screen_getDensityPoints(context, height), weight)
        );
  }
  
  /**
   * Gets the current orientation.
   * 
   * @param context
   * @return  {@link es.javocsoft.android.lib.toolbox.ToolBox.SCREEN_ORIENTATION}
   */
  @SuppressWarnings("deprecation")
  public static SCREEN_ORIENTATION screen_getOrientation(Context context){
    SCREEN_ORIENTATION res = SCREEN_ORIENTATION.PORTRAIT;
    
    Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
      //int orientation = Configuration.ORIENTATION_UNDEFINED;
      if(display.getWidth()==display.getHeight()){
        res = SCREEN_ORIENTATION.SQUARE;
          //orientation = Configuration.ORIENTATION_SQUARE;
      } else{ 
          if(display.getWidth() < display.getHeight()){
            res = SCREEN_ORIENTATION.PORTRAIT;
              //orientation = Configuration.ORIENTATION_PORTRAIT;
          }else { 
            res = SCREEN_ORIENTATION.LANDSCAPE;
              //orientation = Configuration.ORIENTATION_LANDSCAPE;
          }
      }
      return res;
  }
  
  /**
   * Gets the density points for a given size.
   * 
   * @param context
   * @param size
   * @return
   */
  public static int screen_getDensityPoints(Context context, float size){
      float d = context.getResources().getDisplayMetrics().density;
      return (int)(size * d); // margin in pixels
  }
   
   
  //--------------- WEB RELATED -----------------------------------------------------------------------
   
   /**
   * Checks if the url exists.
   * 
   * @param URLName
   * @return
   */
  public static boolean web_fileExists(String URLName){
      try {
        HttpURLConnection.setFollowRedirects(false);
        // It may also needed
        //        HttpURLConnection.setInstanceFollowRedirects(false)
        HttpURLConnection con =
           (HttpURLConnection) new URL(URLName).openConnection();
        con.setRequestMethod("HEAD");
        return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
      } catch (Exception e) {
        if(LOG_ENABLE)
          Log.d("ToolBox","Url does not exist ("+URLName+").");
        
         return false;
      }
    }

  /**
   * Enables http cache. (when using webview for example)
   * 
   * @param ctx
   */
  public static void web_enableHttpResponseCache(Context ctx) {
    try {
      long httpCacheSize = HTTP_CACHE_SIZE;
      File httpCacheDir = new File(ctx.getCacheDir(), "http");
      Class.forName("android.net.http.HttpResponseCache")
          .getMethod("install", File.class, long.class)
          .invoke(null, httpCacheDir, httpCacheSize);
    } catch (Exception e) {
      if(LOG_ENABLE)
        Log.e(TAG,"Http Response cache could not be initialized ["+ e.getMessage() + "]", e);
    }
  }
 
 
     // Media Related -----------------------------------------------------------------------------------------------------------------------------
   
  /**
   * Corrects the orientation of a Bitmap. Orientation, depending of the device
   * , is not correctly set in the EXIF data of the taken image when it is saved
   * into disk.
   * 
   * Explanation:
   *   Camera orientation is not working ok (as is when capturing an image) because 
   *  OEMs do not adhere to the standard. So, each company does this following their 
   *  own way.
   * 
   * @param imagePath  path to the file
   * @return
   */
  public static Bitmap media_correctImageOrientation (String imagePath){
    Bitmap res = null;
    
    try {
          File f = new File(imagePath);
          ExifInterface exif = new ExifInterface(f.getPath());
          int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

          int angle = 0;

          if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
              angle = 90;
          } 
          else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
              angle = 180;
          } 
          else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
              angle = 270;
          }

          Matrix mat = new Matrix();
          mat.postRotate(angle);
          BitmapFactory.Options options = new BitmapFactory.Options();
          options.inSampleSize = 2;
          
          Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
          res = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
                  bmp.getHeight(), mat, true);
          
      }catch(OutOfMemoryError e) {
        if(LOG_ENABLE)
            Log.e(TAG,"media_correctImageOrientation() [OutOfMemory!]: "+ e.getMessage(),e);
      }catch (Exception e) {
        if(LOG_ENABLE)
            Log.e(TAG,"media_correctImageOrientation(): "+e.getMessage(),e);
      }catch(Throwable e){
        if(LOG_ENABLE)
            Log.e(TAG,"media_correctImageOrientation(): "+e.getMessage(),e);
      }
      
    
    return res;
  }
  
  /**
   * Converts an image file to Base64 string.
   *  
   * @param pathToFile
   * @return
   */
  public static String media_getAssetImageAsB64(Context context, String pathToFile){
    String encodedImage = null;
    
    byte[] b = storage_readAssetResource(context, pathToFile);
    encodedImage = Base64.encodeToString(b, false);
    
    return encodedImage; 
  }
  
  /**
     * Decodes the specified image of the provided URL, scales it to reduce memory 
     * consumption and returning as a Bitmap object.
     * 
     * First tries from the cache, if does not exists it tries from the net.
     * 
     * @param storageDir  
     * @param urlImage
     * @param cacheExists
     * @return
     */
    public static Bitmap media_getBitmapFromNet(File storageDir, String urlImage, boolean cacheExists) throws Exception{
      Bitmap res=null;
      
      //I creates the names of the images by the hashcode of its url
      String filename=String.valueOf(urlImage.hashCode());
        File f=new File(storageDir, filename);
        
        try {
          //First, try to load then from the cache SD dir        
            if(cacheExists){
              Bitmap b = media_getBitmapFromFile(f);
              if(b!=null)
                  return b;
            }
          
            //If is not in the cache (or cache is not activated), tries from web          
          //
            //...get the image from the net
            Bitmap bitmap=null;
            
            if(cacheExists){
              //We store the image in the cache
              storage_saveInputData(new URL(urlImage).openStream(),f,true);              
                //...and get from the cache
                bitmap = media_getBitmapFromFile(f);
            }else{
              //Read directly from the net without saving in cache
            URL imageURL=new URL(urlImage);
                InputStream is=imageURL.openConnection().getInputStream();
            BufferedInputStream bis=new BufferedInputStream(is);
                bitmap = BitmapFactory.decodeStream(bis); 
                bis.close();is.close();                
            }            
            
            res=bitmap;
        } catch (Exception e){
          if(LOG_ENABLE)
            Log.e(TAG,"media_getBitmapFromNet(): "+e.getMessage(),e);
          
          throw new Exception(TAG+"[media_getBitmapFromNet()]: "+e.getMessage(),e);          
        }
        
        return res;
    }

    /**
     * Decodes the specified image from the storage, scales it to reduce memory consumption
     * and returning as a Bitmap object.
     * 
     * @param imgFile  File to get as a Bitmap object.
     * @return
     */
    public static Bitmap media_getBitmapFromFile(File imgFile) throws Exception{
        Bitmap res=null;
      
      try {
            //Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;            
            BitmapFactory.decodeStream(new FileInputStream(imgFile),null,o);
            
            //Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE=70;
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }
            
            //Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            res=BitmapFactory.decodeStream(new FileInputStream(imgFile), null, o2);
            
        }catch (FileNotFoundException e){
          if(LOG_ENABLE)
            Log.e(TAG,"media_generateBitmapFromFile() - FileNotFoundException: "+e.getMessage(),e);
          
          throw new Exception(TAG+"[media_generateBitmapFromFile() - FileNotFoundException]: "+e.getMessage(),e);
        }catch (Exception e){
          if(LOG_ENABLE)
            Log.e(TAG,"media_generateBitmapFromFile(): "+e.getMessage(),e);
          
          throw new Exception(TAG+"[media_generateBitmapFromFile()]: "+e.getMessage(),e);
        }
        
        return res;
    }
    
    /**
     * Grabs an image direct from a URL into a Drawable without saving a cache
     * 
     * @param urlImage
     * @param src_name
     * @return
     * @throws Exception
     */
  public static Drawable media_getDrawableFromNet(String urlImage, String src_name) throws Exception {
    Drawable res=null;
    
      try{
        InputStream is=((InputStream)new URL(urlImage).getContent());        
      res=Drawable.createFromStream(is, src_name);
      is.close();
    }catch (MalformedURLException e) {
      if(LOG_ENABLE)
        Log.e(TAG,"media_generateBitmapFromFile() - MalformedURLException: "+e.getMessage(),e);
      
          throw new Exception(TAG+"[media_generateBitmapFromFile() - MalformedURLException]: "+e.getMessage(),e);
    }catch (IOException e) {
      if(LOG_ENABLE)
        Log.e(TAG,"media_generateBitmapFromFile() - IOException: "+e.getMessage(),e);
      
          throw new Exception(TAG+"[media_generateBitmapFromFile() - IOException]: "+e.getMessage(),e);
    }catch(Exception e){
      if(LOG_ENABLE)
        Log.e(TAG,"media_generateBitmapFromFile(): "+e.getMessage(),e);
      
          throw new Exception(TAG+"[media_generateBitmapFromFile()]: "+e.getMessage(),e);
    }
            
      return res;
  }
    
  /**
     * Grabs an image direct from a file into a Drawable without saving a cache
     * 
     * @param filePath
     * @return
     * @throws Exception
     */
  public static Drawable media_getDrawableFromFile(String filePath) throws Exception {
    Drawable res=null;
    
      try{                
      res=Drawable.createFromPath(filePath);
    }catch(Exception e){
      if(LOG_ENABLE)
        Log.e(TAG,"media_getDrawableFromFile(): "+e.getMessage(),e);
      
          throw new Exception(TAG+"[media_getDrawableFromFile()]: "+e.getMessage(),e);
    }
            
      return res;
  } 
   
   /**
    * Loads a Bitmap image form the internal storage.
    * 
    * @param context
    * @param fileName
    * @return
    * @throws Exception
    */
   public static Bitmap media_loadBitmapFromInternalStorage(Context context, String fileName) throws Exception{
     
     try{
       FileInputStream is = context.openFileInput(fileName);
       Bitmap b = BitmapFactory.decodeStream(is);
       
       return b;
     } catch (Exception e) {       
       throw new Exception("Error reading data '" + fileName + "' (internal storage) : "+ e.getMessage(),e);
     }
   }
   
   
   /**
    * Makes rounded corners on a bitmap.
    * 
    * Requires Level 17 of Android API!!
    * 
    * @param bitmap
    * @return
    */
   /*public static Bitmap media_getRoundedCornerBitmap(Bitmap bitmap) {
      Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
          bitmap.getHeight(), Config.ARGB_8888);
      Canvas canvas = new Canvas(output);

      final int color = 0xff424242;
      final Paint paint = new Paint();
      final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
      final RectF rectF = new RectF(rect);
      final float roundPx = 8;

      paint.setAntiAlias(true);
      canvas.drawARGB(0, 0, 0, 0);
      paint.setColor(color);
      canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

      paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
      canvas.drawBitmap(bitmap, rect, rect, paint);

      return output;
    }*/

  /**
   * Convers a Bitmap to grayscale.
   * 
   * @param bmpOriginal
   * @return
   */
   public static Bitmap media_getGrayScale(Bitmap bmpOriginal) {
    int width, height;
    height = bmpOriginal.getHeight();
    width = bmpOriginal.getWidth();

    Bitmap bmpGrayscale = Bitmap.createBitmap(width, height,
        Bitmap.Config.RGB_565);
    Canvas c = new Canvas(bmpGrayscale);
    Paint paint = new Paint();
    ColorMatrix cm = new ColorMatrix();
    cm.setSaturation(0);
    ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
    paint.setColorFilter(f);
    c.drawBitmap(bmpOriginal, 0, 0, paint);
    return bmpGrayscale;
   }
   
   
   /**
    * Plays the specified ringtone from the application raw folder.
    * 
    * @param appPackage      Application package. (you can get it by using: 
    *               AppVigilant.thiz.getApplicationContext().getPackageName())
    * @param soundResourceId    Sound resource id
    */
   public static void media_soundPlayFromRawFolder(Context context, String appPackage, int soundResourceId){
    try {
      Uri soundUri = Uri.parse("android.resource://" + appPackage + "/" + soundResourceId);
          Ringtone r = RingtoneManager.getRingtone(context, soundUri);          
          r.play();
    
      } catch (Exception e) {
        if(LOG_ENABLE){
          Log.e(TAG, "Error playing sound with resource id: '" + soundResourceId + "' (" + e.getMessage() + ")", e);
        }
      }
   }
   
   /**
    * Plays the default system notification ringtone.
    * 
    * @param context
    */
   public static void media_soundPlayNotificationDefault(Context context){
    try {
      Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
          Ringtone r = RingtoneManager.getRingtone(context, soundUri);
          r.play();
          
      } catch (Exception e) {
        if(LOG_ENABLE){
          Log.e(TAG, "Error playing default notification sound (" + e.getMessage() + ")", e);
        }
      }
   }
   
   /**
    * Plays the specified sound from the application asset folder.
    * 
    * @param context
    * @param assetSoundPath  Path to the sound in the assets folder.
    */
   public static void media_soundPlayFromAssetFolder(Context context, String assetSoundPath){
    try {
      AssetFileDescriptor afd = context.getAssets().openFd(assetSoundPath);
      
          MediaPlayer player = new MediaPlayer();
          player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
          player.prepare();
          player.start();
          
      } catch (Exception e) {
        if(LOG_ENABLE){
          Log.e(TAG, "Error playing sound: '" + assetSoundPath + "' (" + e.getMessage() + ")", e);
        }
      }
   }
   
   // Device Related -----------------------------------------------------------------------------------------------------------------------------
   
   /**
  * Returns a unique UUID for the an android device. As with any UUIDs,
    * this unique ID is "very highly likely" to be unique across all Android
    * devices. Much more than ANDROID_ID is.
  * 
  * It uses as the base the ANDROID_ID only if is not null and not the 
  * some device manufacturers buggy ID 9774d56d682e549c for 2.2, 2.3 android
  * version (@see http://code.google.com/p/android/issues/detail?id=10603). 
  * If is not available or is the buggy one, a unique UUID will be 
  * generated using the SERIAL property of the device and if not available,
  * a bunch of device properties will be used to generated a unique UUID string.
  * 
  * @param context
  * @return a UUID that may be used, in most cases, to uniquely identify your 
  *       device for most.
  */
  public static String device_getId(Context context) {
     UUID uuid = null;
     
     String androidId = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);     
     if(androidId==null) {
       uuid = generateUniqueDeviceUUIDId();
     }else{
      //Several devices by several manufacturers are affected by the ANDROID_ID bug in 2.2.
         //All affected devices have the same ANDROID_ID, which is 9774d56d682e549c. Which is 
         //also the same device id reported by the emulator.
         if(!"9774d56d682e549c".equals(androidId)){
           try{
             uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
           } catch (UnsupportedEncodingException e) {
              Log.e(TAG, "UnsupportedEncodingException (" + e.getMessage() + ").", e);
          }
         }else{
           uuid = generateUniqueDeviceUUIDId();           
         }
     }
     
     return uuid.toString();
   }
   
  /**
   * Generates a unique device id using the device 
   * "serial" property if is available. If not, a bunch
   * of device properties will be used to get a reliable
   * unique string key for the device.
   * 
   * If there is an error in UUID generation null is
   * returned.
   *    
   * @return  The unique UUID or nul in case of error.
   */
  private static UUID generateUniqueDeviceUUIDId() {
    UUID uuid = null;
       
    try{
      //We generate a unique id
      String serial = null;
           if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) { 
             serial = Build.SERIAL;
             uuid = UUID.nameUUIDFromBytes(serial.getBytes("utf8"));
           }else{
             //This bunch of data should be enough to "ensure" the 
             //uniqueness.
             String m_szDevIDAlterbative = "35" + //To look like a valid IMEI
                    Build.BOARD.length()%10+ Build.BRAND.length()%10 +
                    Build.CPU_ABI.length()%10 + Build.DEVICE.length()%10 +
                    Build.DISPLAY.length()%10 + Build.HOST.length()%10 +
                    Build.ID.length()%10 + Build.MANUFACTURER.length()%10 +
                    Build.MODEL.length()%10 + Build.PRODUCT.length()%10 +
                    Build.TAGS.length()%10 + Build.TYPE.length()%10 +
                    Build.USER.length()%10 ; //13 digits
             
             uuid = UUID.nameUUIDFromBytes(m_szDevIDAlterbative.getBytes("utf8"));
           }
         
    } catch (UnsupportedEncodingException e) {
          Log.e(TAG, "UnsupportedEncodingException (" + e.getMessage() + ").", e);
      }
         
         return uuid;
   }
  
  
  /**
   * Gets the device screen size in pixels.
   * 
   * @param context
   * @return
   */
  @SuppressWarnings("deprecation")
  @SuppressLint("NewApi")
  public static Point device_screenSize(Context context){
    Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    final Point size = new Point();
    try{
      display.getSize(size);
    } catch (NoSuchMethodError ignore) { // Older device
      size.x = display.getWidth();
      size.y = display.getHeight();
      }
      
      return size;
  }
  
  
  public static DisplayMetrics device_screenMetrics(Context context){
    DisplayMetrics metrics = new DisplayMetrics();
    Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    display.getMetrics(metrics);
    //display.getRealMetrics(metrics);
      
      return metrics;
  }
   
  /**
   * Gets the device type from its screen properties.
   * 
   * @param context  
   * @param strictlyInInches  This makes that all calculations be made by 
   *               inches, using the number of pixels per inch,
   *               instead using density points. Useful for some 
   *               weird non standard devices.
   * @return  {@link es.javocsoft.android.lib.toolbox.ToolBox.DEVICE_BY_SCREEN}.
   */
  public static DEVICE_BY_SCREEN device_getTypeByScreen(Context context, boolean strictlyInInches){
    DEVICE_BY_SCREEN res = DEVICE_BY_SCREEN.DP320_NORMAL;
    
    DisplayMetrics metrics = device_screenMetrics(context);
    
    int widthPixels = -1;
    int heightPixels = -1;
    
    //The width and height in pixels
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        // For JellyBeans and onward
          widthPixels = metrics.widthPixels;
      heightPixels = metrics.heightPixels;
      } else {
        //To avoid excluding the dimensions of the Navigation Bar
          try {
            Method mGetRawH = Display.class.getMethod("getRawHeight");
            Method mGetRawW = Display.class.getMethod("getRawWidth");            
            widthPixels = (Integer) mGetRawW.invoke(metrics);
            heightPixels = (Integer) mGetRawH.invoke(metrics);
          } catch (Exception e) {
            if(LOG_ENABLE)
              Log.w(TAG, "Controlled error getting width and height in pixels [" + e.getMessage() + "]",e);
          }
      }
    
      if(widthPixels==-1 || heightPixels==-1){
        //We do nothing, return NORMAL.
      }else{
      if(strictlyInInches){
        //Physical pixels per inch  
        float widthDpi = metrics.xdpi;
        float heightDpi = metrics.ydpi;
        
        float widthInches = widthPixels / widthDpi;
        float heightInches = heightPixels / heightDpi;
        
        /* However, we also know that given the height of a triangle and the width, 
         * we can use the Pythagorean theorem to work out the length of the 
         * hypotenuse (In this case, the size of the screen diagonal).
         * 
         * a? + b? = c? 
         */
        //The size of the diagonal in inches is equal to the square root of the height 
        //in inches squared plus the width in inches squared.
        double diagonalInches = Math.sqrt((widthInches * widthInches)+ (heightInches * heightInches));
        
        if (diagonalInches >= 7) {
          res = DEVICE_BY_SCREEN.DP600_7INCH;
        }else if (diagonalInches >= 10) {
          res = DEVICE_BY_SCREEN.DP720_10INCH;
        }else{
          res = DEVICE_BY_SCREEN.DP320_NORMAL;
        }
        
      }else{
        //We get in density points (dp)
        float scaleFactor = metrics.density;    
        float widthDp = widthPixels / scaleFactor;
        float heightDp = heightPixels / scaleFactor;
        
        /*
         * Now we get the inches according to Google:
         * 
         * 320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).
         * 480dp: a tweener tablet like the Streak (480x800 mdpi).
         * 600dp: a 7" tablet (600x1024 mdpi).
         * 720dp: a 10" tablet (720x1280 mdpi, 800x1280 mdpi, etc).
         */    
        float smallestWidth = Math.min(widthDp, heightDp);    
        if (smallestWidth <= 320 ) {
            res = DEVICE_BY_SCREEN.DP320_NORMAL;
        }else if (smallestWidth > 320 && smallestWidth <= 480) {
          res = DEVICE_BY_SCREEN.DP480_TWEENER;
        }else if (smallestWidth > 600 && smallestWidth < 720) {
          res = DEVICE_BY_SCREEN.DP600_7INCH;
        }else if (smallestWidth > 720) {
          res = DEVICE_BY_SCREEN.DP720_10INCH;
        }
      }
      }
    
    return res;
  }
  
  /**
   * Returns the device resolution type.
   * 
   * @param context
   * @return  {@link es.javocsoft.android.lib.toolbox.ToolBox.DEVICE_RESOLUTION_TYPE}
   */
  public static DEVICE_RESOLUTION_TYPE device_getResolutionType(Context context) {
    DEVICE_RESOLUTION_TYPE res = null;
    
    DisplayMetrics metrics = new DisplayMetrics();
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    windowManager.getDefaultDisplay().getMetrics(metrics);
    
    switch (metrics.densityDpi) {
      case DisplayMetrics.DENSITY_LOW:
        res = DEVICE_RESOLUTION_TYPE.ldpi;
        break;
      case DisplayMetrics.DENSITY_MEDIUM:
        res = DEVICE_RESOLUTION_TYPE.mdpi;
        break;
      case DisplayMetrics.DENSITY_HIGH:
        res = DEVICE_RESOLUTION_TYPE.hdpi;
        break;
      case DisplayMetrics.DENSITY_XHIGH:
        res = DEVICE_RESOLUTION_TYPE.xhdpi;
        break;
      case DisplayMetrics.DENSITY_XXHIGH:
        res = DEVICE_RESOLUTION_TYPE.xxhdpi;
        break;    
    }
    
    return res;
  }
  
  /**
   * Get the device language (two letter code value)
   * @return
   */
  public static String device_getLanguage(){
    return Locale.getDefault().getLanguage();
  }
  
  
  /**
   * Get the current android API Level.
   * 
   * Android 4.2        17
   * Android 4.1        16
   * Android 4.0.3      15
   * Android 4.0        14
   * Android 3.2        13
   * Android 3.1        12
   * Android 3.0        11
   * Android 2.3.3      10
   * Android 2.3        9
   * Android 2.2        8
   * Android 2.1        7
   * Android 2.0.1      6
   * Android 2.0        5
   * Android 1.6        4
   * Android 1.5        3
   * Android 1.1        2
   * Android 1.0        1
   * 
   * @return
   */
  public static int device_getAPILevel(){
    return Build.VERSION.SDK_INT;
  }
  
  /**
   * Gets the device number if is available.
   * 
   * @param ctx
   * @return
   */
  public static String device_getDeviceMobileNumber(Context ctx) {
    TelephonyManager tm = (TelephonyManager) ctx
        .getSystemService(Context.TELEPHONY_SERVICE);
    return tm.getLine1Number();
  }
  
  public static String device_getIMEI(Context context) {
    TelephonyManager telephonyManager = (TelephonyManager) context
        .getSystemService(Context.TELEPHONY_SERVICE);
    return telephonyManager.getDeviceId();
  }

  public static String device_getOSVersion() {
    return String.valueOf(Build.VERSION.SDK_INT);
  }
  
  /**
   * Returns TRUE if a specified hardware feature is present.
   * 
   * Use PackageManager.FEATURE_[feature] to specify the feature
   * to query.
   * 
   * @param context
   * @param hardwareFeature  Use PackageManager.FEATURE_[feature] to specify the feature to query.
   * @return
   */
  public static boolean device_isHardwareFeatureAvailable(Context context, String hardwareFeature){
    return context.getPackageManager().hasSystemFeature(hardwareFeature);
  }
  
  /**
   * Return TRUE if there is a hardware keyboard present.
   * 
   * @param context
   * @return
   */
  public static boolean device_isHardwareKeyboard(Context context){
    //You can also get some of the features which are not testable by the PackageManager via the Configuration, e.g. the DPAD.
        Configuration c = context.getResources().getConfiguration();
        if(c.keyboard != Configuration.KEYBOARD_NOKEYS){
            return true;
        }else{
          return false;
        }
  }
  
  /**
   * Return TRUE if there is a hardware DPAD navigation button.
   * 
   * @param context
   * @return
   */
  public static boolean device_isHardwareDPAD(Context context){
    //You can also get some of the features which are not testable by the PackageManager via the Configuration, e.g. the DPAD.
        Configuration c = context.getResources().getConfiguration();
        if(c.navigation == Configuration.NAVIGATION_DPAD){
          return true;
        }else{
          return false;
        }
  }
  
  /**
   * Return TRUE if there is a hardware keyboard and is being made hidden.
   *  
   * @param context
   * @return
   */
  public static boolean device_isHardwareKeyboardHidden(Context context){
    //You can also get some of the features which are not testable by the PackageManager via the Configuration, e.g. the DPAD.
        Configuration c = context.getResources().getConfiguration();
        if(c.hardKeyboardHidden != Configuration.HARDKEYBOARDHIDDEN_UNDEFINED && 
           c.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES){
          return true;
        }else{
          return false;
        }
  }
  
  /**
   * Return TRUE if there is a hardware keyboard and is being made visible.
   * 
   * @param context
   * @return
   */
  public static boolean device_isHardwareKeyboardVisible(Context context){
    //You can also get some of the features which are not testable by the PackageManager via the Configuration, e.g. the DPAD.
        Configuration c = context.getResources().getConfiguration();
        if(c.hardKeyboardHidden != Configuration.HARDKEYBOARDHIDDEN_UNDEFINED && 
           c.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO){
          return true;
        }else{
          return false;
        }
  }
  
  /**
   * Returns true if the menu hardware menu is present on the device
   * 
   * This function requires API Level 14.
   * 
   * @param context
   * @return
   */
  @SuppressLint("NewApi")
  public static boolean device_isHardwareMenuButtonPresent(Context context){
    if(device_getAPILevel()>=14){
      //This requires API Level 14
      return ViewConfiguration.get(context).hasPermanentMenuKey();
    }else{
      return false;
    }
  }
  
  
  //-------------------- CRYPTO ------------------------------------------------------------------------
    
   public static String crypto_getHASH(byte[] data, HASH_TYPE hashType){
     
     MessageDigest digest = null;
     byte[] resData = null;
     
     try{
       switch(hashType){
         case md5:
           digest = MessageDigest.getInstance("MD5");
           resData = digest.digest(data);
           break;
         case sha1:
           digest = MessageDigest.getInstance("SHA-1");
           resData = digest.digest(data);
           break;
       }
       
       if(resData!=null)
         return new String(resData);
       else
         return null;
       
     }catch(Exception e){
       if(LOG_ENABLE)
         Log.e("TollBox_ERROR","crypto_getHASH() Error getting HASH data: " + e.getMessage(),e);
       
       return null;
     }
   }
   
   //-------------------- FONTS ------------------------------------------------------------------------
   
   /**
    *  Set a font to a text view.
    * 
    * @param context
    * @param textView
    * @param fontPath    The path to the font resource. Must be placed in asset 
    *           folder.
    */
   public static void font_applyTitleFont(Context context, TextView textView, String fontPath) {
     if (textView != null) {
       Typeface font = Typeface.createFromAsset(context.getAssets(),fontPath);
       textView.setTypeface(font);
     }
   }
   
}




Java Source Code List

es.javocsoft.android.lib.toolbox.ToolBox.java
es.javocsoft.android.lib.toolbox.ads.AdBase.java
es.javocsoft.android.lib.toolbox.ads.AdFragment.java
es.javocsoft.android.lib.toolbox.ads.AdInterstitial.java
es.javocsoft.android.lib.toolbox.ads.InterstitialAdsListener.java
es.javocsoft.android.lib.toolbox.analytics.CampaignInfo.java
es.javocsoft.android.lib.toolbox.analytics.CustomCampaignTrackingReceiver.java
es.javocsoft.android.lib.toolbox.encoding.Base64DecodingException.java
es.javocsoft.android.lib.toolbox.encoding.Base64.java
es.javocsoft.android.lib.toolbox.encoding.FileHelper.java
es.javocsoft.android.lib.toolbox.facebook.FacebookLoginFragment.java
es.javocsoft.android.lib.toolbox.facebook.FacebookShareFragment.java
es.javocsoft.android.lib.toolbox.facebook.FbTools.java
es.javocsoft.android.lib.toolbox.facebook.beans.AppRequestBean.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestCancelledActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestDeleteSuccessActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestFailActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestReceivedActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestReceivedErrorActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnAppRequestSuccessActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnLoginActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnLogoutActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnShareCancelledActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnShareFailActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.callback.OnShareSuccessActionCallback.java
es.javocsoft.android.lib.toolbox.facebook.exception.FBException.java
es.javocsoft.android.lib.toolbox.facebook.exception.FBSessionException.java
es.javocsoft.android.lib.toolbox.gcm.EnvironmentType.java
es.javocsoft.android.lib.toolbox.gcm.NotificationModule.java
es.javocsoft.android.lib.toolbox.gcm.core.CustomGCMBroadcastReceiver.java
es.javocsoft.android.lib.toolbox.gcm.core.CustomNotificationReceiver.java
es.javocsoft.android.lib.toolbox.gcm.core.GCMIntentService.java
es.javocsoft.android.lib.toolbox.gcm.core.beans.GCMDeliveryResponse.java
es.javocsoft.android.lib.toolbox.gcm.core.beans.GCMDeliveryResultItem.java
es.javocsoft.android.lib.toolbox.gcm.core.beans.GCMMessage.java
es.javocsoft.android.lib.toolbox.gcm.exception.GCMException.java
es.javocsoft.android.lib.toolbox.gcm.send.GCMHttpDelivery.java
es.javocsoft.android.lib.toolbox.io.IOUtils.java
es.javocsoft.android.lib.toolbox.io.Unzipper.java
es.javocsoft.android.lib.toolbox.media.MediaScannerNotifier.java
es.javocsoft.android.lib.toolbox.net.HttpOperations.java
es.javocsoft.android.lib.toolbox.sms.cmt.CMTInfoHelper.java
es.javocsoft.android.lib.toolbox.sms.cmt.CMTShortNumberInformation.java
es.javocsoft.android.lib.toolbox.sms.observer.SMSObserver.java