Android Tutorial - Security : SHA

SHA-1 string

//package org.artags.android.app.util.security;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SecurityUtils
{

    public static String sha1(String data)
    {
        try
        {
            byte[] b = data.getBytes();
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.reset();
            md.update(b);
            byte messageDigest[] = md.digest();
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < messageDigest.length; i++)
            {
                result.append(Integer.toString((messageDigest[i] & 0xff) + 0x100, 16).substring(1));
            }

            return result.toString();

        } catch (NoSuchAlgorithmException e)
        {

          //  Log.e("ARTags", "SHA1 is not a supported algorithm");
        }
        return null;
    }
} 

hmac Sha1 Digest

//package org.andlib.helpers;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAKeyGenParameterSpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


/**
 * 
 * @author meinside@gmail.com
 * @since 09.11.24.
 * 
 * last update 10.04.13.
 *
 */
final  class StringCodec
{
  /**
   * 
   * @param original
   * @return null if fails
   */
  public static String urlencode(String original)
  {
    try
    {
      //return URLEncoder.encode(original, "utf-8");
      //fixed: to comply with RFC-3986
      return URLEncoder.encode(original, "utf-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
    }
    catch(UnsupportedEncodingException e)
    {
    //  Logger.e(e.toString());
    }
    return null;
  }
  
  /**
   * 
   * @param encoded
   * @return null if fails
   */
  public static String urldecode(String encoded)
  {
    try
    {
      return URLDecoder.decode(encoded, "utf-8");
    }
    catch(UnsupportedEncodingException e)
    {
    //  Logger.e(e.toString());
    }
    return null;
  }
  
  /**
   * 
   * @param original
   * @param key
   * @return null if fails
   */
  public static String hmacSha1Digest(String original, String key)
  {
    return hmacSha1Digest(original.getBytes(), key.getBytes());
  }
  
  /**
   * 
   * @param original
   * @param key
   * @return null if fails
   */
  public static String hmacSha1Digest(byte[] original, byte[] key)
  {
    try
    {
      Mac mac = Mac.getInstance("HmacSHA1");
      mac.init(new SecretKeySpec(key, "HmacSHA1"));
      byte[] rawHmac = mac.doFinal(original);
      return new String(Base64Coder.encode(rawHmac));
    }
    catch (Exception e)
    {
    //  Logger.e(e.toString());
    }
    return null;
  }
  
  /**
   * 
   * @param original
   * @return null if fails
   */
  public static String md5sum(byte[] original)
  {
    try
    {
      MessageDigest md = MessageDigest.getInstance("MD5");
      md.update(original, 0, original.length);
      StringBuffer md5sum = new StringBuffer(new BigInteger(1, md.digest()).toString(16));
      while(md5sum.length() < 32)
        md5sum.insert(0, "0");
      return md5sum.toString();
    }
    catch(NoSuchAlgorithmException e)
    {
      //Logger.e(e.toString());
    }
    return null;
  }
  
  /**
   * 
   * @param original
   * @return null if fails
   */
  public static String md5sum(String original)
  {
    return md5sum(original.getBytes());
  }
  
  /**
   * AES encrypt function
   * 
   * @param original
   * @param key 16, 24, 32 bytes available
   * @param iv initial vector (16 bytes) - if null: ECB mode, otherwise: CBC mode
   * @return
   */
  public static byte[] aesEncrypt(byte[] original, byte[] key, byte[] iv)
  {
    if(key == null || (key.length != 16 && key.length != 24 && key.length != 32))
    {
    //  Logger.e("key's bit length is not 128/192/256");
      return null;
    }
    if(iv != null && iv.length != 16)
    {
    //  Logger.e("iv's bit length is not 16");
      return null;
    }

    try
    {
      SecretKeySpec keySpec = null;
      Cipher cipher = null;
      if(iv != null)
      {
        keySpec = new SecretKeySpec(key, "AES/CBC/PKCS7Padding");
        cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));
      }
      else  //if(iv == null)
      {
        keySpec = new SecretKeySpec(key, "AES/ECB/PKCS7Padding");
        cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
      }

      return cipher.doFinal(original);
    }
    catch(Exception e)
    {
    //  Logger.e(e.toString());
    }
    return null;
  }

  /**
   * AES decrypt function
   * 
   * @param encrypted
   * @param key 16, 24, 32 bytes available
   * @param iv initial vector (16 bytes) - if null: ECB mode, otherwise: CBC mode
   * @return
   */
  public static byte[] aesDecrypt(byte[] encrypted, byte[] key, byte[] iv)
  {
    if(key == null || (key.length != 16 && key.length != 24 && key.length != 32))
    {
    //  Logger.e("key's bit length is not 128/192/256");
      return null;
    }
    if(iv != null && iv.length != 16)
    {
    //  Logger.e("iv's bit length is not 16");
      return null;
    }

    try
    {
      SecretKeySpec keySpec = null;
      Cipher cipher = null;
      if(iv != null)
      {
        keySpec = new SecretKeySpec(key, "AES/CBC/PKCS7Padding");
        cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
      }
      else  //if(iv == null)
      {
        keySpec = new SecretKeySpec(key, "AES/ECB/PKCS7Padding");
        cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
      }

      return cipher.doFinal(encrypted);
    }
    catch(Exception e)
    {
    //  Logger.e(e.toString());
    }
    return null;
  }
  
  /**
   * generates RSA key pair
   * 
   * @param keySize
   * @param publicExponent public exponent value (can be RSAKeyGenParameterSpec.F0 or F4)
   * @return
   */
  public static KeyPair generateRsaKeyPair(int keySize, BigInteger publicExponent)
  {
    KeyPair keys = null;
    try
    {
      KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
      RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(keySize, publicExponent);
      keyGen.initialize(spec);
      keys = keyGen.generateKeyPair();
    }
    catch(Exception e)
    {
    //  Logger.e(e.toString());
    }
    return keys;
  }
  
  /**
   * generates a RSA public key with given modulus and public exponent
   * 
   * @param modulus (must be positive? don't know exactly)
   * @param publicExponent
   * @return
   */
  public static PublicKey generateRsaPublicKey(BigInteger modulus, BigInteger publicExponent)
  {
    try
    {
      return KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, publicExponent));
    }
    catch(Exception e)
    {
    //  Logger.e(e.toString());
    }
    return null;
  }
  
  /**
   * generates a RSA private key with given modulus and private exponent
   * 
   * @param modulus (must be positive? don't know exactly)
   * @param privateExponent
   * @return
   */
  public static PrivateKey generateRsaPrivateKey(BigInteger modulus, BigInteger privateExponent)
  {
    try
    {
      return KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(modulus, privateExponent));
    }
    catch(Exception e)
    {
    //  Logger.e(e.toString());
    }
    return null;
  }
  
  /**
   * RSA encrypt function (RSA / ECB / PKCS1-Padding)
   * 
   * @param original
   * @param key
   * @return
   */
  public static byte[] rsaEncrypt(byte[] original, PublicKey key)
  {
    try
    {
      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
      cipher.init(Cipher.ENCRYPT_MODE, key);
      return cipher.doFinal(original);
    }
    catch(Exception e)
    {
    //  Logger.e(e.toString());
    }
    return null;
  }
  
  /**
   * RSA decrypt function (RSA / ECB / PKCS1-Padding)
   * 
   * @param encrypted
   * @param key
   * @return
   */
  public static byte[] rsaDecrypt(byte[] encrypted, PrivateKey key)
  {
    try
    {
      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
      cipher.init(Cipher.DECRYPT_MODE, key);
      return cipher.doFinal(encrypted);
    }
    catch(Exception e)
    {
    //  Logger.e(e.toString());
    }
    return null;
  }

  /**
   * converts given byte array to a hex string
   * 
   * @param bytes
   * @return
   */
  public static String byteArrayToHexString(byte[] bytes)
  {
    StringBuffer buffer = new StringBuffer();
    for(int i=0; i<bytes.length; i++)
    {
      if(((int)bytes[i] & 0xff) < 0x10)
        buffer.append("0");
      buffer.append(Long.toString((int) bytes[i] & 0xff, 16));
    }
    return buffer.toString();
  }
  
  /**
   * converts given hex string to a byte array
   * (ex: "0D0A" => {0x0D, 0x0A,})
   * 
   * @param str
   * @return
   */
  public static final byte[] hexStringToByteArray(String str)
  {
    int i = 0;
    byte[] results = new byte[str.length() / 2];
    for (int k = 0; k < str.length();)
    {
      results[i] = (byte)(Character.digit(str.charAt(k++), 16) << 4);
      results[i] += (byte)(Character.digit(str.charAt(k++), 16));
      i++;
    } 
    return results;
  }
}



class Base64Coder {

  //Mapping table from 6-bit nibbles to Base64 characters.
  private static char[]    map1 = new char[64];
  static {
     int i=0;
     for (char c='A'; c<='Z'; c++) map1[i++] = c;
     for (char c='a'; c<='z'; c++) map1[i++] = c;
     for (char c='0'; c<='9'; c++) map1[i++] = c;
     map1[i++] = '+'; map1[i++] = '/';
    }
  
  //Mapping table from Base64 characters to 6-bit nibbles.
  private static byte[]    map2 = new byte[128];
  static {
    for (int i=0; i<map2.length; i++) map2[i] = -1;
    for (int i=0; i<64; i++) map2[map1[i]] = (byte)i;
  }
  
  /**
   * Encodes a string into Base64 format.
   * No blanks or line breaks are inserted.
   * @param s  a String to be encoded.
   * @return   A String with the Base64 encoded data.
   */
  public static String encodeString (String s) {
    return new String(encode(s.getBytes()));
  }
  
  /**
   * Encodes a byte array into Base64 format.
   * No blanks or line breaks are inserted.
   * @param in  an array containing the data bytes to be encoded.
   * @return    A character array with the Base64 encoded data.
   */
  public static char[] encode (byte[] in) {
    return encode(in,in.length);
  }
  
  /**
   * Encodes a byte array into Base64 format.
   * No blanks or line breaks are inserted.
   * @param in   an array containing the data bytes to be encoded.
   * @param iLen number of bytes to process in <code>in</code>.
   * @return     A character array with the Base64 encoded data.
   */
  public static char[] encode (byte[] in, int iLen) {
    int oDataLen = (iLen*4+2)/3;       // output length without padding
    int oLen = ((iLen+2)/3)*4;         // output length including padding
    char[] out = new char[oLen];
    int ip = 0;
    int op = 0;
    while (ip < iLen) {
      int i0 = in[ip++] & 0xff;
      int i1 = ip < iLen ? in[ip++] & 0xff : 0;
      int i2 = ip < iLen ? in[ip++] & 0xff : 0;
      int o0 = i0 >>> 2;
      int o1 = ((i0 &   3) << 4) | (i1 >>> 4);
      int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
      int o3 = i2 & 0x3F;
      out[op++] = map1[o0];
      out[op++] = map1[o1];
      out[op] = op < oDataLen ? map1[o2] : '='; op++;
      out[op] = op < oDataLen ? map1[o3] : '='; op++; }
    return out; 
  }
  
  /**
   * Decodes a string from Base64 format.
   * @param s  a Base64 String to be decoded.
   * @return   A String containing the decoded data.
   * @throws   IllegalArgumentException if the input is not valid Base64 encoded data.
   */
  public static String decodeString (String s) {
    return new String(decode(s)); 
  }
  
