|
1 package tz.signaturecapture; |
|
2 |
|
3 import java.io.File; |
|
4 import java.io.FileOutputStream; |
|
5 import java.util.Calendar; |
|
6 |
|
7 import android.app.Activity; |
|
8 import android.content.Context; |
|
9 import android.content.ContextWrapper; |
|
10 import android.content.Intent; |
|
11 import android.graphics.Bitmap; |
|
12 import android.graphics.Canvas; |
|
13 import android.graphics.Color; |
|
14 import android.graphics.Paint; |
|
15 import android.graphics.Path; |
|
16 import android.graphics.RectF; |
|
17 import android.os.Bundle; |
|
18 import android.os.Environment; |
|
19 import android.provider.MediaStore.Images; |
|
20 import android.util.AttributeSet; |
|
21 import android.util.Log; |
|
22 import android.view.Gravity; |
|
23 import android.view.MotionEvent; |
|
24 import android.view.View; |
|
25 import android.view.View.OnClickListener; |
|
26 import android.view.ViewGroup.LayoutParams; |
|
27 import android.view.Window; |
|
28 import android.widget.Button; |
|
29 import android.widget.EditText; |
|
30 import android.widget.LinearLayout; |
|
31 import android.widget.Toast; |
|
32 |
|
33 public class CaptureSignature extends Activity { |
|
34 |
|
35 LinearLayout mContent; |
|
36 signature mSignature; |
|
37 Button mClear, mGetSign, mCancel; |
|
38 public static String tempDir; |
|
39 public int count = 1; |
|
40 public String current = null; |
|
41 private Bitmap mBitmap; |
|
42 View mView; |
|
43 File mypath; |
|
44 |
|
45 private String uniqueId; |
|
46 private EditText yourName; |
|
47 |
|
48 @Override |
|
49 public void onCreate(Bundle savedInstanceState) |
|
50 { |
|
51 super.onCreate(savedInstanceState); |
|
52 this.requestWindowFeature(Window.FEATURE_NO_TITLE); |
|
53 setContentView(R.layout.signature); |
|
54 |
|
55 tempDir = Environment.getExternalStorageDirectory() + "/" + getResources().getString(R.string.external_dir) + "/"; |
|
56 ContextWrapper cw = new ContextWrapper(getApplicationContext()); |
|
57 File directory = cw.getDir(getResources().getString(R.string.external_dir), Context.MODE_PRIVATE); |
|
58 |
|
59 prepareDirectory(); |
|
60 uniqueId = getTodaysDate() + "_" + getCurrentTime() + "_" + Math.random(); |
|
61 current = uniqueId + ".png"; |
|
62 mypath= new File(directory,current); |
|
63 |
|
64 |
|
65 mContent = (LinearLayout) findViewById(R.id.linearLayout); |
|
66 mSignature = new signature(this, null); |
|
67 mSignature.setBackgroundColor(Color.WHITE); |
|
68 mContent.addView(mSignature, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); |
|
69 mClear = (Button)findViewById(R.id.clear); |
|
70 mGetSign = (Button)findViewById(R.id.getsign); |
|
71 mGetSign.setEnabled(false); |
|
72 mCancel = (Button)findViewById(R.id.cancel); |
|
73 mView = mContent; |
|
74 |
|
75 yourName = (EditText) findViewById(R.id.yourName); |
|
76 |
|
77 mClear.setOnClickListener(new OnClickListener() |
|
78 { |
|
79 public void onClick(View v) |
|
80 { |
|
81 Log.v("log_tag", "Panel Cleared"); |
|
82 mSignature.clear(); |
|
83 mGetSign.setEnabled(false); |
|
84 } |
|
85 }); |
|
86 |
|
87 mGetSign.setOnClickListener(new OnClickListener() |
|
88 { |
|
89 public void onClick(View v) |
|
90 { |
|
91 Log.v("log_tag", "Panel Saved"); |
|
92 boolean error = captureSignature(); |
|
93 if(!error){ |
|
94 mView.setDrawingCacheEnabled(true); |
|
95 mSignature.save(mView); |
|
96 Bundle b = new Bundle(); |
|
97 b.putString("status", "done"); |
|
98 Intent intent = new Intent(); |
|
99 intent.putExtras(b); |
|
100 setResult(RESULT_OK,intent); |
|
101 finish(); |
|
102 } |
|
103 } |
|
104 }); |
|
105 |
|
106 mCancel.setOnClickListener(new OnClickListener() |
|
107 { |
|
108 public void onClick(View v) |
|
109 { |
|
110 Log.v("log_tag", "Panel Canceled"); |
|
111 Bundle b = new Bundle(); |
|
112 b.putString("status", "cancel"); |
|
113 Intent intent = new Intent(); |
|
114 intent.putExtras(b); |
|
115 setResult(RESULT_OK,intent); |
|
116 finish(); |
|
117 } |
|
118 }); |
|
119 |
|
120 } |
|
121 |
|
122 @Override |
|
123 protected void onDestroy() { |
|
124 Log.w("GetSignature", "onDestory"); |
|
125 super.onDestroy(); |
|
126 } |
|
127 |
|
128 private boolean captureSignature() { |
|
129 |
|
130 boolean error = false; |
|
131 String errorMessage = ""; |
|
132 |
|
133 |
|
134 if(yourName.getText().toString().equalsIgnoreCase("")){ |
|
135 errorMessage = errorMessage + "Please enter your Name\n"; |
|
136 error = true; |
|
137 } |
|
138 |
|
139 if(error){ |
|
140 Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT); |
|
141 toast.setGravity(Gravity.TOP, 105, 50); |
|
142 toast.show(); |
|
143 } |
|
144 |
|
145 return error; |
|
146 } |
|
147 |
|
148 private String getTodaysDate() { |
|
149 |
|
150 final Calendar c = Calendar.getInstance(); |
|
151 int todaysDate = (c.get(Calendar.YEAR) * 10000) + |
|
152 ((c.get(Calendar.MONTH) + 1) * 100) + |
|
153 (c.get(Calendar.DAY_OF_MONTH)); |
|
154 Log.w("DATE:",String.valueOf(todaysDate)); |
|
155 return(String.valueOf(todaysDate)); |
|
156 |
|
157 } |
|
158 |
|
159 private String getCurrentTime() { |
|
160 |
|
161 final Calendar c = Calendar.getInstance(); |
|
162 int currentTime = (c.get(Calendar.HOUR_OF_DAY) * 10000) + |
|
163 (c.get(Calendar.MINUTE) * 100) + |
|
164 (c.get(Calendar.SECOND)); |
|
165 Log.w("TIME:",String.valueOf(currentTime)); |
|
166 return(String.valueOf(currentTime)); |
|
167 |
|
168 } |
|
169 |
|
170 |
|
171 private boolean prepareDirectory() |
|
172 { |
|
173 try |
|
174 { |
|
175 if (makedirs()) |
|
176 { |
|
177 return true; |
|
178 } else { |
|
179 return false; |
|
180 } |
|
181 } catch (Exception e) |
|
182 { |
|
183 e.printStackTrace(); |
|
184 Toast.makeText(this, "Could not initiate File System.. Is Sdcard mounted properly?", 1000).show(); |
|
185 return false; |
|
186 } |
|
187 } |
|
188 |
|
189 private boolean makedirs() |
|
190 { |
|
191 File tempdir = new File(tempDir); |
|
192 if (!tempdir.exists()) |
|
193 tempdir.mkdirs(); |
|
194 |
|
195 if (tempdir.isDirectory()) |
|
196 { |
|
197 File[] files = tempdir.listFiles(); |
|
198 for (File file : files) |
|
199 { |
|
200 if (!file.delete()) |
|
201 { |
|
202 System.out.println("Failed to delete " + file); |
|
203 } |
|
204 } |
|
205 } |
|
206 return (tempdir.isDirectory()); |
|
207 } |
|
208 |
|
209 public class signature extends View |
|
210 { |
|
211 private static final float STROKE_WIDTH = 5f; |
|
212 private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2; |
|
213 private Paint paint = new Paint(); |
|
214 private Path path = new Path(); |
|
215 |
|
216 private float lastTouchX; |
|
217 private float lastTouchY; |
|
218 private final RectF dirtyRect = new RectF(); |
|
219 |
|
220 public signature(Context context, AttributeSet attrs) |
|
221 { |
|
222 super(context, attrs); |
|
223 paint.setAntiAlias(true); |
|
224 paint.setColor(Color.BLACK); |
|
225 paint.setStyle(Paint.Style.STROKE); |
|
226 paint.setStrokeJoin(Paint.Join.ROUND); |
|
227 paint.setStrokeWidth(STROKE_WIDTH); |
|
228 } |
|
229 |
|
230 public void save(View v) |
|
231 { |
|
232 Log.v("log_tag", "Width: " + v.getWidth()); |
|
233 Log.v("log_tag", "Height: " + v.getHeight()); |
|
234 if(mBitmap == null) |
|
235 { |
|
236 mBitmap = Bitmap.createBitmap (mContent.getWidth(), mContent.getHeight(), Bitmap.Config.RGB_565);; |
|
237 } |
|
238 Canvas canvas = new Canvas(mBitmap); |
|
239 try |
|
240 { |
|
241 FileOutputStream mFileOutStream = new FileOutputStream(mypath); |
|
242 |
|
243 v.draw(canvas); |
|
244 mBitmap.compress(Bitmap.CompressFormat.PNG, 90, mFileOutStream); |
|
245 mFileOutStream.flush(); |
|
246 mFileOutStream.close(); |
|
247 String url = Images.Media.insertImage(getContentResolver(), mBitmap, "title", null); |
|
248 Log.v("log_tag","url: " + url); |
|
249 //In case you want to delete the file |
|
250 //boolean deleted = mypath.delete(); |
|
251 //Log.v("log_tag","deleted: " + mypath.toString() + deleted); |
|
252 //If you want to convert the image to string use base64 converter |
|
253 |
|
254 } |
|
255 catch(Exception e) |
|
256 { |
|
257 Log.v("log_tag", e.toString()); |
|
258 } |
|
259 } |
|
260 |
|
261 public void clear() |
|
262 { |
|
263 path.reset(); |
|
264 invalidate(); |
|
265 } |
|
266 |
|
267 @Override |
|
268 protected void onDraw(Canvas canvas) |
|
269 { |
|
270 canvas.drawPath(path, paint); |
|
271 } |
|
272 |
|
273 @Override |
|
274 public boolean onTouchEvent(MotionEvent event) |
|
275 { |
|
276 float eventX = event.getX(); |
|
277 float eventY = event.getY(); |
|
278 mGetSign.setEnabled(true); |
|
279 |
|
280 switch (event.getAction()) |
|
281 { |
|
282 case MotionEvent.ACTION_DOWN: |
|
283 path.moveTo(eventX, eventY); |
|
284 lastTouchX = eventX; |
|
285 lastTouchY = eventY; |
|
286 return true; |
|
287 |
|
288 case MotionEvent.ACTION_MOVE: |
|
289 |
|
290 case MotionEvent.ACTION_UP: |
|
291 |
|
292 resetDirtyRect(eventX, eventY); |
|
293 int historySize = event.getHistorySize(); |
|
294 for (int i = 0; i < historySize; i++) |
|
295 { |
|
296 float historicalX = event.getHistoricalX(i); |
|
297 float historicalY = event.getHistoricalY(i); |
|
298 expandDirtyRect(historicalX, historicalY); |
|
299 path.lineTo(historicalX, historicalY); |
|
300 } |
|
301 path.lineTo(eventX, eventY); |
|
302 break; |
|
303 |
|
304 default: |
|
305 debug("Ignored touch event: " + event.toString()); |
|
306 return false; |
|
307 } |
|
308 |
|
309 invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH), |
|
310 (int) (dirtyRect.top - HALF_STROKE_WIDTH), |
|
311 (int) (dirtyRect.right + HALF_STROKE_WIDTH), |
|
312 (int) (dirtyRect.bottom + HALF_STROKE_WIDTH)); |
|
313 |
|
314 lastTouchX = eventX; |
|
315 lastTouchY = eventY; |
|
316 |
|
317 return true; |
|
318 } |
|
319 |
|
320 private void debug(String string){ |
|
321 } |
|
322 |
|
323 private void expandDirtyRect(float historicalX, float historicalY) |
|
324 { |
|
325 if (historicalX < dirtyRect.left) |
|
326 { |
|
327 dirtyRect.left = historicalX; |
|
328 } |
|
329 else if (historicalX > dirtyRect.right) |
|
330 { |
|
331 dirtyRect.right = historicalX; |
|
332 } |
|
333 |
|
334 if (historicalY < dirtyRect.top) |
|
335 { |
|
336 dirtyRect.top = historicalY; |
|
337 } |
|
338 else if (historicalY > dirtyRect.bottom) |
|
339 { |
|
340 dirtyRect.bottom = historicalY; |
|
341 } |
|
342 } |
|
343 |
|
344 private void resetDirtyRect(float eventX, float eventY) |
|
345 { |
|
346 dirtyRect.left = Math.min(lastTouchX, eventX); |
|
347 dirtyRect.right = Math.max(lastTouchX, eventX); |
|
348 dirtyRect.top = Math.min(lastTouchY, eventY); |
|
349 dirtyRect.bottom = Math.max(lastTouchY, eventY); |
|
350 } |
|
351 } |
|
352 } |