将签名的图片保存在Android上的Rhodes文件中。

时间:2021-07-26 16:17:22

I am trying to implement signature capture using Rhodes targeting an Android tab. I have managed to get the canvas and scribble on it. But am unable to save the signature at a desired location. The signature_uri takes the default location as db/db-files/Image-XXXXXX.png.

我正在尝试使用Rhodes定位Android选项卡实现签名捕获。我设法弄到画布并在上面乱涂乱画。但我无法将签名保存在所需的位置。signature_uri将默认位置设置为db/db /db- db-files/ image - xxxxxxxx .png。

This was the code in the sample example:

这是示例示例中的代码:

def signature_callback
if @params['status'] == 'ok'
  #create signature record in the DB
  signature = SignatureUtil.new({'signature_uri'=>@params['signature_uri']})
  signature.save
  puts "new Signature object: " + signature.inspect
end

In the console I got:

在控制台我得到:

APP| RHO serve: /app/Settings/signature_callback
I/APP     (  801): I 01/26/2012 11:36:20:236 0000032e                  APP| Params: {"status"=>"ok", "signature_uri"=>"db/db-files/Image_20120126113618375.png", "rho_callback"=>"1"}
I/APP     (  801): I 01/26/2012 11:36:20:238 0000032e                  APP| *******************ok****************
I/APP     (  801): I 01/26/2012 11:36:20:238 0000032e                  APP| %%%%%%%%%%%%%%%%%db/db-files/Image_20120126113618375.png%%%%%%%%%%%
I/APP     (  801): I 01/26/2012 11:36:20:239 0000032e                  APP| App error: can't convert Symbol into Integer
I/APP     (  801):  lib/rhom/rhom_object_factory.rb:67:in `[]'
I/APP     (  801): lib/rhom/rhom_object_factory.rb:67:in `initialize'
I/APP     (  801): apps/app/Settings/controller.rb:34:in `new'
I/APP     (  801): apps/app/Settings/controller.rb:34:in `signature_callback'
I/APP     (  801): lib/rho/rhocontroller.rb:91:in `serve'
I/APP     (  801): lib/rho/rhoapplication.rb:209:in `serve'
I/APP     (  801): lib/rho/rho.rb:822:in `serve'
I/APP     (  801): E 01/26/2012 11:36:20:248 00000321                  Net| Request failed. HTTP Code: 500 returned. HTTP Response:         <html>
I/APP     (  801):             <head>
I/APP     (  801):                 <meta name="viewport" content="width=320"/>
I/APP     (  801):             </head>
I/APP     (  801):             <body>
I/APP     (  801):                 <h2>Server Error</h2>
I/APP     (  801):                 <p>
I/APP     (  801): Error: can't convert Symbol into Integer<br/>Trace: <br/

Now instead of this database storage, I want to save it in a desired location. Please share your views.

现在,我想将它保存在一个需要的位置,而不是这个数据库存储。请谈谈你的看法。

3 个解决方案

#1


1  

have you checked out this page: http://docs.rhomobile.com/rhodes/device-caps#file-system-access ? It looks to me like you need to save the image to the DB and use the Rho::RhoApplication::get_blob_path(image.image_uri) method to open the file. Then you should be able to use the file system API to create a new file and write the contents of the image to it wherever you choose.

您查看过这个页面:http://docs.rhomobile.com/rhodes/device-caps#file-system-access吗?在我看来,您需要将图像保存到DB并使用Rho:::RhoApplication:::get_blob_path(image.image_uri)方法打开文件。然后,您应该能够使用文件系统API来创建一个新文件,并将图像的内容写入到任意位置。

#2


1  

Just try to pass sd card location in signature uri. Please note to give permission of read write for sd card in manifest.

尝试在签名uri中传递sd卡位置。请注意在舱单内给sd卡的读写权限。

Else

其他的

Copy the signature file to desire location from internal package but this is duplicacy of work.

将签名文件从内部包复制到希望的位置,但这是工作的副本。

#3


0  

The bellow code may useful to you

下面的代码可能对您有用

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

}

}

#1


1  

have you checked out this page: http://docs.rhomobile.com/rhodes/device-caps#file-system-access ? It looks to me like you need to save the image to the DB and use the Rho::RhoApplication::get_blob_path(image.image_uri) method to open the file. Then you should be able to use the file system API to create a new file and write the contents of the image to it wherever you choose.

您查看过这个页面:http://docs.rhomobile.com/rhodes/device-caps#file-system-access吗?在我看来,您需要将图像保存到DB并使用Rho:::RhoApplication:::get_blob_path(image.image_uri)方法打开文件。然后,您应该能够使用文件系统API来创建一个新文件,并将图像的内容写入到任意位置。

#2


1  

Just try to pass sd card location in signature uri. Please note to give permission of read write for sd card in manifest.

尝试在签名uri中传递sd卡位置。请注意在舱单内给sd卡的读写权限。

Else

其他的

Copy the signature file to desire location from internal package but this is duplicacy of work.

将签名文件从内部包复制到希望的位置,但这是工作的副本。

#3


0  

The bellow code may useful to you

下面的代码可能对您有用

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

}

}