  /**
   * Decodes a byte array from Base64 format.
   * @param s  a Base64 String to be decoded.
   * @return   An array containing the decoded data bytes.
   * @throws   IllegalArgumentException if the input is not valid Base64 encoded data.
   */
  public static byte[] decode (String s) {
    return decode(s.toCharArray()); 
  }
  
  /**
   * Decodes a byte array from Base64 format.
   * No blanks or line breaks are allowed within the Base64 encoded data.
   * @param in  a character array containing the Base64 encoded data.
   * @return    An array containing the decoded data bytes.
   * @throws    IllegalArgumentException if the input is not valid Base64 encoded data.
   */
  public static byte[] decode (char[] in) {
    int iLen = in.length;
    if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
    while (iLen > 0 && in[iLen-1] == '=') iLen--;
    int oLen = (iLen*3) / 4;
    byte[] out = new byte[oLen];
    int ip = 0;
    int op = 0;
    while (ip < iLen) {
      int i0 = in[ip++];
      int i1 = in[ip++];
      int i2 = ip < iLen ? in[ip++] : 'A';
      int i3 = ip < iLen ? in[ip++] : 'A';
      if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
        throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
      int b0 = map2[i0];
      int b1 = map2[i1];
      int b2 = map2[i2];
      int b3 = map2[i3];
      if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
        throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
      int o0 = ( b0       <<2) | (b1>>>4);
      int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
      int o2 = ((b2 &   3)<<6) |  b3;
      out[op++] = (byte)o0;
      if (op<oLen) out[op++] = (byte)o1;
      if (op<oLen) out[op++] = (byte)o2;
    }
    return out;
  }
  
  //Dummy constructor.
  private Base64Coder() {}

} // end class Base64Coder 

Sha1 hashes based on a given String 

//package gr.aueb.cs.mscis.chordroid.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


class Sha1 {

  public static String getHash(String str) {
    MessageDigest digest = null;
    byte[] input = null;

    try {
      digest = MessageDigest.getInstance("SHA-1");
      digest.reset();
      input = digest.digest(str.getBytes("UTF-8"));

    } catch (NoSuchAlgorithmException e1) {
      e1.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return convertToHex(input);
  }
  
  public static String getHash(byte[] data) {
    MessageDigest digest = null;
    byte[] input = null;

    try {
      digest = MessageDigest.getInstance("SHA-1");
      digest.reset();
      input = digest.digest(data);

    } catch (NoSuchAlgorithmException e1) {
      e1.printStackTrace();
    }
    return convertToHex(input);
  }
  
    private static String convertToHex(byte[] data) { 
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) { 
            int halfbyte = (data[i] >>> 4) & 0x0F;
            int two_halfs = 0;
            do { 
                if ((0 <= halfbyte) && (halfbyte <= 9)) 
                    buf.append((char) ('0' + halfbyte));
                else 
                    buf.append((char) ('a' + (halfbyte - 10)));
                halfbyte = data[i] & 0x0F;
            } while(two_halfs++ < 1);
        } 
        return buf.toString();
    } 


}
SHA1 Utils
package es.cesar.quitesleep.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.Arrays;

import android.util.Log;

public class SHA1Utils {
  
  final static String CLASS_NAME = "SHA1Util";
  
  // Genera SHA-1 de un char[]
  public static byte[] generateSHA1 (char chars[]) {
    return generateSHA1(new String(chars));
  }

  // Genera SHA-1 de un String
  public static byte[] generateSHA1 (String str) {
    return generateSHA1(str.getBytes());
  }

  // Genera SHA-1 de un InputStream
  public static byte[] generateSHA1 (InputStream is) {
    try {
      return generateSHA1(InputStreamUtils.InputStreamTOByte(is));
    } catch (Exception e) {
      return null;
    }
  }  
  
  /**
   * This function converts a string without conding into a String encoded
   * into a SHA1
   * 
   * @param str
   * @return
   */
  public static String generateSHA1toString (String str) {
    try
    {
      byte[] datos = generateSHA1(str.getBytes());
      return byteArrayToHexString(datos);
      
    }catch (Exception e) {
      if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, 
          ExceptionUtils.exceptionTraceToString(
              e.toString(), 
              e.getStackTrace()));
      return null;
    }
  }
  
  /**
   * This function converts an InputStream into a SHA1 String
   * 
   * @param is
   * @return
   */
  public static String generateSHA1toString (InputStream is) {
    try {
      return InputStreamUtils.byteToString(generateSHA1(InputStreamUtils.InputStreamTOByte(is)));
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * This function generates a SHA1 byte[] from a file
   * @param file
   * @return
   */
  public static byte[] generateSHA1 (File file) {
    try {
      return generateSHA1(new FileInputStream (file));
    } catch (Exception e) {
      return null;
    }
  }  

  /**
   * This function generates a SHA1 byte[] from another byte[].
   * @param bytes
   * @return
   */
  public static byte[] generateSHA1 (byte[] bytes) {
    byte[] encryted = null;
    try {
      MessageDigest digest = MessageDigest.getInstance("SHA-1");
      digest.reset();      
      digest.update(bytes);
      encryted = digest.digest();
      
    } catch (Exception e) { 
      if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString(
          e.toString(), 
          e.getStackTrace()));      
    }
    return encryted;
  }
  
  

  /**
   * This function encodes byte[] into a hex
   * 
   * @param b
   * @return
   */
  public static String byteArrayToHexString(byte[] b){
    if (b==null) return null;
    
    StringBuffer sb = new StringBuffer(b.length * 2);
    for (int i = 0; i < b.length; i++){
      int v = b[i] & 0xff;
      if (v < 16) {
        sb.append('0');
      }
      sb.append(Integer.toHexString(v));
    }
    return sb.toString().toUpperCase();
  }

  /**
   * This function encodes a Hex String into a byte[]
   * @param s
   * @return
   */
  public static byte[] hexStringToByteArray(String s) {
    if (s==null) return null;
    
    byte[] b = new byte[s.length() / 2];
    for (int i = 0; i < b.length; i++){
      int index = i * 2;
      int v = Integer.parseInt(s.substring(index, index + 2), 16);
      b[i] = (byte)v;
    }
    return b;
  }
  
  /**
   * This function compares two bytes[]
   * @param b1
   * @param b2
   * @return
   */
  public static boolean compareByteArrays (byte[] b1, byte[] b2) {
    return b1!=null && b2!=null && Arrays.equals(b1, b2) ;
  }

  
  public static boolean compareHexString (String s1, String s2) {
    return s1!=null && s2!=null && s1.equalsIgnoreCase(s2);
  }

  
}

Using SharedPreferences to store password

 
package app.test;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.EditText;

public class Test extends Activity {
  public static final String SETTING_INFOS = "SETTING_Infos";
  public static final String NAME = "NAME";
  public static final String PASSWORD = "PASSWORD";
  
  private EditText field_name;
  private EditText filed_pass;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        field_name = (EditText) findViewById(R.id.name);
        filed_pass = (EditText) findViewById(R.id.password);
        SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0);
    String name = settings.getString(NAME, "");
    String password = settings.getString(PASSWORD, "");
    field_name.setText(name);
    filed_pass.setText(password);
    }
    protected void onStop(){
        super.onStop();
    SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0);
    settings.edit()
      .putString(NAME, field_name.getText().toString())
      .putString(PASSWORD, filed_pass.getText().toString())
      .commit();
    }
}
//main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="SharedPreferences demo"
    />
<TextView android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    android:text="Name:" />
    
<EditText android:id="@+id/name" 
  android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    android:text="" />
  
<TextView android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    android:text="Password:" />
    
    
<EditText android:id="@+id/password" 
  android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    android:password="true"
    android:text="" />  
    
</LinearLayout>

Using SharedPreferences

 


package app.test;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.util.Log;

public class Test extends Activity {

    private static final String TAG = "SavingState";
  final String INITIALIZED = "initialized";
  private String someString;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        SharedPreferences myPrefs = getPreferences(MODE_PRIVATE);
        boolean hasPreferences = myPrefs.getBoolean(INITIALIZED, false);
        if(hasPreferences) {
            Log.v(TAG, "We've been called before");
            someString = myPrefs.getString("someString", "");
        }else {
            Log.v(TAG, "First time ever being called");
            someString = "some default value";
        }
        Editor editor = myPrefs.edit();
        editor.putBoolean(INITIALIZED, true);
        editor.putString("someString", someString);
        editor.commit();
    }
}

Drawing Shapes

 

package app.test;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class Test extends Activity {
  class RenderView extends View {
    Paint paint;

    public RenderView(Context context) {
      super(context);
      paint = new Paint();
    }

    protected void onDraw(Canvas canvas) {
      canvas.drawRGB(255, 255, 255);
      paint.setColor(Color.RED);
      canvas.drawLine(0, 0, canvas.getWidth() - 1,canvas.getHeight() - 1, paint);
      paint.setStyle(Style.STROKE);
      paint.setColor(0xff00ff00);
      canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2,40, paint);
      paint.setStyle(Style.FILL);
      paint.setColor(0x770000ff);
      canvas.drawRect(100, 100, 200, 200, paint);
      invalidate();
    }
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(new RenderView(this));
  }
}
Animated wallpaper draws a rotating wireframe shape with a choice of 2 shapes
package app.test;

import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.os.SystemClock;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;




 class CubeWallpaper2Settings extends PreferenceActivity
    implements SharedPreferences.OnSharedPreferenceChangeListener {

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        getPreferenceManager().setSharedPreferencesName(
                CubeWallpaper2.SHARED_PREFS_NAME);
        addPreferencesFromResource(R.xml.cube2_settings);
        getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(
                this);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onDestroy() {
        getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
                this);
        super.onDestroy();
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
            String key) {
    }
}

public class CubeWallpaper2 extends WallpaperService {

    public static final String SHARED_PREFS_NAME="cube2settings";

    static class ThreeDPoint {
        float x;
        float y;
        float z;
    }

    static class ThreeDLine {
        int startPoint;
        int endPoint;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public Engine onCreateEngine() {
        return new CubeEngine();
    }

