I need to know how I capture a person's signature on an Android screen to put in a document (practically a digital signature).
I need to know how I capture a person's signature on an Android screen to put in a document (practically a digital signature).
Your question is not very well defined, but I'll try to help anyway.
There's nothing ready on "official" Android to do this, you need to assemble the pieces, or use a not-well-known third-party library. The idea is to create a canvas (screen space) where the user will draw freely with the finger or stylus. Then you will need to capture the formed image and then do whatever you want with it.
Recommended Option 1: Android Signature Pad
A great solution is the android-signaturepad library that can be found here: link
It is based on Square's signup code and has a fantastic article showing the concept behind the idea: link
Recommended Option 2: SignatureView
Another great option I found was the SignatureView library that can be found at:
It's an open-source and complete solution for what you want. The original answer to this solution can be seen here: link
There is another article in English that can be useful if you do not use the above option because it implements exactly the junction of the parts as I said at the beginning (although it only records the image generated in a file, it is trivial to modify it to do what you want):
There is already a response in Stack Overflow in English with an interesting implementation, which provides a View that you can use to capture signatures. The code is as follows:
public class CaptureSignatureView extends View {
private Bitmap _Bitmap;
private Canvas _Canvas;
private Path _Path;
private Paint _BitmapPaint;
private Paint _paint;
private float _mX;
private float _mY;
private float TouchTolerance = 4;
private float LineThickness = 4;
public CaptureSignatureView(Context context, AttributeSet attr) {
super(context, attr);
_Path = new Path();
_BitmapPaint = new Paint(Paint.DITHER_FLAG);
_paint = new Paint();
_paint.setAntiAlias(true);
_paint.setDither(true);
_paint.setColor(Color.argb(255, 0, 0, 0));
_paint.setStyle(Paint.Style.STROKE);
_paint.setStrokeJoin(Paint.Join.ROUND);
_paint.setStrokeCap(Paint.Cap.ROUND);
_paint.setStrokeWidth(LineThickness);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
_Bitmap = Bitmap.createBitmap(w, (h > 0 ? h : ((View) this.getParent()).getHeight()), Bitmap.Config.ARGB_8888);
_Canvas = new Canvas(_Bitmap);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(_Bitmap, 0, 0, _BitmapPaint);
canvas.drawPath(_Path, _paint);
}
private void TouchStart(float x, float y) {
_Path.reset();
_Path.moveTo(x, y);
_mX = x;
_mY = y;
}
private void TouchMove(float x, float y) {
float dx = Math.abs(x - _mX);
float dy = Math.abs(y - _mY);
if (dx >= TouchTolerance || dy >= TouchTolerance) {
_Path.quadTo(_mX, _mY, (x + _mX) / 2, (y + _mY) / 2);
_mX = x;
_mY = y;
}
}
private void TouchUp() {
if (!_Path.isEmpty()) {
_Path.lineTo(_mX, _mY);
_Canvas.drawPath(_Path, _paint);
} else {
_Canvas.drawPoint(_mX, _mY, _paint);
}
_Path.reset();
}
@Override
public boolean onTouchEvent(MotionEvent e) {
super.onTouchEvent(e);
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
TouchStart(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
TouchMove(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
TouchUp();
invalidate();
break;
}
return true;
}
public void ClearCanvas() {
_Canvas.drawColor(Color.WHITE);
invalidate();
}
public byte[] getBytes() {
Bitmap b = getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
public Bitmap getBitmap() {
View v = (View) this.getParent();
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
v.draw(c);
return b;
}
}
To add this View to a LinearLayout you can do:
LinearLayout mContent = (LinearLayout) findViewById(R.id.linearLayout);
CaptureSignatureView mSig = new CaptureSignatureView(this, null);
mContent.addView(mSig, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
To get an array of bytes with the signature data, or get a bitmap directly from it, use the following code:
byte[] signature = mSig.getBytes();
Bitmap signature = mSig.getBitmap();
You can then do whatever you want with these subscription images. Here is the less defined part of your question: what kind of document will you record this signature on? Is it enough to send it separately? Depending on your answer it may be very difficult to implement this part.
Here's an example:
DrawView.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class DrawView extends View {
Paint paint = new Paint();
ArrayList<Line> lines = new ArrayList<Line>();
Line currentLine;
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(8f);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
}
@Override
protected void onDraw(Canvas canvas) {
print(canvas);
}
/**
* Desenha no canvas as linhas
* @param canvas
*/
private void print(final Canvas canvas){
// Deesenha todas as linha já escritas
for(final Line l : lines){
int max = l.pointers.size()-1;
for(int pt =0; pt < max; pt++ ) {
Pointer pA = l.pointers.get(pt);
Pointer pB = l.pointers.get(pt+1);
canvas.drawLine(pA._x, pA._y, pB._x, pB._y, paint);
}
}
// Desenha a linha corrente!
if(currentLine != null){
int max = currentLine.pointers.size()-1;
for(int pt =0; pt < max; pt++ ) {
Pointer pA = currentLine.pointers.get(pt);
Pointer pB = currentLine.pointers.get(pt+1);
canvas.drawLine(pA._x, pA._y, pB._x, pB._y, paint);
}
}
}
public Bitmap generateBitmap() {
Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
print(c);
return b;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Inicia uma nova linha
if(event.getAction() == MotionEvent.ACTION_DOWN){
currentLine = new Line();
currentLine.addPointer(new Pointer(event.getX(), event.getY()));
invalidate();
return true;
}else if(event.getAction() == MotionEvent.ACTION_MOVE) { // adiciona os pontos a linha
currentLine.addPointer(new Pointer(event.getX(), event.getY()));
invalidate();
return true;
}else if(event.getAction() == MotionEvent.ACTION_UP ){ // finaliza a linha
lines.add(currentLine);
currentLine = null;
invalidate();
return true;
}else{
return false;
}
}
/**
* Representa um ponto
*/
class Pointer{
float _x, _y;
public Pointer(float _x, float _y){
this._x = _x;
this._y = _y;
}
}
/**
* Representa uma linha (formado por uma lista de pontos)
*/
class Line {
List<Pointer> pointers = new ArrayList<>();
public void addPointer(final Pointer p){
pointers.add(p);
}
}
}
XML:
<seu.pacote.DrawView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/assinatura" />
Activity :
DrawView assinatura = DrawView.class.cast(findViewById(R.id.assinatura));
final Bitmap assinaturaBitmap = assinatura.generateBitmap();