2012-01-26 22 views
47

Próbuję zaimplementować przechwytywanie podpisu przy użyciu narzędzia Rodos kierującego kartę Android. Udało mi się zdobyć płótno i napisać na nim. Ale nie mogę zapisać podpisu w wybranej lokalizacji. Numer signature_uri przyjmuje domyślną lokalizację jako db/db-files/Image-XXXXXX.png.Zapisz zdjęcie podpisu do pliku na Rodos na Androidzie

To był kod w próbce przykład:

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 

W konsoli mam:

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/ 

Teraz zamiast tego przechowywania bazy danych, chcę, aby zapisać go w żądanym Lokalizacja. Podziel się swoimi poglądami.

+0

Czy możesz pokazać nam ślad? pozostałe: przeczytaj pytanie. Zdobył już podpis, ale chce go uratować z Rodos. To jest prawdziwy problem, to nie jest "Jak przechwycić podpis na Androidzie". – Bourbon

Odpowiedz

1

czy wyrejestrowany tej strony internetowej: http://docs.rhomobile.com/rhodes/device-caps#file-system-access? Wydaje mi się, że potrzebujesz zapisać obraz do bazy danych i użyć metody Rho :: RhoApplication :: get_blob_path (image.image_uri) do otwarcia pliku. Wtedy powinieneś być w stanie użyć interfejsu API systemu plików, aby utworzyć nowy plik i zapisać do niego zawartość obrazu, gdziekolwiek chcesz.

+0

To było całkiem blisko tego, co zrobiliśmy w naszym projekcie. Zasadniczo signature_uri zwraca lokalizację zapisanego obrazu (do którego po prostu nie mogłem uzyskać dostępu). Przesłaliśmy tę lokalizację jako źródło obrazu do usługi internetowej i utworzyliśmy rekord w DB. Zweryfikowano, że obraz jest zapisywany przez rozmiar przechowywanego pliku. Liczba uderzeń proporcjonalna do wielkości obrazu. – Vikas

0

Kod mieszek może przydatna

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

}

+0

Nie szukałem klasy aktywności/kumpla fragmentu kodu Android. I tak dziękuję. – Vikas

1

Po prostu spróbuj przekazać lokalizację karty SD w formie podpisu. Należy pamiętać o wyrażeniu zgody na zapisywanie do odczytu dla karty SD w manifeście.

Else

skopiować plik podpis pragnąć lokalizację z opakowania wewnętrznego, lecz jest to duplicacy pracy.

+0

Dzięki za odpowiedź Manish i przeprosiny za spóźnioną odpowiedź. Próbowałem, ale bez powodzenia. – Vikas