    class CubeEngine extends Engine 
        implements SharedPreferences.OnSharedPreferenceChangeListener {

        private final Handler mHandler = new Handler();

        ThreeDPoint [] mOriginalPoints;
        ThreeDPoint [] mRotatedPoints;
        ThreeDLine [] mLines;
        private final Paint mPaint = new Paint();
        private float mOffset;
        private float mTouchX = -1;
        private float mTouchY = -1;
        private long mStartTime;
        private float mCenterX;
        private float mCenterY;

        private final Runnable mDrawCube = new Runnable() {
            public void run() {
                drawFrame();
            }
        };
        private boolean mVisible;
        private SharedPreferences mPrefs;

        CubeEngine() {
            // Create a Paint to draw the lines for our cube
            final Paint paint = mPaint;
            paint.setColor(0xffffffff);
            paint.setAntiAlias(true);
            paint.setStrokeWidth(2);
            paint.setStrokeCap(Paint.Cap.ROUND);
            paint.setStyle(Paint.Style.STROKE);

            mStartTime = SystemClock.elapsedRealtime();

            mPrefs = CubeWallpaper2.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
            mPrefs.registerOnSharedPreferenceChangeListener(this);
            onSharedPreferenceChanged(mPrefs, null);
        }

        public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {

            String shape = prefs.getString("cube2_shape", "cube");

            // read the 3D model from the resource
            readModel(shape);
        }

        private void readModel(String prefix) {
            // Read the model definition in from a resource.

            // get the resource identifiers for the arrays for the selected shape
            int pid = getResources().getIdentifier(prefix + "points", "array", getPackageName());
            int lid = getResources().getIdentifier(prefix + "lines", "array", getPackageName());

            String [] p = getResources().getStringArray(pid);
            int numpoints = p.length;
            mOriginalPoints = new ThreeDPoint[numpoints];
            mRotatedPoints = new ThreeDPoint[numpoints];

            for (int i = 0; i < numpoints; i++) {
                mOriginalPoints[i] = new ThreeDPoint();
                mRotatedPoints[i] = new ThreeDPoint();
                String [] coord = p[i].split(" ");
                mOriginalPoints[i].x = Float.valueOf(coord[0]);
                mOriginalPoints[i].y = Float.valueOf(coord[1]);
                mOriginalPoints[i].z = Float.valueOf(coord[2]);
            }

            String [] l = getResources().getStringArray(lid);
            int numlines = l.length;
            mLines = new ThreeDLine[numlines];

            for (int i = 0; i < numlines; i++) {
                mLines[i] = new ThreeDLine();
                String [] idx = l[i].split(" ");
                mLines[i].startPoint = Integer.valueOf(idx[0]);
                mLines[i].endPoint = Integer.valueOf(idx[1]);
            }
        }

        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            super.onCreate(surfaceHolder);
            setTouchEventsEnabled(true);
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            mHandler.removeCallbacks(mDrawCube);
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            mVisible = visible;
            if (visible) {
                drawFrame();
            } else {
                mHandler.removeCallbacks(mDrawCube);
            }
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            super.onSurfaceChanged(holder, format, width, height);
            // store the center of the surface, so we can draw the cube in the right spot
            mCenterX = width/2.0f;
            mCenterY = height/2.0f;
            drawFrame();
        }

        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);
        }

        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            mVisible = false;
            mHandler.removeCallbacks(mDrawCube);
        }

        @Override
        public void onOffsetsChanged(float xOffset, float yOffset,
                float xStep, float yStep, int xPixels, int yPixels) {
            mOffset = xOffset;
            drawFrame();
        }

        /*
         * Store the position of the touch event so we can use it for drawing later
         */
        @Override
        public void onTouchEvent(MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_MOVE) {
                mTouchX = event.getX();
                mTouchY = event.getY();
            } else {
                mTouchX = -1;
                mTouchY = -1;
            }
            super.onTouchEvent(event);
        }

        void drawFrame() {
            final SurfaceHolder holder = getSurfaceHolder();
            final Rect frame = holder.getSurfaceFrame();
            final int width = frame.width();
            final int height = frame.height();

            Canvas c = null;
            try {
                c = holder.lockCanvas();
                if (c != null) {
                    // draw something
                    drawCube(c);
                    drawTouchPoint(c);
                }
            } finally {
                if (c != null) holder.unlockCanvasAndPost(c);
            }

            mHandler.removeCallbacks(mDrawCube);
            if (mVisible) {
                mHandler.postDelayed(mDrawCube, 1000 / 25);
            }
        }

        void drawCube(Canvas c) {
            c.save();
            c.translate(mCenterX, mCenterY);
            c.drawColor(0xff000000);

            long now = SystemClock.elapsedRealtime();
            float xrot = ((float)(now - mStartTime)) / 1000;
            float yrot = (0.5f - mOffset) * 2.0f;
            rotateAndProjectPoints(xrot, yrot);
            drawLines(c);
            c.restore();
        }

        void rotateAndProjectPoints(float xrot, float yrot) {
            int n = mOriginalPoints.length;
            for (int i = 0; i < n; i++) {
                // rotation around X-axis
                ThreeDPoint p = mOriginalPoints[i];
                float x = p.x;
                float y = p.y;
                float z = p.z;
                float newy = (float)(Math.sin(xrot) * z + Math.cos(xrot) * y);
                float newz = (float)(Math.cos(xrot) * z - Math.sin(xrot) * y);

                // rotation around Y-axis
                float newx = (float)(Math.sin(yrot) * newz + Math.cos(yrot) * x);
                newz = (float)(Math.cos(yrot) * newz - Math.sin(yrot) * x);

                // 3D-to-2D projection
                float screenX = newx / (4 - newz / 400);
                float screenY = newy / (4 - newz / 400);

                mRotatedPoints[i].x = screenX;
                mRotatedPoints[i].y = screenY;
                mRotatedPoints[i].z = 0;
            }
        }

        void drawLines(Canvas c) {
            int n = mLines.length;
            for (int i = 0; i < n; i++) {
                ThreeDLine l = mLines[i];
                ThreeDPoint start = mRotatedPoints[l.startPoint];
                ThreeDPoint end = mRotatedPoints[l.endPoint];
                c.drawLine(start.x, start.y, end.x, end.y, mPaint);
            }
        }

        void drawTouchPoint(Canvas c) {
            if (mTouchX >=0 && mTouchY >= 0) {
                c.drawCircle(mTouchX, mTouchY, 80, mPaint);
            }
        }
    }
}



//\res\xml\cube1.xml
<?xml version="1.0" encoding="utf-8"?>

<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
/>



//\res\xml\cube2.xml
<?xml version="1.0" encoding="utf-8"?>


<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
        android:settingsActivity="com.example.android.livecubes.cube2.CubeWallpaper2Settings"
/>



//res\xml\cube2_settings.xml
<?xml version="1.0" encoding="utf-8"?>


<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        android:title="@string/cube2_settings"
        android:key="cube2wallpaper_settings">

    <ListPreference
            android:key="cube2_shape"
            android:title="@string/cube2_settings_title"
            android:summary="@string/cube2_settings_summary"
            android:entries="@array/cube2_shapenames"
            android:entryValues="@array/cube2_shapeprefix" />

</PreferenceScreen>

Animation: shake

package app.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

public class Test extends Activity implements View.OnClickListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        View loginButton = findViewById(R.id.login);
        loginButton.setOnClickListener(this);
    }

    public void onClick(View v) {
        Animation shake = AnimationUtils.loadAnimation(this, R.animator.myanim);
        findViewById(R.id.pw).startAnimation(shake);
    }

}


//layout/main.xml

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical"
    android:padding="10dip"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    
    <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dip"
        android:text="animation_1_instructions"
    />
    
    <EditText android:id="@+id/pw"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:singleLine="true"
        android:password="true"
    />

    <Button android:id="@+id/login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="googlelogin_login"
    />

</LinearLayout>


//animator/myanim.xml

<?xml version="1.0" encoding="utf-8"?>


<translate xmlns:android="http://schemas.android.com/apk/res/android" 
           android:fromXDelta="0" 
           android:toXDelta="10" 
           android:duration="1000" 
           android:interpolator="@anim/cycle_7" />

Get reference from SharedPreferences

 
import android.content.SharedPreferences;

class Main {

  public static Long getLongPref(SharedPreferences prefs, String key,
      long defaultValue) {
    String v = prefs.getString(key, String.valueOf(defaultValue));
    if (v != null) {
      try {
        return Long.parseLong(v);
      } catch (NumberFormatException e) {

      }
    }
    return defaultValue;
  }
}

Glutes shape

//package com.akjava.lib.android.opengl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.opengl.GLUtils;
import android.util.Log;

class OpenGLUtils {

  public static FloatBuffer allocateFloatBuffer(int capacity) {
    ByteBuffer vbb = ByteBuffer.allocateDirect(capacity);
    vbb.order(ByteOrder.nativeOrder());
    return vbb.asFloatBuffer();
  }

  public static IntBuffer allocateInttBuffer(int capacity) {
    ByteBuffer vbb = ByteBuffer.allocateDirect(capacity);
    vbb.order(ByteOrder.nativeOrder());
    return vbb.asIntBuffer();
  }

  public static ShortBuffer allocateShortBuffer(int capacity) {
    ByteBuffer vbb = ByteBuffer.allocateDirect(capacity);
    vbb.order(ByteOrder.nativeOrder());
    return vbb.asShortBuffer();
  }

  public static void addVertex3f(FloatBuffer buffer, float x, float y, float z) {
    buffer.put(x);
    buffer.put(y);
    buffer.put(z);
  }

  public static void addIndex(ShortBuffer buffer, int index1, int index2,
      int index3) {
    buffer.put((short) index1);
    buffer.put((short) index2);
    buffer.put((short) index3);
  }

  public static void addCoord2f(FloatBuffer buffer, float x, float y) {
    buffer.put(x);
    buffer.put(y);
  }

  public static void addColorf(FloatBuffer buffer, float r, float g, float b,
      float a) {
    buffer.put(r);
    buffer.put(g);
    buffer.put(b);
    buffer.put(a);
  }

  public static FloatBuffer toFloatBufferPositionZero(float[] values) {
    ByteBuffer vbb = ByteBuffer.allocateDirect(values.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    FloatBuffer buffer = vbb.asFloatBuffer();
    buffer.put(values);
    buffer.position(0);
    return buffer;
  }

  public static ShortBuffer toShortBuffer(short[] values) {
    ByteBuffer vbb = ByteBuffer.allocateDirect(values.length * 2);
    vbb.order(ByteOrder.nativeOrder());
    ShortBuffer buffer = vbb.asShortBuffer();
    buffer.put(values);
    buffer.position(0);
    return buffer;
  }

  public static Bitmap loadBitmap(Context mContext, int id) {
    Options opt = new Options();
    Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),
        id, opt);

