ユーザーが署名できる Android デジタル署名アプリを開発しています。このファイルを image.i として保存する必要があります。描画に SurfaceView を使用しています。DigitalSignatureActivity には、Save、Clear の 2 つのボタンがあります。1.Save ボタンでファイルを画像として保存します。 2.Clear ボタンで表面をクリアします。しかし、私は表面をクリアすることができません。まだ前の記号が保持され、canvas.drawColor(Color.BLACK); 効果はなく、ファイルを保存できますが、署名が完全に保存されていません(一部のコンテンツが欠落しています)助けてください。私のコードは: DigitalSignatureActivity.java
package com.pop.digitalsign;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.os.Environment;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
public class DigitalSignatureActivity extends Activity implements
View.OnTouchListener {
private DrawingSurface drawingSurface;
private DrawingPath currentDrawingPath;
private Paint currentPaint;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setCurrentPaint();
drawingSurface = (DrawingSurface) findViewById(R.id.drawingSurface);
drawingSurface.setOnTouchListener(this);
}
private void setCurrentPaint() {
currentPaint = new Paint();
currentPaint.setDither(true);
currentPaint.setColor(Color.WHITE);
currentPaint.setStyle(Paint.Style.STROKE);
currentPaint.setStrokeJoin(Paint.Join.ROUND);
currentPaint.setStrokeCap(Paint.Cap.ROUND);
currentPaint.setStrokeWidth(2);
}
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
drawingSurface.setBackgroundColor(0);
currentDrawingPath = new DrawingPath();
currentDrawingPath.paint = currentPaint;
currentDrawingPath.path = new Path();
currentDrawingPath.path.moveTo(motionEvent.getX(),
motionEvent.getY());
currentDrawingPath.path.lineTo(motionEvent.getX(),
motionEvent.getY());
} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
currentDrawingPath.path.lineTo(motionEvent.getX(),motionEvent.getY());
drawingSurface.addDrawingPath(currentDrawingPath);
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
currentDrawingPath.path.lineTo(motionEvent.getX(),motionEvent.getY());
}
return true;
}
//To save file as Image
public void saveDrawing(View v) throws IOException {
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MySignatures");
Bitmap nBitmap = drawingSurface.getBitmap();
try {
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile = new File(mediaStorageDir.getPath()
+ File.separator + "SIGN_" + timeStamp + ".png");
FileOutputStream out = new FileOutputStream(mediaFile);
nBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
Toast.makeText(this, "Signature saved to " + mediaFile,
Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Not saved",
Toast.LENGTH_SHORT).show();
}
}
//To clear Surface
public void clearScreen(View v) {
//drawingSurface.setBackgroundColor(Color.BLACK);
drawingSurface.clear();
}
}
DrawingSurface.java
package com.pop.digitalsign;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {
private Boolean _run;
protected DrawThread thread;
private Bitmap mBitmap;
Canvas canvas;
private CommandManager commandManager;
public DrawingSurface(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
commandManager = new CommandManager();
thread = new DrawThread(getHolder());
}
class DrawThread extends Thread{
public SurfaceHolder mSurfaceHolder;
public DrawThread(SurfaceHolder surfaceHolder){
mSurfaceHolder = surfaceHolder;
}
public DrawThread() {
// TODO Auto-generated constructor stub
}
public void setRunning(boolean run) {
_run = run;
}
@Override
public void run() {
canvas = null;
while (_run){
try{
canvas = mSurfaceHolder.lockCanvas(null);
//canvas.drawColor(Color.WHITE);
if(mBitmap == null){
mBitmap = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);;
}
final Canvas c = new Canvas (mBitmap);
c.drawColor(0, PorterDuff.Mode.CLEAR);
commandManager.executeAll(c);
canvas.drawBitmap (mBitmap, 0, 0,null);
} finally {
if(canvas!=null){
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
public void addDrawingPath (DrawingPath drawingPath){
commandManager.addCommand(drawingPath);
}
public void clear(){
//Here i want to clear surface
canvas.drawColor(Color.BLACK);//it has no effect
}
public boolean hasMoreUndo(){
return commandManager.hasMoreUndo();
}
public Bitmap getBitmap(){
return mBitmap;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mBitmap = Bitmap.createBitmap (width, height, Bitmap.Config.ARGB_8888);;
}
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
CommandManager.java
package com.pop.digitalsign;
import android.graphics.Canvas;
import java.util.Iterator;
import java.util.List;
import java.util.Collections;
import java.util.ArrayList;
public class CommandManager {
private List<DrawingPath> currentStack;
public CommandManager(){
currentStack = Collections.synchronizedList(new ArrayList<DrawingPath>());
}
public void addCommand(DrawingPath command){
currentStack.add(command);
}
public void undo (){
final int length = currentStackLength();
if ( length > 0) {
final DrawingPath undoCommand = currentStack.get( length - 1 );
currentStack.remove( length - 1 );
undoCommand.undo();
}
}
public int currentStackLength(){
final int length = currentStack.toArray().length;
return length;
}
public void executeAll( Canvas canvas){
if( currentStack != null ){
synchronized( currentStack ) {
final Iterator<?> i = currentStack.iterator();
while ( i.hasNext() ){
final DrawingPath drawingPath = (DrawingPath) i.next();
drawingPath.draw( canvas );
}
}
}
}
public boolean hasMoreUndo(){
return currentStack.toArray().length > 0;
}
}
DrawingPath.java
package com.pop.digitalsign;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
public class DrawingPath {
public Path path;
public Paint paint;
public void draw(Canvas canvas) {
canvas.drawPath( path, paint );
}
public void undo() {
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@android:color/white" >
<com.pop.digitalsign.DrawingSurface
android:id="@+id/drawingSurface"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center" >
<Button
android:id="@+id/saveBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="saveDrawing"
android:text="@string/save" />
<Button
android:id="@+id/clearBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="clearScreen"
android:text="@string/clear" />
</LinearLayout>
</RelativeLayout>