0

I have created an ImageView and I can see the preview of the camera and load the captured image into the ImageView and I wanted to store the image into a directory in my internal memory. I have referred many posts and tried but I couldn't find my image in my internal memory.

This is the code I have used:

package com.example.shravan.camera;

import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    private final String TAG = "abc";

    static final int REQUEST_IMAGE_CAPTURE =1 ;
    ImageView iv;
    Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn = (Button)findViewById(R.id.myB);
        iv = (ImageView) findViewById(R.id.myIV);
        //disable the button if the user has no camera
        if (!hasCamera()) {
            btn.setEnabled(false);
        }
    }

    public boolean hasCamera() {
        return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
    }

    //on click event handler that launches the camera
    public void launchCamera(View v) {
        Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(i, REQUEST_IMAGE_CAPTURE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            imageUri=data.getData();
            iv.setImageURI(imageUri);;
        }
    }

    public void SaveFile(View v) {
        BitmapDrawable drawable = (BitmapDrawable) iv.getDrawable();
        Bitmap bitmap = drawable.getBitmap();

        print("Creating cw");
        ContextWrapper cw = new ContextWrapper(this.getApplicationContext());
        print("Creating dir");
        File directory = cw.getDir("ImagesDir", Context.MODE_PRIVATE);
        print("Created dir" + directory);
        File mypath = new File(directory,"myImagesDGS.jpg");
        print("path is" + mypath);

        FileOutputStream fos = null;
        try {
            print("creating fos");
            fos = new FileOutputStream(mypath);
            print("Compressing bitmap");
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
                print("fos closed");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void print(String str){
        Log.d(TAG, str);
    }

}

I have made many log messages to debug and I got one path which I couldn't find in my phone.

This is the logcat:

08-07 21:47:37.089 11030-11030/com.example.shravan.camera D/abc: Creating cw 08-07

21:47:37.089 11030-11030/com.example.shravan.camera D/abc: Creating dir 08-07

21:47:37.099 11030-11030/com.example.shravan.camera D/abc: Created dir/data/user/0/com.example.shravan.camera/app_ImagesDir 08-07

21:47:37.099 11030-11030/com.example.shravan.camera D/abc: path is/data/user/0/com.example.shravan.camera/app_ImagesDir/myImagesDGS.jpg

08-07 21:47:37.099 11030-11030/com.example.shravan.camera D/abc: creating fos

08-07 21:47:37.099 11030-11030/com.example.shravan.camera D/abc: Compressing bitmap

08-07 21:47:42.589 11030-11030/com.example.shravan.camera D/abc: fos closed

Is there anything I need to check and I should change? Please help!

Matt Ke
  • 3,599
  • 12
  • 30
  • 49
Shravan DG
  • 527
  • 1
  • 5
  • 16
  • ITs in /data/user/0/com.example.shravan.camera/app_ImagesDir/myImagesDGS.jpg. But you need root access to get at private app files. – Gabe Sechan Aug 08 '16 at 03:02
  • Your app saved a file in an app specific private directory. Only your app has access (no need for root)). Not other apps like file explorers which you used to find the file. – greenapps Aug 08 '16 at 07:10
  • @greenapps How can I find it on file explorer then? – Shravan DG Aug 08 '16 at 18:55
  • @GabeSechan How can I access it from other apps? What modifications do I need to make? – Shravan DG Aug 08 '16 at 19:30
  • As said you can not find it with a file explorer. So don't save your file in internal memory but in external. – greenapps Aug 08 '16 at 21:21
  • My device doesn't have an external storage. That's the problem! What should I do now in this case to create a separate folder in my internal memory and then store my images in that directory? – Shravan DG Aug 08 '16 at 21:38
  • All devices have internal and external storage. It is unclear where you are talking about. If you put a micro SD card in it then that is considered removable storage. – greenapps Aug 09 '16 at 10:09
  • Ya. My device doesn't have support for a micro SD. All it has is internal storage. So, that's the issue – Shravan DG Aug 09 '16 at 13:37

7 Answers7

9

Got it working!

I used this code to create a directory in my file storage and then store the image:

FileOutputStream outStream = null;