    System.out.println(bitmap.getConfig());
    if (!sizeCheck(bitmap)) {
      throw new RuntimeException(
          "width or height not 2x size,it make invalid error on OpenGL:"
              + id);
    }
    return bitmap;
  }

  private static boolean sizeCheck(Bitmap bitmap) {
    boolean ret = true;
    int t = 2;
    int w = bitmap.getWidth();

    while (w != t) {
      if (w % t == 1) {
        Log.e("glutils w=", w + "," + t);
        return false;
      }
      t *= 2;
      if (t > w) {
        return false;
      }
    }

    t = 2;
    int h = bitmap.getHeight();
    while (h != t) {
      if (h % t == 1) {
        Log.e("glutils h=", h + "," + t);
        return false;
      }
      t *= 2;
      if (t > h) {
        return false;
      }
    }

    return ret;
  }

  /**
   * this is for resized GLU.gluOrtho2D (gl,-1f, 1.0f, -1f, 1.0f);
   * 
   * @param x
   * @param y
   * @param screenWidth
   * @param screenHeight
   * @return
   */
  public static float[] toOpenGLCordinate(float x, float y, int screenWidth,
      int screenHeight) {
    float sx = ((float) x / screenWidth) * 2 - 1.0f;
    float sy = ((float) y / screenHeight) * 2 - 1.0f;
    sy *= -1;
    return new float[] { sx, sy };
  }

  /*
   * y should *=-1;
   */
  public static float toOpenGLCordinate(float x, int screenWidth) {
    Log.i("myapp", "x=" + x + "," + screenWidth);
    float sx = ((float) x / screenWidth) * 2 - 1.0f;
    return sx;
  }

  public static float realToVirtialValue(int x, int real, float virtial) {
    return virtial / real * x;
  }

  public static int virtualToRealvalue(float x, int real, float virtial) {
    // using DecimalFormat make gc
    return (int) ((float) x / (virtial / real));
  }

  private static FloatBuffer mTextureBuffer;
  private static FloatBuffer mFVertexBuffer;
  private static ShortBuffer mIndexBuffer;

  public static FloatBuffer getBoxTriangleTextureBuffer() {
    if (mTextureBuffer == null) {
      mTextureBuffer = OpenGLUtils.allocateFloatBuffer(4 * 6 * 2);
      OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 1.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 0.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 1.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 1.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 0.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 0.0f);
      mTextureBuffer.position(0);
    }
    return mTextureBuffer;
  }

  public static FloatBuffer getBoxTriangleFlipVerticalTextureBuffer() {
    if (mTextureBuffer == null) {
      mTextureBuffer = OpenGLUtils.allocateFloatBuffer(4 * 6 * 2);
      OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 0.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 1.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 0.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 0.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 1.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 1.0f);
      mTextureBuffer.position(0);
    }
    return mTextureBuffer;
  }

  public static FloatBuffer getBoxTextureBuffer() {
    if (mTextureBuffer == null) {
      mTextureBuffer = OpenGLUtils.allocateFloatBuffer(4 * 4 * 2);
      OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 0.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 0.0f, 1.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 0.0f);
      OpenGLUtils.addCoord2f(mTextureBuffer, 1.0f, 1.0f);
      mTextureBuffer.position(0);
    }
    return mTextureBuffer;
  }

  public static ShortBuffer getBoxIndexBuffer() {
    if (mIndexBuffer == null) {
      mIndexBuffer = OpenGLUtils.allocateShortBuffer(6 * 2);
      mIndexBuffer.put((short) 0);
      mIndexBuffer.put((short) 1);
      mIndexBuffer.put((short) 2);
      mIndexBuffer.put((short) 2);
      mIndexBuffer.put((short) 3);
      mIndexBuffer.put((short) 1);
      mIndexBuffer.position(0);
    }
    return mIndexBuffer;
  }

  public static FloatBuffer getBoxVertexBuffer() {
    if (mFVertexBuffer == null) {
      mFVertexBuffer = OpenGLUtils.allocateFloatBuffer(4 * 4 * 3);
      OpenGLUtils.addVertex3f(mFVertexBuffer, -1, -1f, 0);
      OpenGLUtils.addVertex3f(mFVertexBuffer, -1, 1f, 0);

      OpenGLUtils.addVertex3f(mFVertexBuffer, 1, -1f, 0);
      OpenGLUtils.addVertex3f(mFVertexBuffer, 1, 1f, 0);
      mFVertexBuffer.position(0);

    }
    return mFVertexBuffer;
  }

  public static FloatBuffer getBoxTriangleVertexBuffer() {
    if (mFVertexBuffer == null) {
      mFVertexBuffer = OpenGLUtils.allocateFloatBuffer(4 * 6 * 3);
      OpenGLUtils.addVertex3f(mFVertexBuffer, -1, -1f, 0);
      OpenGLUtils.addVertex3f(mFVertexBuffer, -1, 1f, 0);
      OpenGLUtils.addVertex3f(mFVertexBuffer, 1, -1f, 0);

      OpenGLUtils.addVertex3f(mFVertexBuffer, 1, -1f, 0);
      OpenGLUtils.addVertex3f(mFVertexBuffer, 1, 1f, 0);
      OpenGLUtils.addVertex3f(mFVertexBuffer, -1, 1f, 0);

      mFVertexBuffer.position(0);

    }
    return mFVertexBuffer;
  }

  // TODO ??????????????
  /*
   * bitmap???????????
   */
  public static void bindTextureImage(GL10 gl, final int id,
      final Bitmap bitmap) {
    gl.glBindTexture(GL10.GL_TEXTURE_2D, id);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
        GL10.GL_CLAMP_TO_EDGE);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
        GL10.GL_CLAMP_TO_EDGE);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
        GL10.GL_NEAREST);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
        GL10.GL_NEAREST);
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
    bitmap.recycle();
  }

}

public class GLUT {

  public static class SolidCube {
    public static float v[] = new float[108]; // 108 = 6*18

    public static float cubev[] = { -1f, -1f, 1f, /* front */
    1f, -1f, 1f, -1f, 1f, 1f,

    1f, -1f, 1f, 1f, 1f, 1f, -1f, 1f, 1f,

    -1f, 1f, -1f, /* back */
    1f, -1f, -1f, -1f, -1f, -1f,

    -1f, 1f, -1f, 1f, 1f, -1f, 1f, -1f, -1f,

    -1f, -1f, -1f, /* left */
    -1f, -1f, 1f, -1f, 1f, -1f,

    -1f, -1f, 1f, -1f, 1f, 1f, -1f, 1f, -1f,

    1f, -1f, 1f, /* right */
    1f, -1f, -1f, 1f, 1f, 1f,

    1f, -1f, -1f, 1f, 1f, -1f, 1f, 1f, 1f,

    -1f, 1f, 1f, /* top */
    1f, 1f, 1f, -1f, 1f, -1f,

    1f, 1f, 1f, 1f, 1f, -1f, -1f, 1f, -1f,

    -1f, -1f, -1f, /* bottom */
    1f, -1f, -1f, -1f, -1f, 1f,

    1f, -1f, -1f, 1f, -1f, 1f, -1f, -1f, 1f, };

    static float cuben[] = { 0, 0, 1f, /* front */
    0, 0, 1f, 0, 0, 1f,

    0, 0, 1f, 0, 0, 1f, 0, 0, 1f,

    0, 0, -1f, /* back */
    0, 0, -1f, 0, 0, -1f,

    0, 0, -1f, 0, 0, -1f, 0, 0, -1f,

    -1f, 0, 0, /* left */
    -1f, 0, 0, -1f, 0, 0,

    -1f, 0, 0, -1f, 0, 0, -1f, 0, 0,

    1f, 0, 0, /* right */
    1f, 0, 0, 1f, 0, 0,

    1f, 0, 0, 1f, 0, 0, 1f, 0, 0,

    0, 1f, 0, /* top */
    0, 1f, 0, 0, 1f, 0,

    0, 1f, 0, 0, 1f, 0, 0, 1f, 0,

    0, -1f, 0, /* bottom */
    0, -1f, 0, 0, -1f, 0,

    0, -1f, 0, 0, -1f, 0, 0, -1f, 0, };

    private static FloatBuffer loadCuben() {

      cubenBuffer = OpenGLUtils.allocateFloatBuffer(108 * 4);
      for (int i = 0; i < 108; i++)
        cubenBuffer.put(cuben[i]);

      cubenBuffer.position(0);
      return cubenBuffer;
    }

    private static FloatBuffer cubevBuffer;
    private static FloatBuffer cubenBuffer;
    private static float param;

    private static FloatBuffer loadCubev(float size) {

      size /= 2;

      cubevBuffer = OpenGLUtils.allocateFloatBuffer(108 * 4);

      for (int i = 0; i < 108; i++) {
        cubevBuffer.put(cubev[i] * size);
        Log.d("", "" + cubev[i] * size);
      }
      cubevBuffer.position(0);

      return cubevBuffer;
    }

