Problem with saved image and ACTION_SEND - Image deleting!

All your problems with Audio, Video and Images.

Problem with saved image and ACTION_SEND - Image deleting!

Postby spengilley » Fri Feb 25, 2011 4:47 pm

Hi all,

I have a strange problem in my android app. I have an activity which shows an image. The image is saved on the SD card. The user can choose share from the context menu which is coded with the standard ACTION_SEND code. Please see below
Code: Select all
public void shareImage(){
      Intent emailShare = new Intent(android.content.Intent.ACTION_SEND);
      emailShare.setType("image/jpeg");
      emailShare.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
      emailShare.putExtra(Intent.EXTRA_STREAM,uriId);
      startActivity(Intent.createChooser(emailShare,"Send picture using:"));
   }


Where uriId is the uri of the image.

This works and the image can be sent to facebook or whatever. But if I then exit my app, rotate the screen the image is missing. I get a file io error in the log when i try and retrieve the image. I have used Astro to search for the image but it is nowhere to be found!

I will post the entire class below. If anyone has any ideas I would be very appreciative.

Stephen
Code: Select all
package com.pengilleys.fishingsnapz;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.FloatMath;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.TextView;

public class ImagePreview extends Activity implements OnTouchListener{
   protected Context mContext;
   static final String TAG = "ImagePreview";
   static final int SHARE_ID = 0;
   static final int EDIT_ID = 1;
   static final int PROGRESS_DIALOG = 0;
   ProgressDialog progressDialog;
   private Bundle extras;
   protected static Bitmap bm;
   protected DBAdapter db = new DBAdapter(ImagePreview.this);
   Long id;
   private FacebookManager fb;
   private Uri uriId;

      
   //Touch gesture related variables
   Matrix matrix = new Matrix();
   Matrix savedMatrix = new Matrix();
   
   // Remember some things for zooming
   PointF start = new PointF();
   PointF mid = new PointF();
   
   float oldDist = 0;
   
