1

I am making an app that uses the camera and I would like the default camera open as soon as the app is opened. I currently start my image capture intent in the onCreate method of my main activity. This works perfectly fine sometimes, but other times the camera intent is launched 3 consecutive times.

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

        mImageView = (ImageView) findViewById(R.id.imageView1);
        mImageBitmap = null;

        Button picBtn = (Button) findViewById(R.id.pictureButton);
        setBtnListenerOrDisable(
                picBtn,
                mTakePicOnClickListener,
                MediaStore.ACTION_IMAGE_CAPTURE
        );

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
            mAlbumStorageDirFactory = new FroyoAlbumDirFactory();
        } else {
            mAlbumStorageDirFactory = new BaseAlbumDirFactory();
        }
        dispatchTakePictureIntent(ACTION_TAKE_PHOTO_B);
    }

private void dispatchTakePictureIntent(int actionCode) {

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File f;
        try {
            f = setUpPhotoFile();
            mCurrentPhotoPath = f.getAbsolutePath();
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
        } catch (IOException e) {
            e.printStackTrace();
            mCurrentPhotoPath = null;
        }

        startActivityForResult(takePictureIntent, actionCode);
    }

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            handleBigCameraPhoto();
        }
    }

private void handleBigCameraPhoto() {

        if (mCurrentPhotoPath != null) {
            setPic();
            galleryAddPic();
            lastPhotoPath = mCurrentPhotoPath;
            mCurrentPhotoPath = null;
        }

    }

 private void setPic() {

        /* There isn't enough memory to open up more than a couple camera photos */
        /* So pre-scale the target bitmap into which the file is decoded */

        /* Get the size of the ImageView */
        int targetW = mImageView.getWidth();
        int targetH = mImageView.getHeight();

        /* Get the size of the image */
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
        int photoW = bmOptions.outWidth;
        int photoH = bmOptions.outHeight;

        /* Figure out which way needs to be reduced less */
        int scaleFactor = 1;
        if ((targetW > 0) || (targetH > 0)) {
            scaleFactor = Math.min(photoW / targetW, photoH / targetH);
        }

        /* Set bitmap options to scale the image decode target */
        bmOptions.inJustDecodeBounds = false;
        bmOptions.inSampleSize = scaleFactor;
        bmOptions.inPurgeable = true;

        /* Decode the JPEG file into a Bitmap */
        Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);

        /* Associate the Bitmap to the ImageView */
        mImageView.setImageBitmap(bitmap);
        mImageView.setVisibility(View.VISIBLE);
    }
Anthony Porter
  • 152
  • 1
  • 9

3 Answers3

1

Look here:

Android: onCreate() getting called multiple times (and not by me)

One piece of guidance I can provide is to try and move that call to

public void onResume(){

}

You'll get the desired behavior of automatically going to the camera, but this might cut down on some of the extra calls, since it only occurs when the activity is actually being shown to the user (including returning from other applications etc..).

Community
  • 1
  • 1
Nathaniel D. Waggoner
  • 2,856
  • 2
  • 19
  • 41
1

I think Nathaniel is giving you good advice to move your camera intent launching into onResume.

However, you'll need to differentiate between an onResume that is your activity starting for the first time from one that is happening because of your activity resuming after the camera intent is finished. If you dont, you'll get the loop you see.

To do this, you can alter your onActivityResult() to set a member variable in your Activity called something like isResumingFromCaptureIntent. Set it to true in onActivityResult when the resultCode matches what you used to start the camera intent. Then, in your onResume, check isResumingFromCaptureIntent, if true you know you dont need to start the camera intent and can set is back to false and proceed with whatever else your activity needs to do.

mmeyer
  • 3,598
  • 1
  • 19
  • 22
  • Is that better than doing it onCreate and checking if onCreate has been called yet? – Anthony Porter Jul 10 '14 at 23:54
  • 1
    Yes, because onCreate is not guaranteed to be called when coming back from your capture activity. The OS may elect to keep your activity around when it launches the camera activity (or the user navigates to some other activity), providing it has enough free memory to keep your activity resident. onResume will always get called. – mmeyer Jul 11 '14 at 00:03
  • I will make the change thank you for the explanation! – Anthony Porter Jul 11 '14 at 15:07
0

In the onCreate method I added logic to check if onCreate had previously been called. I did this by checking if the bundle passed in was null or not

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

        mImageView = (ImageView) findViewById(R.id.imageView1);
        mImageBitmap = null;

        Button picBtn = (Button) findViewById(R.id.pictureButton);
        setBtnListenerOrDisable(
                picBtn,
                mTakePicOnClickListener,
                MediaStore.ACTION_IMAGE_CAPTURE
        );

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
            mAlbumStorageDirFactory = new FroyoAlbumDirFactory();
        } else {
            mAlbumStorageDirFactory = new BaseAlbumDirFactory();
        }

        if(savedInstanceState == null)
            dispatchTakePictureIntent(ACTION_TAKE_PHOTO_B);
    }
Anthony Porter
  • 152
  • 1
  • 9