    public static void draw(GL10 gl, float size) {
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

      if (cubevBuffer != null) {
        if (param != size) {
          cubevBuffer = null;
          cubenBuffer = null;
          gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
          gl.glNormalPointer(GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
        }
      }

      if (cubenBuffer == null) {
        cubevBuffer = loadCubev(size);
        cubenBuffer = loadCuben();
        param = size;
      }

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubevBuffer);
      gl.glNormalPointer(GL10.GL_FLOAT, 0, cubenBuffer);

      gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 36);

      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
    }
  }

  public static void glutSolidCube(GL10 gl, float size) {
    SolidCube.draw(gl, size);
  }

  public static void glutSolidTorus(GL10 gl, float ir, float or, int sides,
      int rings) {
    SolidTorus.draw(gl, ir, or, sides, rings);
  }

  public static class SolidTorus {
    private static FloatBuffer p = null, q = null;
    private static FloatBuffer v = null, n = null;
    private static float parms[] = new float[4];// static

    /*
     * sometime it make heap problem
     */
    private static void draw(GL10 gl, float ir, float or, int sides,
        int rings) {
      int SIZEOF = 4;
      int i, j, k, triangles;
      float s, t, x, y, z, twopi, nx, ny, nz;
      float sin_s, cos_s, cos_t, sin_t, twopi_s, twopi_t;
      float twopi_sides, twopi_rings;

      // maybe clear buffer.
      if (v != null) {
        if (parms[0] != ir || parms[1] != or || parms[2] != sides
            || parms[3] != rings) {

          // free(v);
          // free(n);
          n = v = null; // maybe free later.

          gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
          gl.glNormalPointer(GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
        }
      }

      if (v == null) {
        parms[0] = ir;
        parms[1] = or;
        parms[2] = (float) sides;
        parms[3] = (float) rings;

        // this size is maybe wrong.
        p = v = OpenGLUtils.allocateFloatBuffer((int) (sides
            * (rings + 1) * 2 * 3 * SIZEOF));
        q = n = OpenGLUtils.allocateFloatBuffer((int) (sides
            * (rings + 1) * 2 * 3 * SIZEOF));

        twopi = 2.0f * (float) Math.PI;
        twopi_sides = twopi / sides;
        twopi_rings = twopi / rings;

        for (i = 0; i < sides; i++) {
          for (j = 0; j <= rings; j++) {
            for (k = 1; k >= 0; k--) {
              s = (i + k) % sides + 0.5f;
              t = (float) (j % rings);

              twopi_s = s * twopi_sides;
              twopi_t = t * twopi_rings;

              cos_s = (float) Math.cos(twopi_s);
              sin_s = (float) Math.sin(twopi_s);

              cos_t = (float) Math.cos(twopi_t);
              sin_t = (float) Math.sin(twopi_t);

              x = (or + ir * (float) cos_s) * (float) cos_t;
              y = (or + ir * (float) cos_s) * (float) sin_t;
              z = ir * (float) sin_s;

              p.put(x);
              p.put(y);
              p.put(z);

              nx = (float) cos_s * (float) cos_t;
              ny = (float) cos_s * (float) sin_t;
              nz = (float) sin_s;

              q.put(nx);
              q.put(ny);
              q.put(nz);
            }
          }
        }
      }

      v.position(0);
      n.position(0);
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, v);
      gl.glNormalPointer(GL10.GL_FLOAT, 0, n);

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

      triangles = ((int) rings + 1) * 2;

      for (i = 0; i < sides; i++) {
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, triangles * i,
            triangles);

      }

      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

    }

  }

  public static void glutSolidBox(GL10 gl, float Width, float Depth,
      float Height) {
    SolidBox.draw(gl, Width, Depth, Height);
  }

  public static class SolidBox {
    static float boxvec[][] = { { -1.0f, 0.0f, 0.0f },
        { 0.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f },
        { 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f },
        { 0.0f, 0.0f, -1.0f } };

    static ShortBuffer boxndex[] = {
        OpenGLUtils.toShortBuffer(new short[] { 0, 1, 2 }),
        OpenGLUtils.toShortBuffer(new short[] { 0, 2, 3 }),
        OpenGLUtils.toShortBuffer(new short[] { 3, 2, 6 }),
        OpenGLUtils.toShortBuffer(new short[] { 3, 6, 7 }),
        OpenGLUtils.toShortBuffer(new short[] { 6, 4, 7 }),
        OpenGLUtils.toShortBuffer(new short[] { 6, 5, 4 }),
        OpenGLUtils.toShortBuffer(new short[] { 4, 5, 1 }),
        OpenGLUtils.toShortBuffer(new short[] { 4, 1, 0 }),
        OpenGLUtils.toShortBuffer(new short[] { 2, 1, 5 }),
        OpenGLUtils.toShortBuffer(new short[] { 2, 5, 6 }),
        OpenGLUtils.toShortBuffer(new short[] { 3, 7, 4 }),
        OpenGLUtils.toShortBuffer(new short[] { 3, 4, 0 }) };

    static FloatBuffer vBuffer;

    static float parms[] = new float[3];

    public static void draw(GL10 gl, float Width, float Depth, float Height) {

      // maybe clear buffer.
      if (vBuffer != null) {
        if (parms[0] != Width || parms[1] != Depth
            || parms[2] != Height) {

          // free(v);
          // free(n);
          vBuffer = null; // maybe free later.

          gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));

        }
      }

      int i;
      if (vBuffer == null) {
        float v[] = new float[8 * 3];
        v[0 * 3 + 0] = v[1 * 3 + 0] = v[2 * 3 + 0] = v[3 * 3 + 0] = -Width / 2.0f;
        v[4 * 3 + 0] = v[5 * 3 + 0] = v[6 * 3 + 0] = v[7 * 3 + 0] = Width / 2.0f;
        v[0 * 3 + 1] = v[1 * 3 + 1] = v[4 * 3 + 1] = v[5 * 3 + 1] = -Depth / 2.0f;
        v[2 * 3 + 1] = v[3 * 3 + 1] = v[6 * 3 + 1] = v[7 * 3 + 1] = Depth / 2.0f;
        v[0 * 3 + 2] = v[3 * 3 + 2] = v[4 * 3 + 2] = v[7 * 3 + 2] = -Height / 2.0f;
        v[1 * 3 + 2] = v[2 * 3 + 2] = v[5 * 3 + 2] = v[6 * 3 + 2] = Height / 2.0f;
        vBuffer = OpenGLUtils.toFloatBufferPositionZero(v);

        parms[0] = Width;
        parms[1] = Depth;
        parms[2] = Height;
      }

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuffer);
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

      for (i = 0; i < 6; i++) {
        gl.glNormal3f(boxvec[i][0], boxvec[i][1], boxvec[i][2]);
        gl.glDrawElements(GL10.GL_TRIANGLES, 3, GL10.GL_UNSIGNED_SHORT,
            boxndex[i * 2]);
        gl.glDrawElements(GL10.GL_TRIANGLES, 3, GL10.GL_UNSIGNED_SHORT,
            boxndex[i * 2 + 1]);
      }

      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }

  }

  public static void glutWireBox(GL10 gl, float Width, float Depth,
      float Height) {
    WireBox.draw(gl, Width, Depth, Height);
  }

  public static class WireBox {
    static FloatBuffer vBuffer;
    static float parms[] = new float[3];
    static ShortBuffer wireboxndex[] = {
        OpenGLUtils.toShortBuffer(new short[] { 0, 1, 2, 3 }),
        OpenGLUtils.toShortBuffer(new short[] { 3, 2, 6, 7 }),
        OpenGLUtils.toShortBuffer(new short[] { 7, 6, 5, 4 }),
        OpenGLUtils.toShortBuffer(new short[] { 4, 5, 1, 0 }),
        OpenGLUtils.toShortBuffer(new short[] { 5, 6, 2, 1 }),
        OpenGLUtils.toShortBuffer(new short[] { 7, 4, 0, 3 }) };

    public static void draw(GL10 gl, float Width, float Depth, float Height) {
      if (vBuffer != null) {
        if (parms[0] != Width || parms[1] != Depth
            || parms[2] != Height) {

          // free(v);
          // free(n);
          vBuffer = null; // maybe free later.

          gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));

        }
      }
      int i;

      if (vBuffer == null) {
        float v[] = new float[8 * 3];
        v[0 * 3 + 0] = v[1 * 3 + 0] = v[2 * 3 + 0] = v[3 * 3 + 0] = -Width / 2.0f;
        v[4 * 3 + 0] = v[5 * 3 + 0] = v[6 * 3 + 0] = v[7 * 3 + 0] = Width / 2.0f;
        v[0 * 3 + 1] = v[1 * 3 + 1] = v[4 * 3 + 1] = v[5 * 3 + 1] = -Depth / 2.0f;
        v[2 * 3 + 1] = v[3 * 3 + 1] = v[6 * 3 + 1] = v[7 * 3 + 1] = Depth / 2.0f;
        v[0 * 3 + 2] = v[3 * 3 + 2] = v[4 * 3 + 2] = v[7 * 3 + 2] = -Height / 2.0f;
        v[1 * 3 + 2] = v[2 * 3 + 2] = v[5 * 3 + 2] = v[6 * 3 + 2] = Height / 2.0f;
        vBuffer = OpenGLUtils.toFloatBufferPositionZero(v);

        parms[0] = Width;
        parms[1] = Depth;
        parms[2] = Height;
      }

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuffer);
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

      for (i = 0; i < 6; i++) {
        gl.glNormal3f(SolidBox.boxvec[i][0], SolidBox.boxvec[i][1],
            SolidBox.boxvec[i][2]);
        gl.glDrawElements(GL10.GL_LINE_LOOP, 4, GL10.GL_UNSIGNED_SHORT,
            wireboxndex[i]);
      }
      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }
  }

  public static void glutWireCube(GL10 gl, float size) {
    WireCube.draw(gl, size);
  }

  public static class WireCube {
    static float v[] = new float[72];

    static float cubev[] = // 72 = 3*6*4
    { -1.0f, -1.0f, 1.0f, /* front */
    1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,

    -1.0f, 1.0f, -1.0f, /* back */
    1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,

    -1.0f, -1.0f, -1.0f, /* left */
    -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f,

    1.0f, -1.0f, 1.0f, /* right */
    1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,

    -1.0f, 1.0f, 1.0f, /* top */
    1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,

    -1.0f, -1.0f, -1.0f, /* bottom */
    1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, };

    static float cuben[] = { 0f, 0f, 1.0f, /* front */
    0f, 0f, 1.0f, 0f, 0f, 1.0f, 0f, 0f, 1.0f,

    0f, 0f, -1.0f, /* back */
    0f, 0f, -1.0f, 0f, 0f, -1.0f, 0f, 0f, -1.0f,

    -1.0f, 0f, 0f, /* left */
    -1.0f, 0f, 0f, -1.0f, 0f, 0f, -1.0f, 0f, 0f,

    1.0f, 0f, 0f, /* right */
    1.0f, 0f, 0f, 1.0f, 0f, 0f, 1.0f, 0f, 0f,

    0f, 1.0f, 0f, /* top */
    0f, 1.0f, 0f, 0f, 1.0f, 0f, 0f, 1.0f, 0f,

    0f, -1.0f, 0f, /* bottom */
    0f, -1.0f, 0f, 0f, -1.0f, 0f, 0f, -1.0f, 0f, };
    private static FloatBuffer cubenBuffer;

    private static FloatBuffer loadCuben() {
      if (cubenBuffer == null) {
        cubenBuffer = OpenGLUtils.allocateFloatBuffer(72 * 4);
        for (int i = 0; i < 72; i++)
          cubenBuffer.put(cuben[i]);

        cubenBuffer.position(0);
      }
      return cubenBuffer;
    }

    private static FloatBuffer cubevBuffer;

    private static FloatBuffer loadCubev(float size) {
      // TODO size
      if (cubevBuffer == null) {
        size /= 2;

        cubevBuffer = OpenGLUtils.allocateFloatBuffer(72 * 4);

        for (int i = 0; i < 72; i++) {
          cubevBuffer.put(cubev[i] * size);
          Log.d("", "" + cubev[i] * size);
        }
        cubevBuffer.position(0);
      }

      return cubevBuffer;
    }

    private static float param;

    public static void draw(GL10 gl, float size) {

      if (cubevBuffer != null) {
        if (param != size) {
          cubevBuffer = null;
          cubenBuffer = null;
          gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
          gl.glNormalPointer(GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
        }
      }

      if (cubenBuffer == null) {
        cubevBuffer = loadCubev(size);
        cubenBuffer = loadCuben();
        param = size;
      }

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubevBuffer);
      gl.glNormalPointer(GL10.GL_FLOAT, 0, cubenBuffer);

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

      for (int i = 0; i < 6; i++)
        gl.glDrawArrays(GL10.GL_LINE_LOOP, 4 * i, 4);

      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

    }
  }

  public static void glutWireTorus(GL10 gl, float dInnerRadius,
      float dOuterRadius, int nSides, int nRings) {
    WireTorus.draw(gl, dInnerRadius, dOuterRadius, nSides, nRings);
  }

  public static class WireTorus {
    private static FloatBuffer p = null, q = null;
    private static FloatBuffer v = null, n = null;
    private static float parms[] = new float[4];// static

    /*
     * sometime it make heap problem
     */
    private static void draw(GL10 gl, float ir, float or, int sides,
        int rings) {
      int SIZEOF = 4;
      int i, j, k, triangles;
      float s, t, x, y, z, twopi, nx, ny, nz;
      float sin_s, cos_s, cos_t, sin_t, twopi_s, twopi_t;
      float twopi_sides, twopi_rings;

      // maybe clear buffer.
      if (v != null) {
        if (parms[0] != ir || parms[1] != or || parms[2] != sides
            || parms[3] != rings) {

          // free(v);
          // free(n);
          n = v = null; // maybe free later.

          gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
          gl.glNormalPointer(GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
        }
      }

      if (v == null) {
        parms[0] = ir;
        parms[1] = or;
        parms[2] = (float) sides;
        parms[3] = (float) rings;

        // this size is maybe wrong.
        p = v = OpenGLUtils.allocateFloatBuffer((int) (sides
            * (rings + 1) * 2 * 3 * SIZEOF));
        q = n = OpenGLUtils.allocateFloatBuffer((int) (sides
            * (rings + 1) * 2 * 3 * SIZEOF));

        twopi = 2.0f * (float) Math.PI;
        twopi_sides = twopi / sides;
        twopi_rings = twopi / rings;

        for (i = 0; i < sides; i++) {
          for (j = 0; j <= rings; j++) {
            for (k = 1; k >= 0; k--) {
              s = (i + k) % sides + 0.5f;
              t = (float) (j % rings);

              twopi_s = s * twopi_sides;
              twopi_t = t * twopi_rings;

              cos_s = (float) Math.cos(twopi_s);
              sin_s = (float) Math.sin(twopi_s);

              cos_t = (float) Math.cos(twopi_t);
              sin_t = (float) Math.sin(twopi_t);

              x = (or + ir * (float) cos_s) * (float) cos_t;
              y = (or + ir * (float) cos_s) * (float) sin_t;
              z = ir * (float) sin_s;

              p.put(x);
              p.put(y);
              p.put(z);

              nx = (float) cos_s * (float) cos_t;
              ny = (float) cos_s * (float) sin_t;
              nz = (float) sin_s;

              q.put(nx);
              q.put(ny);
              q.put(nz);
            }
          }
        }
      }

      // Log.d("cap",""+v+","+p+"");

      v.position(0);
      n.position(0);
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, v);
      gl.glNormalPointer(GL10.GL_FLOAT, 0, n);

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

      triangles = ((int) rings + 1) * 2;

      for (i = 0; i < sides; i++) {
        gl.glDrawArrays(GL10.GL_LINE_LOOP, triangles * i, triangles);
      }

      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

    }

  }


  public static void glutSolidSphere(GL10 gl, float radius, int slices,
      int stacks) {
    SolidSphere.draw(gl, radius, slices, stacks);
  }

  public static class SolidSphere {
    public static void draw(GL10 gl, float radius, int slices, int stacks) {
      int i, triangles;

      if (sphereVertex != null) {
        if (sphere_parms[0] != radius || sphere_parms[1] != slices
            || sphere_parms[2] != stacks) {
          sphereVertex = null;
          sphereNormal = null;

          gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
          gl.glNormalPointer(GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
        }
      }

      if (sphereVertex == null) {
        sphere_parms[0] = radius;
        sphere_parms[1] = (float) slices;
        sphere_parms[2] = (float) stacks;

        plotSpherePoints(radius, stacks, slices);

      }

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, sphereVertex);
      gl.glNormalPointer(GL10.GL_FLOAT, 0, sphereNormal);

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

      triangles = (slices + 1) * 2;

      for (i = 0; i < stacks; i++)
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * triangles,
            triangles);

      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

    }
  }

  public static void glutWireSphere(GL10 gl, float radius, int slices,
      int stacks) {
    WireSphere.draw(gl, radius, slices, stacks);
  }

  public static class WireSphere {
    public static void draw(GL10 gl, float radius, int slices, int stacks) {

      if (sphereVertex != null) {
        if (sphere_parms[0] != radius || sphere_parms[1] != slices
            || sphere_parms[2] != stacks) {
          sphereVertex = null;
          sphereNormal = null;

          gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
          gl.glNormalPointer(GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
        }
      }

      if (sphereVertex == null) {
        sphere_parms[0] = radius;
        sphere_parms[1] = (float) slices;
        sphere_parms[2] = (float) stacks;

        plotSpherePoints(radius, stacks, slices);

      }

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, sphereVertex);
      gl.glNormalPointer(GL10.GL_FLOAT, 0, sphereNormal);

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

      int f;
      for (int i = 0; i < stacks; ++i) {
        f = i * (slices + 1);

        for (int j = 0; j <= slices; ++j)
          gl.glDrawArrays(GL10.GL_LINE_LOOP, (f + j) * 2, 3);
      }

      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);

    }
  }

  static private FloatBuffer sphereVertex;
  static private FloatBuffer sphereNormal;
  static float sphere_parms[] = new float[3];

  private static void plotSpherePoints(float radius, int stacks, int slices) {
    sphereVertex = OpenGLUtils.allocateFloatBuffer(4 * 6 * stacks
        * (slices + 1));
    sphereNormal = OpenGLUtils.allocateFloatBuffer(4 * 6 * stacks
        * (slices + 1));
    int i, j;
    float slicestep, stackstep;

    stackstep = ((float) Math.PI) / stacks;
    slicestep = 2.0f * ((float) Math.PI) / slices;

    for (i = 0; i < stacks; ++i) {
      float a = i * stackstep;
      float b = a + stackstep;

      float s0 = (float) Math.sin(a);
      float s1 = (float) Math.sin(b);

      float c0 = (float) Math.cos(a);
      float c1 = (float) Math.cos(b);

      float nv;
      for (j = 0; j <= slices; ++j) {
        float c = j * slicestep;
        float x = (float) Math.cos(c);
        float y = (float) Math.sin(c);

        nv = x * s0;
        sphereNormal.put(nv);
        sphereVertex.put(nv * radius);

        nv = y * s0;
        sphereNormal.put(nv);
        sphereVertex.put(nv * radius);

        nv = c0;

        sphereNormal.put(nv);
        sphereVertex.put(nv * radius);

        nv = x * s1;

        sphereNormal.put(nv);
        sphereVertex.put(nv * radius);

        nv = y * s1;

        sphereNormal.put(nv);
        sphereVertex.put(nv * radius);

        nv = c1;

        sphereNormal.put(nv);
        sphereVertex.put(nv * radius);
      }
    }
    sphereNormal.position(0);
    sphereVertex.position(0);
  }

  public static void glutSolidCone(GL10 gl, float base, float height,
      int slices, int stacks) {
    SolidCone.glutCone(gl, base, height, slices, stacks, true);
  }

  public static void glutWireCone(GL10 gl, float base, float height,
      int slices, int stacks) {
    SolidCone.glutCone(gl, base, height, slices, stacks, false);
  }

  static float cone_parms[] = new float[4];
  static private FloatBuffer coneVertex;
  static private FloatBuffer coneNormal;

  public static class SolidCone {
    static int SIZEOF = 4;

    public static void glutCone(GL10 gl, float base, float height,
        int slices, int stacks, boolean isSolid) {
      int i, j;
      float twopi, nx, ny, nz;

      if (coneVertex != null) {
        if (cone_parms[0] != base || cone_parms[1] != height
            || cone_parms[2] != slices || cone_parms[3] != stacks) {
          coneVertex = null;
          coneNormal = null;

          gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
          gl.glNormalPointer(GL10.GL_FLOAT, 0,
              OpenGLUtils.allocateFloatBuffer(0));
        }
      }

      if ((coneVertex == null) && (height != 0.0f)) {
        float phi = (float) Math.atan(base / height);
        float cphi = (float) Math.cos(phi);
        float sphi = (float) Math.sin(phi);

        cone_parms[0] = base;
        cone_parms[1] = height;
        cone_parms[2] = (float) slices;
        cone_parms[3] = (float) stacks;
        coneVertex = OpenGLUtils.allocateFloatBuffer(stacks
            * (slices + 1) * 2 * 3 * SIZEOF);
        coneNormal = OpenGLUtils.allocateFloatBuffer(stacks
            * (slices + 1) * 2 * 3 * SIZEOF);

        twopi = 2.0f * ((float) Math.PI);

        for (i = 0; i < stacks; i++) {
          float r = base * (1.0f - (float) i / stacks);
          float r1 = base * (1.0f - (float) (i + 1.0) / stacks);
          float z = height * i / stacks;
          float z1 = height * (1.0f + i) / stacks;

          for (j = 0; j <= slices; j++) {
            float theta = j == slices ? 0.f : (float) j / slices
                * twopi;
            float ctheta = (float) Math.cos(theta);
            float stheta = (float) Math.sin(theta);

            nx = ctheta;
            ny = stheta;
            nz = sphi;

            coneVertex.put(r1 * nx);
            coneVertex.put(r1 * ny);
            coneVertex.put(z1);

            coneNormal.put(nx * cphi);
            coneNormal.put(ny * cphi);
            coneNormal.put(nz);

            coneVertex.put(r * nx);
            coneVertex.put(r * ny);
            coneVertex.put(z);

            coneNormal.put(nx * cphi);
            coneNormal.put(ny * cphi);
            coneNormal.put(nz);

          }
        }
        coneVertex.position(0);
        coneNormal.position(0);
      }

      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, coneVertex);
      gl.glNormalPointer(GL10.GL_FLOAT, 0, coneNormal);

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

      for (i = 0; i < stacks; i++) {
        if (isSolid) {
          gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * (slices + 1)
              * 2, (slices + 1) * 2);
        } else {
          gl.glDrawArrays(GL10.GL_LINE_LOOP, i * (slices + 1) * 2,
              (slices + 1) * 2);

        }
      }

      gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
    }
  }
}