// Write to SD Card
try {
    File sdCard = Environment.getExternalStorageDirectory();
    File dir = new File(sdCard.getAbsolutePath() + "/camtest");
    dir.mkdirs();

    String fileName = String.format("%d.jpg", System.currentTimeMillis());
    File outFile = new File(dir, fileName);

    outStream = new FileOutputStream(outFile);
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
    outStream.flush();
    outStream.close();

    Log.d(TAG, "onPictureTaken - wrote to " + outFile.getAbsolutePath());

    refreshGallery(outFile);
} catch (FileNotFoundException e) {
    print("FNF");
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {

}

My permissions:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Finally, the most important thing:

Go to Device Settings>Device>Applications>Application Manager>"your app">Permissions>Enable Storage permission!

Matt Ke
  • 3,599
  • 12
  • 30
  • 49
Shravan DG
  • 527
  • 1
  • 5
  • 16
1

The location your current images are saving, cannot be accessed by an other application.It's better to save them in a accessible location.try like this..

BitmapDrawable drawable = (BitmapDrawable) iv.getDrawable();
Bitmap bitmap = drawable.getBitmap();
 try {
           String root = Environment.getExternalStorageDirectory().toString();
           File file = new File(root + "/YourDirectory/myImagesDGS.jpg");
           FileOutputStream out = new FileOutputStream(file);
           bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
           out.flush();
           out.close();

                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }

then you can retrieve your saved images like this..

String root = Environment.getExternalStorageDirectory().toString();
  File file = new File(root + "/YourDirectory/myImagesDGS.jpg");    
Bitmap bmap=BitmapFactory.decodeFile(file.getAbsolutePath());
Chathu_sm
  • 85
  • 9
  • `The location your current images are saving, cannot be accessed`. Of course you can. If you can write to files there you can read them too. Please rephrase what you mean. – greenapps Aug 08 '16 at 07:08
  • I have tried your code and it gave me a file not found exception! What am I missing? – Shravan DG Aug 08 '16 at 19:12
  • But my device doesn't have external storage! How to create a directory in internal storage? @greenapps – Shravan DG Aug 08 '16 at 22:31
  • @ShravanDG actually you does...the one you can access(Internal Storage) is referred as external storage here.. – Chathu_sm Aug 09 '16 at 03:04
  • Where will the images be saved (the directory of the app or YourDirectory) in internal memory? I didn't find anything in either of these folders! – Shravan DG Aug 09 '16 at 04:32
  • @ShravanDG you'll find a directory called "yourdirectory" in your storage...that is where the file is being stored – Chathu_sm Aug 09 '16 at 05:25
  • @Sandaruwan I cannot create the directory and save the image. I have been trying it in several ways. Can you please help? – Shravan DG Aug 09 '16 at 18:38
  • @ShravanDG are there any execeptions thrown....can you please check where the code breaks using `Log.e()` or something – Chathu_sm Aug 10 '16 at 02:28
  • I am getting a FileNotFound exception! Don't know why! What am I missing? – Shravan DG Aug 10 '16 at 03:37
  • can you check weather the file is properly stored or not in the storage...using a file manager tool or something.. – Chathu_sm Aug 10 '16 at 03:41
  • That is the problem. I have checked it! It is not being stored! – Shravan DG Aug 10 '16 at 14:26
  • It is stored in some random location /data/user/0/com.example.shravan.asbdbsadbsabcxscsa/app_mydir/myfile which I cant find. By default I can ses the image in DCIM folder. – Shravan DG Aug 10 '16 at 14:47
0

Your image is saving from this path /data/user/0/com.example.shravan.camera/app_ImagesDir/myImagesDGS.jpg but your are not access.try this code for iamge reading.Call this method into onCreate this method is return you bitmap.

 Bitmap mBitmap= getImageBitmap(this,"myImagesDGS","jpg");

   if(mBitmap !=null){

yourImageView.setBitmap(mBitmap);

}else{

Log.d("MainActivity","Image is not found");
}

It is sepread method

     public Bitmap getImageBitmap(Context context,String name,String extension){
        name=name+"."+extension;  
        try{ 
            FileInputStream fis = context.openFileInput(name);
                Bitmap b = BitmapFactory.decodeStream(fis);
                fis.close();
                return b;
            } 
            catch(Exception e){
            } 
            return null; 
        }
Muhammad Waleed
  • 2,517
  • 4
  • 27
  • 75
0

try this. I modified my code to fit the code your provide. I did not test it. I temporary store the photo taken into a file with time stamp, then use the filename to retrieve the file. Hope it helps

private Uri mImageCaptureUri;
public void launchCamera(View v)
{
    //Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    //startActivityForResult(i, REQUEST_IMAGE_CAPTURE);

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
                            "tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));

                    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (mImageCaptureUri!=null){
//Do whatever you want with the uri
}

}
}
kggoh
  • 742
  • 1
  • 10
  • 24
