user2900761
user2900761

Reputation: 121

How to keep images private to the app and not viewable in the gallery?

I am making an app to click pics and save that images in app folder.I want my images to be private to application only and not viewable in gallery. But with the code I have written my images are viewable in gallery. Follow my code below

MainActicity.java package com.mycamera;

import android.net.Uri;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.widget.Button;
import android.widget.ImageView; 
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
 import java.util.Locale;
 import android.content.Intent;
 import android.content.pm.PackageManager;
     import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;

 import android.os.Environment;
 import android.provider.MediaStore;
  import android.util.Log;
 import android.widget.Toast;


public class MainActivity extends ActionBarActivity {

 // Activity request codes
  private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;

  public static final int MEDIA_TYPE_IMAGE = 1;

    // directory name to store captured images and videos
   private static final String IMAGE_DIRECTORY_NAME = "Car Camera";

   private Uri fileUri; // file url to store image/video

    private ImageView imgPreview;

    private Button btnCapturePicture;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    imgPreview = (ImageView) findViewById(R.id.imgPreview);

    btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);

    /**
     * Capture image button click event
     * */
    btnCapturePicture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // capture picture
            captureImage();
        }
    });


 // Checking camera availability
    if (!isDeviceSupportCamera()) {
        Toast.makeText(getApplicationContext(),
                "Sorry! Your device doesn't support camera",
                Toast.LENGTH_LONG).show();
        // will close the app if the device does't have camera
        finish();
    }
}
/**
 * Checking device has camera hardware or not
 * */
private boolean isDeviceSupportCamera() {
    if (getApplicationContext().getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA)) {
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}

        private void captureImage() {
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

            fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

            intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

       // start the image capture Intent
            startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
        }
            /**
             * Here we store the file url as it will be null after returning from camera
             * app
             */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        // save file url in bundle as it will be null on scren orientation
        // changes
        outState.putParcelable("file_uri", fileUri);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        // get the file url
        fileUri = savedInstanceState.getParcelable("file_uri");
    }
/**
 * Receiving activity result method will be called after closing the camera
 * */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // if the result is capturing Image
    if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            // successfully captured the image
            // display it in image view
            previewCapturedImage();
        } else if (resultCode == RESULT_CANCELED) {
            // user cancelled Image capture
            Toast.makeText(getApplicationContext(),
                    "User cancelled image capture", Toast.LENGTH_SHORT)
                    .show();
        } else {
            // failed to capture image
            Toast.makeText(getApplicationContext(),
                    "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
                    .show();
        }
    }
}

/**
 * Display image from a path to ImageView
 */
private void previewCapturedImage() {
    try {


        imgPreview.setVisibility(View.VISIBLE);

        // bimatp factory
        BitmapFactory.Options options = new BitmapFactory.Options();

        // downsizing image as it throws OutOfMemory Exception for larger
        // images
        options.inSampleSize = 8;

        final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
                options);

        imgPreview.setImageBitmap(bitmap);
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}
/**
 * ------------ Helper Methods ----------------------
  * */

   /**
 * Creating file uri to store image/video
 */
public Uri getOutputMediaFileUri(int type) {
    return Uri.fromFile(getOutputMediaFile(type));
}

/**
 * returning image / video
 */
private static File getOutputMediaFile(int type) {

    // External sdcard location
    File mediaStorageDir = new File(
            Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            IMAGE_DIRECTORY_NAME);

    // Create the storage directory if it does not exist
    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
                    + IMAGE_DIRECTORY_NAME + " directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
            Locale.getDefault()).format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator
                + "IMG_" + timeStamp + ".jpg");
    } else if (type == MEDIA_TYPE_VIDEO) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator
                + "VID_" + timeStamp + ".mp4");
    } else {
        return null;
    }

    return mediaFile;
}
}

Your Suggestions are appreciated. Thanks.

Upvotes: 3

Views: 4528

Answers (3)

cybersam
cybersam

Reputation: 66947

You should not be using Environment.getExternalStoragePublicDirectory() to get the directory for your images. As the method's name implies, it will return a public directory.

To get your app's private data directory, you can call Context.getFilesDir().

See here for a guide that provides more information about writing app-private files.

Upvotes: 2

Divers
Divers

Reputation: 9569

Add empty file with name ".nomedia" in this folder. Then MediaStore will not scan this folder.

Also if you want to show to user media only from certain folder, you can use my small and simple open source library. Check TestActivity to see how to use that.

Upvotes: 5

scottt
scottt

Reputation: 8371

One way is to to name your images directory with a name that starts with a period, that will hide the images from the media scanners. So in your case the name might be ".Car Camera".

Alternatively, you can put an empty file in the directory (alongside your images) with the name ".nomedia".

Here's a link that describes these options it a bit more.

Upvotes: 3

Related Questions