Reshaping Arabic Sentences and Text Utilities to deal with Arabic

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Typeface;
import android.view.Gravity;
import android.widget.TextView;

/**
 * This class is the main class that is responsible for Reshaping Arabic Sentences and Text
 * Utilities Class to make it easier to deal with Arabic Reshaper Class
 * Wrapper for Arabic Reshaper Class
 * @author Amr Gawish
 */
public class ArabicUtilities {

         /**
   * the path of teh fonts file must be under assets folder
   */
  private static final String FONTS_LOCATION_PATH = "fonts/me_quran.ttf";
        static Typeface face ;



  /**
   * Helper function is to check if the character passed, is Arabic
   * @param target The Character to check Against
   * @return true if the Character is Arabic letter, otherwise returns false
   */
  private static boolean isArabicCharacter(char target){

    //Iterate over the 36 Characters in ARABIC_GLPHIES Matrix
    for(int i = 0; i < ArabicReshaper.ARABIC_GLPHIES.length;i++){
      //Check if the target Character exist in ARABIC_GLPHIES Matrix
      if(ArabicReshaper.ARABIC_GLPHIES[i][0]==target)
        return true;
    }

                for(int i = 0; i < ArabicReshaper.HARAKATE.length;i++){
      //Check if the target Character exist in ARABIC_GLPHIES Matrix
      if(ArabicReshaper.HARAKATE[i]==target)
        return true;
    }

    return false;
  }

  /**
   * Helper function to split Sentence By Space
   * @param sentence the Sentence to Split into Array of Words
   * @return Array Of words
   */
  private static String[] getWords(String sentence){
    if (sentence != null) {
      return sentence.split("\\s");
    } else {
      return new String[0];
    }
  }

  /**
   * Helper function to check if the word has Arabic Letters
   * @param word The to check Against
   * @return true if the word has Arabic letters, false otherwise
   */
  public static boolean hasArabicLetters(String word){

    //Iterate over the word to check all the word's letters
    for(int i=0;i<word.length();i++){

      if(isArabicCharacter(word.charAt(i)))
        return true;
    }
    return false;
  }

  /**
   * Helper function to check if the word is all Arabic Word
   * @param word The word to check against
   * @return true if the word is Arabic Word, false otherwise
   */
  public static boolean isArabicWord(String word){
    //Iterate over the Word
    for(int i=0;i<word.length();i++){
      if(!isArabicCharacter(word.charAt(i)))
        return false;
    }
    return true;
  }

  /**
   * Helper function to split the Mixed Word into words with only Arabic, and English Words
   * @param word The Mixed Word
   * @return The Array of the Words of each Word may exist inside that word
   */
  private static String[] getWordsFromMixedWord(String word){

    //The return result of words
    ArrayList finalWords=new ArrayList();

    //Temp word to hold the current word
    String tempWord="";

    //Iterate over the Word Length
    for(int i=0;i<word.length();i++){

      //Check if the Character is Arabic Character
      if(isArabicCharacter(word.charAt(i))){

        //Check if the tempWord is not empty, and what left in tempWord is not Arabic Word
        if(!tempWord.equals("") && !isArabicWord(tempWord)) {

          //add the Word into the Array
          finalWords.add(tempWord);

          //initiate the tempWord again
          tempWord=""+word.charAt(i);

        }else{

          //Not to add the tempWord, but to add the character to the rest of the characters
          tempWord+=word.charAt(i);
        }

      }else{

        //Check if the tempWord is not empty, and what left in tempWord is Arabic Word
        if(!tempWord.equals("") && isArabicWord(tempWord)){

          //add the Word into the Array
          finalWords.add(tempWord);

          //initiate the tempWord again
          tempWord=""+word.charAt(i);

        }else{

          //Not to add the tempWord, but to add the character to the rest of the characters
          tempWord+=word.charAt(i);
        }
      } 
    }

    String[] theWords=new String[finalWords.size()];
    theWords=(String[])finalWords.toArray(theWords);

    return theWords;
  }

