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(); } }