   // We can be in one of these 3 states
   static final int NONE = 0;
   static final int DRAG = 1;
   static final int ZOOM = 2;
   int mode = NONE;
   
   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image_view);
        mContext = this;
           
       
        try{
           extras = getIntent().getExtras();
           id = (Long) extras.get(DBAdapter.KEY_ROWID);    
           Log.d(TAG,"id="+id);
                                  
           ImageView imageV = (ImageView)findViewById(R.id.image_preview);
           imageV.setOnTouchListener(this);
         
           //get image
           bm = getImage(id);
           imageV.setImageBitmap(bm);
           imageV.setImageMatrix(matrix);
                      
            //get snap details for text overlay
           ArrayList<String> details = new ArrayList<String>();
           details = getSnapDetails(id);
          
           prepareSnapDetails(details);                 
           
           
           
        }catch(Exception e){
           Log.e(TAG,e.toString());
        }finally{
       
        }
       
   }
   
   private ArrayList<String> getSnapDetails(long id){
      ArrayList<String> fishDetails = new ArrayList<String>();
      Cursor cursor;
            
      //open the database and grab the snap details
      db.open();
      cursor = db.fetchNote(id);
      db.close();
      
      //loop through cursor results and put into our arraylist<string>
      try{
         startManagingCursor(cursor);
         cursor.moveToFirst();
         //only one row but multiple columns, manually assign columns
         String value = cursor.getString(cursor.getColumnIndexOrThrow("date"));
         value = checkValue(value);
         fishDetails.add(value);
         value = cursor.getString(cursor.getColumnIndexOrThrow("type"));
         value = checkValue(value);
         fishDetails.add(value);
         value = cursor.getString(cursor.getColumnIndexOrThrow("weight"));
         value = checkValue(value);
         fishDetails.add(value);
         value = cursor.getString(cursor.getColumnIndexOrThrow("place"));
         value = checkValue(value);
         fishDetails.add(value);
         
      
      }catch(Exception e){
         Log.e(TAG,e.toString());
      }
      db.close();
      return fishDetails;
   }
      
      private String checkValue(String value){
         if(value==""){value="-";};
         return value;
      }

   private boolean prepareSnapDetails(ArrayList<String> details){
      TextView tx = (TextView)findViewById(R.id.details_overlay);
      tx.setText("");
      String detail="";
      String[] labels = new String[]{"Date: ","Type: ","Weight: ","Place: "};
      try{      
         for(int i=0;i<4;i++){
            //add text details to textview
            detail = labels[i] + details.get(i) + '\n';
            Log.d(TAG,detail);
            CharSequence ch = detail.subSequence(0,detail.length());
            tx.append(ch);
         }
      }catch(Exception e){
         Log.e(TAG,e.toString());
         
      }
      return true;
   }
   
   private Bitmap getImage(Long id){
      try{
         db.open();
         Cursor c = db.fetchUri(id);
         uriId = Uri.parse(c.getString(c.getColumnIndexOrThrow(DBAdapter.KEY_URI)));
   
         ContentResolver cr = getContentResolver();
      
         Bitmap bitmap = MediaStore.Images.Media.getBitmap(cr,uriId);
         
         Display display = getWindowManager().getDefaultDisplay();
           int width = display.getWidth();
           int height = display.getHeight();
           
           if(bitmap.getWidth() > width || bitmap.getHeight() > height){
              float heightRatio = (float) height / bitmap.getHeight();
              float widthRatio = (float) width / bitmap.getWidth();
              Log.d(TAG,"height="+heightRatio + " width=" + widthRatio);
              matrix.setScale(widthRatio, heightRatio);
           }else{
              matrix.setTranslate(1f,1f);
              Log.d(TAG,"bitmap.getWidth="+bitmap.getWidth() + " vs width="+width);
              Log.d(TAG,"bitmap.getHeight="+bitmap.getHeight() + " vs height="+height);
           }
   
         db.close();
         return bitmap;
   
      } catch (FileNotFoundException e) {
         Log.e("GETIMAGE",e.toString());
         return null;
      } catch (IOException e) {
         Log.e("GETIMAGE",e.toString());
         return null;
      }catch(Exception e){
         Log.e("GETIMAGE",e.toString());
         return null;
      }
   }
   
   public void shareImage(){
      Intent emailShare = new Intent(android.content.Intent.ACTION_SEND);
      emailShare.setType("image/jpeg");
      emailShare.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
      emailShare.putExtra(Intent.EXTRA_STREAM,uriId);
      startActivity(Intent.createChooser(emailShare,"Send picture using:"));
   }
   
   @Override
   public boolean onTouch(View v, MotionEvent event) {
      ImageView view = (ImageView) v;
      final float MIN_ZOOM = 0.25f;
      final float MAX_ZOOM = 4;
      float height = view.getDrawable().getIntrinsicHeight();
      float width = view.getDrawable().getIntrinsicWidth();
      float[] matrixValues = new float[9];
      RectF viewRect = new RectF(0, 0, view.getWidth(), view.getHeight());
      
      dumpEvent(event);
      
      
            
      switch(event.getAction() & MotionEvent.ACTION_MASK){
      case MotionEvent.ACTION_DOWN:
         savedMatrix.set(matrix);
         start.set(event.getX(), event.getY());
         Log.d(TAG,"mode=DRAG");
         mode=DRAG;
         break;
      case MotionEvent.ACTION_UP:
      case MotionEvent.ACTION_POINTER_DOWN:
         oldDist=spacing(event);
         Log.d(TAG, "oldDist=" + oldDist);
         if(oldDist>10f){
            savedMatrix.set(matrix);
            midPoint(mid,event);
            mode=ZOOM;
            Log.d(TAG,"mode=ZOOM");
         }
         
         break;
         
      case MotionEvent.ACTION_MOVE:
         
         if(mode==DRAG){
            Log.d(TAG,"mode=MOVE");
            matrix.set(savedMatrix);
            // limit pan
            matrix.getValues(matrixValues);
            float currentY = matrixValues[Matrix.MTRANS_Y];
            float currentX = matrixValues[Matrix.MTRANS_X];
            float currentScale = matrixValues[Matrix.MSCALE_X];
            float currentHeight = height * currentScale;
            float currentWidth = width * currentScale;
            float dx = event.getX() - start.x;
            float dy = event.getY() - start.y;
            float newX = currentX+dx;
            float newY = currentY+dy;   

            RectF drawingRect = new RectF(newX, newY, newX+currentWidth, newY+currentHeight);
            float diffUp = Math.min(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
            float diffDown = Math.max(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
            float diffLeft = Math.min(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
            float diffRight = Math.max(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
            if(diffUp > 0 ){
            dy +=diffUp;   
            }
            if(diffDown < 0){
            dy +=diffDown;
            }   
            if( diffLeft> 0){   
            dx += diffLeft;
            }
            if(diffRight < 0){
            dx += diffRight;
            }
            matrix.postTranslate(dx, dy);
         }else if(mode==ZOOM){
            float newDist= spacing(event);
            
            if(newDist>10f){
               matrix.set(savedMatrix);
               float scale = newDist / oldDist;
               Log.d(TAG,"Scale="+scale);
               matrix.getValues(matrixValues);
               float currentScale = matrixValues[Matrix.MSCALE_X];
               Log.d(TAG,"currentScale="+currentScale);
               // limit zoom
               if (scale * currentScale > MAX_ZOOM) {
               scale = MAX_ZOOM / currentScale;
               } else if (scale * currentScale < MIN_ZOOM) {
               scale = MIN_ZOOM / currentScale;
               }
               matrix.postScale(scale, scale, mid.x, mid.y);
            }
         }
         break;
      }
         //perform the transformation
         view.setImageMatrix(matrix);
      
      return true;
   }
   
   private static float spacing(MotionEvent event){
      float x = event.getX(0) - event.getX(1);
      float y = event.getY(0) - event.getY(1);
      return FloatMath.sqrt(x * x + y * y);
   }
   
   private static void midPoint(PointF point, MotionEvent event){
      float x = event.getX(0) + event.getX(1);
      float y = event.getY(0) + event.getY(1);
      point.set(x / 2, y / 2);
   }
   
   /** Show an event in the logcat view for debugging **/
   private void dumpEvent(MotionEvent event){
      String names[] = {"DOWN","UP","MOVE","CANCEL","OUTSIDE","POINTER_DOWN","POINTER_UP","7?","8?","9?"};
      StringBuilder sb = new StringBuilder();
      int action = event.getAction();
      int actionCode = action & MotionEvent.ACTION_MASK;
      sb.append("event ACTION_").append(names[actionCode]);
      if(actionCode==MotionEvent.ACTION_POINTER_DOWN
            || actionCode==MotionEvent.ACTION_POINTER_UP){
         sb.append("pid ").append(
         action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
         sb.append(")");
      };
      sb.append(" [");
      for(int i=0;i < event.getPointerCount();i++){
         sb.append("#").append(i);
         sb.append("(pid ").append(event.getPointerId(i));
         sb.append(")=").append((int) event.getX(i));
         sb.append(",").append((int) event.getY(i));
         if(i+1 < event.getPointerCount())
            sb.append(";");
      }
      sb.append("]");
      Log.d("DUMP", sb.toString());
   }
   
   
    @Override
   public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, SHARE_ID, 0, R.string.share_id);
        menu.add(0,EDIT_ID,0,R.string.edit_details);
        return true;
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch(item.getItemId()) {
            case SHARE_ID:
               try{
                  shareImage();
                  
                    }catch(Exception e){
                       Log.e(TAG,e.toString());
                    }
                return true;
           
            case EDIT_ID:
               try{
                  Intent intent = new Intent(mContext,SnapDetails.class);
                  intent.putExtra(DBAdapter.KEY_ROWID,id);
                  startActivityForResult(intent,FishingSnapz.SNAP_EDIT);
                  
               }catch(Exception e){
                  Log.e(TAG,e.toString());
               }
               
        }

        return super.onMenuItemSelected(featureId, item);
    }
   
    @Override
   protected void onResume(){
       super.onResume();
       
    }
   
   @Override
   protected void onActivityResult (int requestCode, int resultCode, Intent data){
      super.onActivityResult(requestCode, resultCode, data);
      
      //Required by facebook single sign on - check that we are returning to activity from FB
      if(data!=null){
         fb.authorizeCallback(requestCode, resultCode, data);
      }else{
         extras = getIntent().getExtras();
           id = (Long) extras.get(DBAdapter.KEY_ROWID);
           
           //get snap details for text overlay
           ArrayList<String> details = new ArrayList<String>();
           details = getSnapDetails(id);
          
           prepareSnapDetails(details);     
           
      }
   }

}
spengilley
Junior Developer
Junior Developer
 
Posts: 18
Joined: Tue Sep 07, 2010 9:14 pm

Top

Return to Multimedia Problems

Who is online

Users browsing this forum: Google [Bot] and 18 guests