  public static String reshape(String allText) {
    if (allText != null) {
      StringBuffer result = new StringBuffer();
      String[] sentences = allText.split("\n");
      for (int i = 0; i < sentences.length; i++) {
        result.append(reshapeSentence(sentences[i]));
        result.append("\n");
      }
      return result.toString();
    } else {
      return null;
    }
    
  }
  /**
   * The Main Reshaping Function to be Used in Android Program
   * @param allText The text to be Reshaped
   * @return the Reshaped Text
   */
  public static String reshapeSentence(String sentence){
      
      //get the Words from the Text
      String[] words=getWords(sentence);

      //prepare the Reshaped Text
      StringBuffer reshapedText=new StringBuffer("");

      //Iterate over the Words
      for(int i=0;i<words.length;i++){

        //Check if the Word has Arabic Letters
        if(hasArabicLetters(words[i])){

          //Check if the Whole word is Arabic
          if(isArabicWord(words[i])){

            //Initiate the ArabicReshaper functionality
            ArabicReshaper arabicReshaper=new ArabicReshaper(words[i],true);

            //Append the Reshaped Arabic Word to the Reshaped Whole Text
            reshapedText.append(arabicReshaper.getReshapedWord());
          }else{ //The word has Arabic Letters, but its not an Arabic Word, its a mixed word

            //Extract words from the words (split Arabic, and English)
            String [] mixedWords=getWordsFromMixedWord(words[i]);

            //iterate over mixed Words
            for(int j=0;j<mixedWords.length;j++){

              //Initiate the ArabicReshaper functionality
              ArabicReshaper arabicReshaper=new ArabicReshaper(mixedWords[j],true);

              //Append the Reshaped Arabic Word to the Reshaped Whole Text
              reshapedText.append(arabicReshaper.getReshapedWord());
            }
          }  
        }else{//The word doesn't have any Arabic Letters

          //Just append the word to the whole reshaped Text
          reshapedText.append(words[i]);
        }

        //Append the space to separate between words
        reshapedText.append(" ");
      }

      //return the final reshaped whole text
      return reshapedText.toString();
  }
  
  public static TextView getArabicEnabledTextView(Context context, TextView targetTextView) {
    //this is a static for testing!
    if (face == null) {
      face = Typeface.createFromAsset(context.getAssets(), FONTS_LOCATION_PATH);
    }
    targetTextView.setTypeface(face);
    targetTextView.setGravity(Gravity.RIGHT);
    return targetTextView;
  }
}


 class ArabicReshaper{
  /**
   * The reshaped Word String
   */
  private String _returnString;


  /**
   * The Reshaped Word
   * @return reshaped Word
   */
  public String getReshapedWord(){

    return _returnString;
  }

  
  public static char DEFINED_CHARACTERS_ORGINAL_ALF_UPPER_MDD = 0x0622;

  
  public static char DEFINED_CHARACTERS_ORGINAL_ALF_UPPER_HAMAZA = 0x0623;

  
  public static char DEFINED_CHARACTERS_ORGINAL_ALF_LOWER_HAMAZA = 0x0625;  
  
  
  public static char DEFINED_CHARACTERS_ORGINAL_ALF = 0x0627;

  
  public static char DEFINED_CHARACTERS_ORGINAL_LAM  =0x0644;



  
  public static char[][] LAM_ALEF_GLPHIES=
  {{15270,65270,65269},
   {15271,65272,65271},
   {1575, 65276,65275},
   {1573, 65274,65273}
  };

  public static char[] HARAKATE= {'\u064B', '\u064C', '\u064D','\u064E', '\u064F', '\u0650', '\u0651',
                     '\u0652', '\u0653', '\u0654', '\u0655', '\u0656'};

  public static char[][] ARABIC_GLPHIES=
       {{ 1569,65152,65163,65164,65152,3 } ,
      { 1570,65153,65153,65154,65154,2 } ,
      { 1571,65155,65155,65156,65156,2 } ,
      { 1572,65157,65157,65158,65158,2 } ,
      { 1573,65159,65159,65160,65160,2 } ,
      { 1575,65165,65165,65166,65166,2 } ,
      { 1576,65167,65169,65170,65168,4 } ,
      { 1577,65171,65171,65172,65172,2 } ,
      { 1578,65173,65175,65176,65174,4 } ,
      { 1579,65177,65179,65180,65178,4 } ,
      { 1580,65181,65183,65184,65182,4 } ,
      { 1581,65185,65187,65188,65186,4 } ,
      { 1582,65189,65191,65192,65190,4 } ,
      { 1583,65193,65193,65194,65194,2 } ,
      { 1584,65195,65195,65196,65196,2 } ,
      { 1585,65197,65197,65198,65198,2 } ,
      { 1586,65199,65199,65200,65200,2 } ,
      { 1587,65201,65203,65204,65202,4 } ,
      { 1588,65205,65207,65208,65206,4 } ,
      { 1589,65209,65211,65212,65210,4 } ,
      { 1590,65213,65215,65216,65214,4 } ,
      { 1591,65217,65219,65218,65220,4 } ,
      { 1592,65221,65223,65222,65222,4 } ,
      { 1593,65225,65227,65228,65226,4 } ,
      { 1594,65229,65231,65232,65230,4 } ,
      { 1601,65233,65235,65236,65234,4 } ,
      { 1602,65237,65239,65240,65238,4 } ,
      { 1603,65241,65243,65244,65242,4 } ,
      { 1604,65245,65247,65248,65246,4 } ,
      { 1605,65249,65251,65252,65250,4 } ,
      { 1606,65253,65255,65256,65254,4 } ,
      { 1607,65257,65259,65260,65258,4 } ,
      { 1608,65261,65261,65262,65262,2 } ,
      { 1609,65263,65263,65264,65264,2 } ,
      { 1574,65161,65163,65163,65162,2 } ,
      { 1610,65265,65267,65268,65266,4 } };


  /**
   * Searching for the letter and Get the right shape for the character depends on the location specified 
   * @param target The character that needs to get its form
   * @param location The location of the Form letter
   * @return The letter with its right shape
   */
  private char getReshapedGlphy(char target,int location){
    //Iterate over the 36 characters in the GLPHIES Matrix
    for(int n = 0; n<ARABIC_GLPHIES.length;n++)
    {
      //Check if the character equals the target character
      if(ARABIC_GLPHIES[n][0]==target)
      {
        //Get the right shape for the character, depends on the location
        return ARABIC_GLPHIES[n][location];
      }
    }
    //get the same character, If not found in the GLPHIES Matrix
    return target;
  }

  /**
   * Define which Character Type is This, that has 2,3 or 4 Forms variation?
   * @param target The character, that needed 
   * @return the integer number indicated the Number of forms the Character has, return 2 otherwise
   */
  private int getGlphyType(char target){
    //Iterate over the 36 characters in the GLPHIES Matrix
    for(int n = 0; n<36;n++)
    {
      //Check if the character equals the target character
      if(ARABIC_GLPHIES[n][0]==target)
        //Get the number of Forms that the character has
        return ARABIC_GLPHIES[n][5];
    }
    //Return the number 2 Otherwise
    return 2;
  }

        private boolean isHaraka(char target) {
    
    return getHaraka(target) > 0;
  }

  private char getHaraka(char target){
    //Iterate over the 36 characters in the GLPHIES Matrix
    for(int n = 0; n<HARAKATE.length;n++)
    {
      //Check if the character equals the target character
      if(HARAKATE[n]==target)
        //Get the number of Forms that the character has
        return HARAKATE[n];
    }
    return 0;
  }


  /**
   * Get LamAlef right Character Presentation of the character
   * @param candidateAlef The letter that is supposed to Alef
   * @param candidateLam The letter that is supposed to Lam
   * @param isEndOfWord Is those characters at the end of the Word, to get its right form 
   * @return Reshaped character of the LamAlef
   */
  private char getLamAlef(char candidateAlef,char candidateLam,boolean isEndOfWord){
    //The shift rate, depends if the the end of the word or not!
    int shiftRate = 1;

    //The reshaped Lam Alef
    char reshapedLamAlef=0;

    //Check if at the end of the word
    if(isEndOfWord)
      shiftRate++;

    //check if the Lam is matching the candidate Lam
    if((int)DEFINED_CHARACTERS_ORGINAL_LAM ==(int)candidateLam){

      //Check which Alef is matching after the Lam and get Its form
      if((int)candidateAlef ==(int)DEFINED_CHARACTERS_ORGINAL_ALF_UPPER_MDD){
        reshapedLamAlef = LAM_ALEF_GLPHIES[0][shiftRate];
      }

      if((int)candidateAlef ==(int)DEFINED_CHARACTERS_ORGINAL_ALF_UPPER_HAMAZA){
        reshapedLamAlef = LAM_ALEF_GLPHIES[1][shiftRate];
      }

      if((int)candidateAlef ==(int)DEFINED_CHARACTERS_ORGINAL_ALF_LOWER_HAMAZA){
        reshapedLamAlef = LAM_ALEF_GLPHIES[3][shiftRate];
      }

      if((int)candidateAlef ==(int)DEFINED_CHARACTERS_ORGINAL_ALF){
        reshapedLamAlef = LAM_ALEF_GLPHIES[2][shiftRate];
      }      
      
    }
    //return the ReshapedLamAlef
    return reshapedLamAlef;
  }


  /**
   * Constructor of the Class
   * It doesn't support Alef Lam by Default
   * @param unshapedWord The unShaped Word
   */
  public ArabicReshaper(String unshapedWord){
    _returnString=reshapeIt(unshapedWord);
  }


  /**
   * The Enhanced Arabic Reshaper Constructor with Lam Alef Support
   * @param unshapedWord The unShaped Word
   * @param supportAlefLam To check If to support AlefLam or Not
   */
  public ArabicReshaper(String unshapedWord,boolean supportAlefLam){
    DecomposedWord decomposedWord = new DecomposedWord(unshapedWord);
    if(!supportAlefLam) {
      _returnString=reshapeIt(new String(decomposedWord.stripedRegularLetters));
    }else {
      _returnString=reshapeItWithLamAlef(new String(decomposedWord.stripedRegularLetters));
    }
    _returnString = decomposedWord.reconstructWord(_returnString);
  }

        class DecomposedWord {
    char[] stripedHarakates ;
    int[] harakatesPositions;
    char[] stripedRegularLetters;
    int[] lettersPositions;
    
    DecomposedWord(String unshapedWord) {
      int wordLength = unshapedWord.length();
      int harakatesCount = 0;
      for(int index = 0; index < wordLength; index++ ) {
        if (isHaraka(unshapedWord.charAt(index))) {
          harakatesCount++;
        }
      }
      harakatesPositions = new int[harakatesCount];
      stripedHarakates = new char[harakatesCount];
      lettersPositions = new int[wordLength - harakatesCount];
      stripedRegularLetters = new char[wordLength - harakatesCount];
      
      harakatesCount = 0;
      int letterCount = 0;
      for(int index = 0; index < unshapedWord.length(); index++ ) {
        if (isHaraka(unshapedWord.charAt(index))) {
          harakatesPositions[harakatesCount] = index;
          stripedHarakates[harakatesCount] = unshapedWord.charAt(index);
          harakatesCount++;
        } else {
          lettersPositions[letterCount] = index;
          stripedRegularLetters[letterCount] = unshapedWord.charAt(index);
          letterCount++;
        }
      }
    }

                String reconstructWord(String reshapedWord) {
      char[] wordWithHarakates = new char[reshapedWord.length() + stripedHarakates.length];
      for(int index = 0; index < lettersPositions.length; index++) {
        wordWithHarakates[lettersPositions[index]] = reshapedWord.charAt(index);
      }
      
      for(int index = 0; index < harakatesPositions.length; index++) {
        wordWithHarakates[harakatesPositions[index]] = stripedHarakates[index];
      }
      return new String(wordWithHarakates);
      
    }
  }

  /**
   * Main Reshaping function, Doesn't Support LamAlef
   * @param unshapedWord The unReshaped Word to Reshape
   * @return The Reshaped Word without the LamAlef Support
   */
  public String reshapeIt(String unshapedWord){

    //The reshaped Word to Return
    StringBuffer reshapedWord=new StringBuffer("");

    //The Word length
    int wordLength = unshapedWord.length();

    //The Word Letters
    char [] wordLetters = new char[wordLength];

    //Copy the unreshapedWord to the WordLetters Character Array
    unshapedWord.getChars(0, wordLength, wordLetters,0 );


    //for the first letter
    reshapedWord.append(getReshapedGlphy(wordLetters[0], 2));//2 is the Form when the Letter is at the start of the word


    //iteration from the second till the second to last
    for(int i=1;i<wordLength-1;i++){
      int beforeLast=i-1;
        //Check if the Letter Before Last has only 2 Forms, for the current Letter to be as a start for a new Word!
        if(getGlphyType(wordLetters[beforeLast])==2){ //checking if it's only has 2 shapes
          //If the letter has only 2 shapes, then it doesnt matter which position it is, It'll be always the second form
          reshapedWord.append(getReshapedGlphy(wordLetters[i], 2));
        }else {
          //Then it should be in the middle which should be placed in its right form [3]
          reshapedWord.append(getReshapedGlphy(wordLetters[i], 3));
        }
    }

    //check for the last letter Before last has 2 forms, that means that the last Letter will be alone.
    if(getGlphyType(wordLetters[wordLength-2])==2){
      //If the letter has only 2 shapes, then it doesnt matter which position it is, It'll be always the second form
      reshapedWord.append(getReshapedGlphy(wordLetters[wordLength-1], 1));
    }else {
      //Put the right form of the character, 4 for the last letter in the word
      reshapedWord.append(getReshapedGlphy(wordLetters[wordLength-1], 4));
    }

    //Return the ReshapedWord
    return reshapedWord.toString();
  }


  /**
   * Main Reshaping Function, With LamAlef Support
   * @param unshapedWord The UnReshaped Word
   * @return The Shaped Word with Lam Alef Support
   */
  public String reshapeItWithLamAlef(String unshapedWord){

    //The reshaped Word to Return
    StringBuffer reshapedWord=new StringBuffer("");

    //The Word length
    int wordLength = unshapedWord.length();

    //The Word Letters
    char [] wordLetters = new char[wordLength];

    //The reshaped Letters
    char [] reshapedLetters=new char[wordLength];

    //Indicator Character, to Tell that lam is exist
    char lamIndicator=43;//The '+' 

    //Copy the unreshapedWord to the WordLetters Character Array
    unshapedWord.getChars(0, wordLength, wordLetters,0 );

    //Check if the Word Length is 0, then return empty String
    if(wordLength==0){
      return "";
    }

    //Check if the Word length is 1, then return the Reshaped One letter, which is the same character of input
    if(wordLength==1){
      return getReshapedGlphy(wordLetters[0],1)+"";
    }

    //Check if the word length is 2, Check if the Word is LamAlef 
    if(wordLength==2){
      //Assign Candidate Lam
      char lam=wordLetters[0];

      //Assign Candidate Alef
      char alef=wordLetters[1];

      //Check if The word is Lam Alef.
      if(getLamAlef(alef, lam, true)>0){
        return (char)getLamAlef(alef,lam,true)+" ";
      }

    }

    //For the First Letter
    reshapedLetters[0]=getReshapedGlphy(wordLetters[0], 2);

    //The current Letter
    char currentLetter=wordLetters[0];

    /**
     * The Main Iterator
     */

    //Iterate over the word from the second character till the second to the last
    for(int i=1;i<wordLength-1;i++){

      //Check if the Letters are Lam Alef
      if(getLamAlef(wordLetters[i], currentLetter, true)>0){
        //Check if the Letter before the Lam is 2 Forms Letter, to Make the Lam Alef as its the end of the Word
        if((i-2 < 0) || ((i-2 >= 0) &&  (getGlphyType(wordLetters[i-2])==2))){

          //Mark the letter of Lam as Lam Indicator
          reshapedLetters[i-1]=lamIndicator;

          //Assign Lam Alef to the Letter of Alef
          reshapedLetters[i]=(char)getLamAlef(wordLetters[i], currentLetter, true);

        }else{ //The Letter before the Lam is more than 2 Forms Letter

          //Mark the letter of Lam as Lam Indicator
          reshapedLetters[i-1]=lamIndicator;

          //Assign Lam Alef to the Letter of Alef
          reshapedLetters[i]=(char)getLamAlef(wordLetters[i], currentLetter, false);
        }
      }else{ //The Word doesn't have LamAlef

        int beforeLast=i-1;

        //Check if the Letter Before Last has only 2 Forms, for the current Letter to be as a start for a new Word!
        if(getGlphyType(wordLetters[beforeLast])==2){

          //If the letter has only 2 shapes, then it doesnt matter which position it is, It'll be always the second form
          reshapedLetters[i]=getReshapedGlphy(wordLetters[i], 2);
        }else{

          //Then it should be in the middle which should be placed in its right form [3]
          reshapedLetters[i]=getReshapedGlphy(wordLetters[i], 3);
        }
      }
      //Assign the CurrentLetter as the Word Letter
      currentLetter=wordLetters[i];
    }


    /**
     * The Last Letters Check
     */

    //Check if the Letters are Lam Alef
    if(getLamAlef(wordLetters[wordLength-1], wordLetters[wordLength-2], true)>0){

      //Check if the Letter before the Lam is 2 Forms Letter, to Make the Lam Alef as its the end of the Word
      if(getGlphyType(wordLetters[wordLength-3])==2){ //check for the last letter

        //Mark the letter of Lam as Lam Indicator
        reshapedLetters[wordLength-2]=lamIndicator;

        //Assign Lam Alef to the Letter of Alef
        reshapedLetters[wordLength-1]=(char)getLamAlef(wordLetters[wordLength-1], wordLetters[wordLength-2], true);
      }else {

        //Mark the letter of Lam as Lam Indicator
        reshapedLetters[wordLength-2]=lamIndicator;

        //Assign Lam Alef to the Letter of Alef
        reshapedLetters[wordLength-1]=(char)getLamAlef(wordLetters[wordLength-1], wordLetters[wordLength-2], false);
      }

    }else { 
      //check for the last letter Before last has 2 forms, that means that the last Letter will be alone.
      if(getGlphyType(wordLetters[wordLength-2])==2){
        //If the letter has only 2 shapes, then it doesn't matter which position it is, It'll be always the second form
        reshapedLetters[wordLength-1]=getReshapedGlphy(wordLetters[wordLength-1], 1);
      }else {
        //Put the right form of the character, 4 for the last letter in the word
        reshapedLetters[wordLength-1]=getReshapedGlphy(wordLetters[wordLength-1], 4);
      }
    }

    /**
     * Assign the Final Results of Shaped Word
     */

    //Iterate over the Reshaped Letters and remove the Lam Indicators
    for(int i=0;i<reshapedLetters.length;i++){

      //Check if the Letter is Lam Indicator
      if(reshapedLetters[i]!=lamIndicator)
        reshapedWord.append(reshapedLetters[i]);
    }

    //Return the Reshaped Word
    return reshapedWord.toString();
  }  
}