0

With that code, you will be ended to store your file to your private application data. You can't access that data with other applications except your application itself without root access. You can get the public image directory by using this code instead when declaring the file path if you want your image file can be accessed by other applications.

File albumF;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
    albumF = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
} else {
    albumF = context.getFilesDir();
}

If you need to make your sub directory inside public gallery directory, you can change the code above like this:

File albumF;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
    albumF = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DCIM), YOUR_SUB_DIRECTORY_STRING);
} else {
    albumF = new File(context.getFilesDir(), YOUR_SUB_DIRECTORY_STRING);
}

You might be need to add this code to create that album directory

if (!albumF.exists()) {
    albumF.mkdirs();
}
HendraWD
  • 2,984
  • 2
  • 31
  • 45
  • I tried this code but still can't find my image directory or image in gallery! It just gets added to my default camera folder. Please help – Shravan DG Aug 08 '16 at 19:30
  • @ShravanDG yes, nothing wrong with the code, because it should work like that. I will add a code to make your subfolder inside the public gallery folder – HendraWD Aug 10 '16 at 04:23
  • I have just tried the code and my app is stopping unfortunately. Can you plese look into this? my code: (I am saving the image on button click) – Shravan DG Aug 10 '16 at 04:43
  • //after converting image to bitmap then File albumF; if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ albumF = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "MyDir"); } else { albumF = new File(context.getFilesDir(), "MyDir"); } albumF.mkdirs(); File file = new File(albumF, "a.jpg"); FileOutputStream fout = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 85, fout); } – Shravan DG Aug 10 '16 at 04:46
  • @ShravanDG can you show the stack trace of the error? – HendraWD Aug 10 '16 at 10:25
  • I got this: E/System: Uncaught exception thrown by finalizer, E/System: java.lang.IllegalStateException: Binder has been finalized at android.os.BinderProxy.transactNative(Native Method) at android.os.BinderProxy.transact(Binder.java:503) at com.android.internal.app.IAppOpsService$Stub$Proxy.stopWatchingMode(IAppOpsService.java:431) at android.media.SoundPool.release(SoundPool.java:195) at android... – Shravan DG Aug 10 '16 at 14:15
  • Hendra Wijaya Djiono- I debugged it! The app is crashing at this part: albumF.mkdirs(); File file = new File(albumF, FILENAME + CurrentDateAndTime + ".jpg"); FileOutputStream fout = new FileOutputStream(file); What shoud I do? (error while creating the fout and getting a FileNotFound exception!) Help.. – Shravan DG Aug 10 '16 at 14:33
  • Try to check if the file exist first. If not exist, just create the file. if(!file.exists()) { file.createNewFile(); } – HendraWD Aug 11 '16 at 04:06
0

Try using ImageSaver. It's a synchronous way to save and load images from internal and external storage.

Usage

  • To save:

    new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            setExternal(true).
            save(bitmap);
    
  • To load:

    Bitmap bitmap = new ImageSaver(context).
            setFileName("myImage.png").
            setDirectoryName("images").
            setExternal(true).
            load();
    
Community
  • 1
  • 1
Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216
0

The solution proposed by @Shravan DG gives error for me. I have modified his code little bit and it works without errors.

 private void downloadQR()
{
    FileOutputStream outStream = null;
    
    try {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "QRCode_" + timeStamp + ".jpg";
        File storageDir = new File(Environment.getExternalStorageDirectory().toString(), "PARENT_DIR)/CHILD_DIR/");
        storageDir.mkdirs();

        File outFile = new File(storageDir, imageFileName);
        outStream = new FileOutputStream(outFile);
        BitmapDrawable drawable = (BitmapDrawable) qrCode.getDrawable();
        Bitmap bitmap = drawable.getBitmap();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.flush();
        outStream.close();

        Log.d(TAG, "onPictureTaken - wrote to " + outFile.getAbsolutePath());

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {

    }
}

Chill Pill :)

Ali Akram
  • 4,803
  • 3
  • 29
  • 38