# HG changeset patch # User Tomas Zeman # Date 1389353047 -3600 # Node ID c3780fcb8441dceff9852b62977a448099834e3e # Parent c06669391cd20318141c75ae2ae6c067aedac52f Imported code from the blog post (renamed namespace com.as400samplecode -> tz.signaturecapture). diff -r c06669391cd2 -r c3780fcb8441 AndroidManifest.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AndroidManifest.xml Fri Jan 10 12:24:07 2014 +0100 @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff -r c06669391cd2 -r c3780fcb8441 ic_launcher-web.png Binary file ic_launcher-web.png has changed diff -r c06669391cd2 -r c3780fcb8441 libs/android-support-v4.jar Binary file libs/android-support-v4.jar has changed diff -r c06669391cd2 -r c3780fcb8441 proguard-project.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/proguard-project.txt Fri Jan 10 12:24:07 2014 +0100 @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff -r c06669391cd2 -r c3780fcb8441 project.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project.properties Fri Jan 10 12:24:07 2014 +0100 @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-19 diff -r c06669391cd2 -r c3780fcb8441 res/drawable-hdpi/ic_launcher.png Binary file res/drawable-hdpi/ic_launcher.png has changed diff -r c06669391cd2 -r c3780fcb8441 res/drawable-mdpi/ic_launcher.png Binary file res/drawable-mdpi/ic_launcher.png has changed diff -r c06669391cd2 -r c3780fcb8441 res/drawable-xhdpi/ic_launcher.png Binary file res/drawable-xhdpi/ic_launcher.png has changed diff -r c06669391cd2 -r c3780fcb8441 res/drawable-xxhdpi/ic_launcher.png Binary file res/drawable-xxhdpi/ic_launcher.png has changed diff -r c06669391cd2 -r c3780fcb8441 res/values-v11/styles.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/res/values-v11/styles.xml Fri Jan 10 12:24:07 2014 +0100 @@ -0,0 +1,11 @@ + + + + + + diff -r c06669391cd2 -r c3780fcb8441 res/values-v14/styles.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/res/values-v14/styles.xml Fri Jan 10 12:24:07 2014 +0100 @@ -0,0 +1,12 @@ + + + + + + diff -r c06669391cd2 -r c3780fcb8441 res/values/strings.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/res/values/strings.xml Fri Jan 10 12:24:07 2014 +0100 @@ -0,0 +1,7 @@ + + + Signature capture + Hello World, CaptureSignatureActivity! + GetSignature + + diff -r c06669391cd2 -r c3780fcb8441 res/values/styles.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/res/values/styles.xml Fri Jan 10 12:24:07 2014 +0100 @@ -0,0 +1,20 @@ + + + + + + + + + diff -r c06669391cd2 -r c3780fcb8441 src/tz/signaturecapture/CaptureSignature.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tz/signaturecapture/CaptureSignature.java Fri Jan 10 12:24:07 2014 +0100 @@ -0,0 +1,352 @@ +package tz.signaturecapture; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.Calendar; + +import android.app.Activity; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RectF; +import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore.Images; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup.LayoutParams; +import android.view.Window; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.Toast; + +public class CaptureSignature extends Activity { + + LinearLayout mContent; + signature mSignature; + Button mClear, mGetSign, mCancel; + public static String tempDir; + public int count = 1; + public String current = null; + private Bitmap mBitmap; + View mView; + File mypath; + + private String uniqueId; + private EditText yourName; + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + this.requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.signature); + + tempDir = Environment.getExternalStorageDirectory() + "/" + getResources().getString(R.string.external_dir) + "/"; + ContextWrapper cw = new ContextWrapper(getApplicationContext()); + File directory = cw.getDir(getResources().getString(R.string.external_dir), Context.MODE_PRIVATE); + + prepareDirectory(); + uniqueId = getTodaysDate() + "_" + getCurrentTime() + "_" + Math.random(); + current = uniqueId + ".png"; + mypath= new File(directory,current); + + + mContent = (LinearLayout) findViewById(R.id.linearLayout); + mSignature = new signature(this, null); + mSignature.setBackgroundColor(Color.WHITE); + mContent.addView(mSignature, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); + mClear = (Button)findViewById(R.id.clear); + mGetSign = (Button)findViewById(R.id.getsign); + mGetSign.setEnabled(false); + mCancel = (Button)findViewById(R.id.cancel); + mView = mContent; + + yourName = (EditText) findViewById(R.id.yourName); + + mClear.setOnClickListener(new OnClickListener() + { + public void onClick(View v) + { + Log.v("log_tag", "Panel Cleared"); + mSignature.clear(); + mGetSign.setEnabled(false); + } + }); + + mGetSign.setOnClickListener(new OnClickListener() + { + public void onClick(View v) + { + Log.v("log_tag", "Panel Saved"); + boolean error = captureSignature(); + if(!error){ + mView.setDrawingCacheEnabled(true); + mSignature.save(mView); + Bundle b = new Bundle(); + b.putString("status", "done"); + Intent intent = new Intent(); + intent.putExtras(b); + setResult(RESULT_OK,intent); + finish(); + } + } + }); + + mCancel.setOnClickListener(new OnClickListener() + { + public void onClick(View v) + { + Log.v("log_tag", "Panel Canceled"); + Bundle b = new Bundle(); + b.putString("status", "cancel"); + Intent intent = new Intent(); + intent.putExtras(b); + setResult(RESULT_OK,intent); + finish(); + } + }); + + } + + @Override + protected void onDestroy() { + Log.w("GetSignature", "onDestory"); + super.onDestroy(); + } + + private boolean captureSignature() { + + boolean error = false; + String errorMessage = ""; + + + if(yourName.getText().toString().equalsIgnoreCase("")){ + errorMessage = errorMessage + "Please enter your Name\n"; + error = true; + } + + if(error){ + Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT); + toast.setGravity(Gravity.TOP, 105, 50); + toast.show(); + } + + return error; + } + + private String getTodaysDate() { + + final Calendar c = Calendar.getInstance(); + int todaysDate = (c.get(Calendar.YEAR) * 10000) + + ((c.get(Calendar.MONTH) + 1) * 100) + + (c.get(Calendar.DAY_OF_MONTH)); + Log.w("DATE:",String.valueOf(todaysDate)); + return(String.valueOf(todaysDate)); + + } + + private String getCurrentTime() { + + final Calendar c = Calendar.getInstance(); + int currentTime = (c.get(Calendar.HOUR_OF_DAY) * 10000) + + (c.get(Calendar.MINUTE) * 100) + + (c.get(Calendar.SECOND)); + Log.w("TIME:",String.valueOf(currentTime)); + return(String.valueOf(currentTime)); + + } + + + private boolean prepareDirectory() + { + try + { + if (makedirs()) + { + return true; + } else { + return false; + } + } catch (Exception e) + { + e.printStackTrace(); + Toast.makeText(this, "Could not initiate File System.. Is Sdcard mounted properly?", 1000).show(); + return false; + } + } + + private boolean makedirs() + { + File tempdir = new File(tempDir); + if (!tempdir.exists()) + tempdir.mkdirs(); + + if (tempdir.isDirectory()) + { + File[] files = tempdir.listFiles(); + for (File file : files) + { + if (!file.delete()) + { + System.out.println("Failed to delete " + file); + } + } + } + return (tempdir.isDirectory()); + } + + public class signature extends View + { + private static final float STROKE_WIDTH = 5f; + private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2; + private Paint paint = new Paint(); + private Path path = new Path(); + + private float lastTouchX; + private float lastTouchY; + private final RectF dirtyRect = new RectF(); + + public signature(Context context, AttributeSet attrs) + { + super(context, attrs); + paint.setAntiAlias(true); + paint.setColor(Color.BLACK); + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeJoin(Paint.Join.ROUND); + paint.setStrokeWidth(STROKE_WIDTH); + } + + public void save(View v) + { + Log.v("log_tag", "Width: " + v.getWidth()); + Log.v("log_tag", "Height: " + v.getHeight()); + if(mBitmap == null) + { + mBitmap = Bitmap.createBitmap (mContent.getWidth(), mContent.getHeight(), Bitmap.Config.RGB_565);; + } + Canvas canvas = new Canvas(mBitmap); + try + { + FileOutputStream mFileOutStream = new FileOutputStream(mypath); + + v.draw(canvas); + mBitmap.compress(Bitmap.CompressFormat.PNG, 90, mFileOutStream); + mFileOutStream.flush(); + mFileOutStream.close(); + String url = Images.Media.insertImage(getContentResolver(), mBitmap, "title", null); + Log.v("log_tag","url: " + url); + //In case you want to delete the file + //boolean deleted = mypath.delete(); + //Log.v("log_tag","deleted: " + mypath.toString() + deleted); + //If you want to convert the image to string use base64 converter + + } + catch(Exception e) + { + Log.v("log_tag", e.toString()); + } + } + + public void clear() + { + path.reset(); + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) + { + canvas.drawPath(path, paint); + } + + @Override + public boolean onTouchEvent(MotionEvent event) + { + float eventX = event.getX(); + float eventY = event.getY(); + mGetSign.setEnabled(true); + + switch (event.getAction()) + { + case MotionEvent.ACTION_DOWN: + path.moveTo(eventX, eventY); + lastTouchX = eventX; + lastTouchY = eventY; + return true; + + case MotionEvent.ACTION_MOVE: + + case MotionEvent.ACTION_UP: + + resetDirtyRect(eventX, eventY); + int historySize = event.getHistorySize(); + for (int i = 0; i < historySize; i++) + { + float historicalX = event.getHistoricalX(i); + float historicalY = event.getHistoricalY(i); + expandDirtyRect(historicalX, historicalY); + path.lineTo(historicalX, historicalY); + } + path.lineTo(eventX, eventY); + break; + + default: + debug("Ignored touch event: " + event.toString()); + return false; + } + + invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH), + (int) (dirtyRect.top - HALF_STROKE_WIDTH), + (int) (dirtyRect.right + HALF_STROKE_WIDTH), + (int) (dirtyRect.bottom + HALF_STROKE_WIDTH)); + + lastTouchX = eventX; + lastTouchY = eventY; + + return true; + } + + private void debug(String string){ + } + + private void expandDirtyRect(float historicalX, float historicalY) + { + if (historicalX < dirtyRect.left) + { + dirtyRect.left = historicalX; + } + else if (historicalX > dirtyRect.right) + { + dirtyRect.right = historicalX; + } + + if (historicalY < dirtyRect.top) + { + dirtyRect.top = historicalY; + } + else if (historicalY > dirtyRect.bottom) + { + dirtyRect.bottom = historicalY; + } + } + + private void resetDirtyRect(float eventX, float eventY) + { + dirtyRect.left = Math.min(lastTouchX, eventX); + dirtyRect.right = Math.max(lastTouchX, eventX); + dirtyRect.top = Math.min(lastTouchY, eventY); + dirtyRect.bottom = Math.max(lastTouchY, eventY); + } + } +} \ No newline at end of file diff -r c06669391cd2 -r c3780fcb8441 src/tz/signaturecapture/CaptureSignatureActivity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tz/signaturecapture/CaptureSignatureActivity.java Fri Jan 10 12:24:07 2014 +0100 @@ -0,0 +1,48 @@ +package tz.signaturecapture; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.Gravity; +import android.view.View; +import android.widget.Button; +import android.widget.Toast; + +public class CaptureSignatureActivity extends Activity { + + public static final int SIGNATURE_ACTIVITY = 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + Button getSignature = (Button) findViewById(R.id.signature); + getSignature.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + Intent intent = new Intent(CaptureSignatureActivity.this, CaptureSignature.class); + startActivityForResult(intent,SIGNATURE_ACTIVITY); + } + }); + } + + protected void onActivityResult(int requestCode, int resultCode, Intent data) + { + switch(requestCode) { + case SIGNATURE_ACTIVITY: + if (resultCode == RESULT_OK) { + + Bundle bundle = data.getExtras(); + String status = bundle.getString("status"); + if(status.equalsIgnoreCase("done")){ + Toast toast = Toast.makeText(this, "Signature capture successful!", Toast.LENGTH_SHORT); + toast.setGravity(Gravity.TOP, 105, 50); + toast.show(); + } + } + break; + } + + } + +} \ No newline at end of file