Save SharedPreferences

 
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Vibrator;

 class Utils {

  public static SharedPreferences preferencias;
  public static Vibrator v;
  public static final int CORTO = 50;
  public static final int LARGO = 500;
  static public void guardarNombre(String id, String nombre){
    SharedPreferences.Editor editor = preferencias.edit();
      editor.putString(id, nombre);
      editor.commit();
  }
  
}  

Save value to SharedPreferences

 

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;


class Library {

  // ---------------------
  /** Update shared preferences from State */
  public static void savePreferences(Context context) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
    SharedPreferences.Editor editor = prefs.edit();
    editor.putBoolean("silentMode", true);
    editor.putString("language", "State.getLanguage()");
    editor.commit();
  }

}



SharedPreferences Set and get value

 
//package shoozhoo.libandrotranslation;

import java.io.Closeable;
import java.util.Locale;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;

class LibAndTransUtil {
  private static String KEY_APPTRANSLATION = "KEY_APPTRANSLATION";
  private static String KEY_LANG = "KEY_LANG";
  public static String getTranslationLang(Context ctx){
    SharedPreferences pref = ctx.getSharedPreferences(KEY_APPTRANSLATION, Context.MODE_PRIVATE);
    if(pref==null){
      return "";
    }
    return pref.getString(KEY_LANG, Locale.getDefault().getLanguage());
  }
  public static void saveTranslationLang(Context ctx, String lang){
    SharedPreferences pref = ctx.getSharedPreferences(KEY_APPTRANSLATION, Context.MODE_PRIVATE);
    Editor editor = pref.edit();
    editor.putString(KEY_LANG, lang);
    editor.commit();
  }
}
Compute the SHA-1 hash of the given byte array
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


//package atorrentapi;


class Main {
  /**
   * Compute the SHA-1 hash of the given byte array
   * 
   * @param hashThis
   *            byte[]
   * @return byte[]
   */
  public static byte[] hash(byte[] hashThis) {
    try {
      byte[] hash = new byte[20];
      MessageDigest md = MessageDigest.getInstance("SHA-1");

      hash = md.digest(hashThis);
      return hash;
    } catch (NoSuchAlgorithmException nsae) {
      System.err.println("SHA-1 algorithm is not available...");
      System.exit(2);
    }
    return null;
  }


}

compute SHA-1 Hash

 

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class CryptoUtils {
  public static String computeHash(final String x) throws NoSuchAlgorithmException
  {
    MessageDigest d = null;
    d = MessageDigest.getInstance("SHA-1");
    d.reset();
    d.update(x.getBytes());
    return  byteArrayToHexString(d.digest());
  }

  private static String byteArrayToHexString(final byte[] b){
    final StringBuffer sb = new StringBuffer(b.length * 2);
    for (int i = 0; i < b.length; i++){
      final int v = b[i] & 0xff;
      if (v < 16) {
        sb.append('0');
      }
      sb.append(Integer.toHexString(v));
    }
    return sb.toString().toUpperCase();
  }

}