0

I'm writing an app that I need to put an image view of which user has to load an image by click on it. After clicking I'm to give options for user to select whether he intents to load a stored image from the phone itself or take a new shot from it's camera.

This question might be redundant but almost none of the similar questions/issues revealed in here didn't reach what I'm trying to do.

P.s. I'm working on Android API15 with Eclipse 4.2 (JUNO) SDK installed.

Here is the snippet code of main activity which gives me an error:

 package test.imgbyte.conerter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import android.net.Uri;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.view.View;

public class FindImgPathActivity extends Activity 
{

      private Uri mImageCaptureUri;
      static final int CAMERA_PIC_REQUEST = 1337; 

      public void onCreate(Bundle savedInstanceState)
      {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.imgfilepath);

        Button camera = (Button) findViewById(R.id.btnLoad);
        camera.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View v) 
            {
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
                startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);               
            }               
        });

      }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAMERA_PIC_REQUEST) 
        {  
            Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
            ImageView image = (ImageView) findViewById(R.id.imgLoaded);  
            image.setImageBitmap(thumbnail);  

            String pathToImage = mImageCaptureUri.getPath();

            // pathToImage is a path you need. 

            // If image file is not in there, 
            //  you can save it yourself manually with this code:
            File file = new File(pathToImage);

            FileOutputStream fOut;
            try 
            {
                fOut = new FileOutputStream(file);
                thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, fOut); // You can choose any format you want
            } 
            catch (FileNotFoundException e) 
            {
                e.printStackTrace();
            }

        }  
    }    
}

Error I get is like this from LogCat:

11-05 19:23:11.777: E/AndroidRuntime(1206): FATAL EXCEPTION: main
11-05 19:23:11.777: E/AndroidRuntime(1206): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1337, result=-1, data=Intent { act=inline-data (has extras) }} to activity {test.imgbyte.conerter/test.imgbyte.conerter.FindImgPathActivity}: java.lang.NullPointerException
  • I think you can refer answer at here: [http://stackoverflow.com/questions/2507898/how-to-pick-an-image-from-gallery-sd-card-for-my-app-in-android?rq=1][1] [1]: http://stackoverflow.com/questions/2507898/how-to-pick-an-image-from-gallery-sd-card-for-my-app-in-android?rq=1 – D T May 14 '14 at 07:10

1 Answers1

4

Ah. This error. I'd spent ages deciphering what it meant, apparently the result has some null field that you're trying to access. In your case it's the mImageCaptureUri field that you've not really initialized with a file. The way to start a camera intent is to create a file, and pass it's Uri to the intent as the EXTRA_OUTPUT.

File tempFile = new File("blah.jpg");
...
cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
...

You can then use the file.getAbsolutePath() method to load the Bitmap.

Given we are on this point let me share with you a very important point I learnt last week about loading Bitmaps directly... Don't do it! It took me a week to understand why, and when I did I couldn't believe I didn't understand earlier, it's all a play on memory.

Use this code to load Bitmaps efficiently. (Once you have the file, just use file.getAbsolutePath() in BitmapFactory.decodeFile()):

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            if (width > height) {
                inSampleSize = Math.round((float)height / (float)reqHeight);
            } else {
                inSampleSize = Math.round((float)width / (float)reqWidth);
            }
        }
        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(path, options);
    }

Just pass your file.getAbsolutePath() as the first argument, along with the required width and height to the decodeSampledBitmapFromPath function to get an efficiently loaded Bitmap. This code was modified from it's version here on the Android docs.

Edit:

private Uri mImageCaptureUri; // This needs to be initialized.
      static final int CAMERA_PIC_REQUEST = 1337; 
private String filePath;

      public void onCreate(Bundle savedInstanceState)
      {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.imgfilepath);
// Just a temporary solution, you're supposed to load whichever directory you need here
        File mediaFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Temp1.jpg");
filePath = mediaFile.getABsolutePath();

        Button camera = (Button) findViewById(R.id.btnLoad);
        camera.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View v) 
            {
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile));
                startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);               
            }               
        });

      }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAMERA_PIC_REQUEST) 
        {  
            if(resultCode == RESULT_OK)
          {
int THUMBNAIL_SIZE = 64;
// Rest assured, if the result is OK, you're file is at that location
            Bitmap thumbnail = decodeSampledBitmapFromPath(filePath, THUMBNAIL_SIZE, THUMBNAIL_SIZE); // This assumes you've included the method I mentioned above for optimization
            ImageView image = (ImageView) findViewById(R.id.imgLoaded);  
            image.setImageBitmap(thumbnail);  
          }
    }    
}
varevarao
  • 2,186
  • 13
  • 26
  • Would you recommend an edited snippet of my code inserted with your suggestion into it? I'd be very thankful because atm as a beginner on Android platform gets painful for me to get used to solutions of issues im encountering on the way. – Alban Nurkollari Nov 05 '12 at 19:14
  • I've added the code inline. TO understand all that better please go through the docs, when I encountered this issue it was the 3 days I spent exhaustively on the Docs that bailed me out, and taught me a lot. Cheers. – varevarao Nov 05 '12 at 19:33