I wasn't sure how to word this, but in iOS terms, if I download an image, and save it in the documents directory, it saves it in the Apps Container, which is not visible to other apps, and camera roll etc.
The way I have it in Android currently, all of these images are visible in the File Explorer and Gallery.
I was wondering how I could save these images in a similar way to iOS and have them hidden in the Apps own container.
Is there a way to create a folder, with context.MODE_PRIVATE or something similiar?
This is what I have currently, does it do the trick?
public static Boolean saveToInternalStorage(Context context, Bitmap bitmap, String filename) {
ContextWrapper cw = new ContextWrapper(context);
//Path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
//Create imageDir
File mypath = new File(directory, filename);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
//Use the compress method on the BitMap object to write image to the OutputStream
if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
public static Bitmap loadImageFromStorage(Context context, String filename) {
ContextWrapper cw = new ContextWrapper(context);
//Path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
try {
File f = new File(directory, filename);
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
return b;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
Read this article. This will help..
You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user). When the user uninstalls your application, these files are removed.
I was wondering how I could save these images in a similar way to iOS and have them hidden in the Apps own container.
Write them to getFilesDir(), getCacheDir(), or another location on internal storage.
This is what I have currently, does it do the trick?
The ContextWrapper is useless. If you are downloading an image, I do not know why you have a Bitmap that you are trying to write to storage — download straight to storage.
But, with respect to keeping the images private to your app, getDir() also points to locations in internal storage.
Related
I cannot seem to delete a picture from the local storage. What I want to happen is: delete the old picture, add a new picture with the same name.
When I change the picture name it has no problem loading it as a new one. But when I don't change its name it shows the old picture.
I tried context.deleteFile(filename). file.exists returns false after deletion but the picture is still there.
A solution with overwriting can be helpful.
I also have external storage permissions in the manifest.
Thanks!
The deletion:
void deleteOldPicture(String filename, Context context){
File file = new ImageSaver(context).setFileName(filename).setDirectoryName("images").createFile();
file.delete();
}
Creating the file
File createFile() {
File directory;
if(external){
directory = getAlbumStorageDir(directoryName);
}
else {
directory = context.getDir(directoryName, Context.MODE_PRIVATE);
}
return new File(directory, fileName);
}
private File getAlbumStorageDir(String albumName) {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e("ImageSaver", "Directory not created");
}
return file;
}
Saving the file:
private String saveFileInSD(String name, ImageView image){
String filename = name+parentId+".png";
Log.e("Filename is", filename);
new ImageSaver(getApplicationContext()).setFileName(filename).setDirectoryName("images").save(((BitmapDrawable) image.getDrawable()).getBitmap());
return filename;
}
add this library to your Gradle, it will help clean up your code a little bit :
implementation 'org.apache.commons:commons-io:1.3.2'
the do the following to save the picture :
//Compress the Bitmap
ByteArrayOutputStream stream = new ByteArrayOutputStream();
yourBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
//save Bitmap to file and get it form preview activity and especially to avoid TransactionTooLargeException
File imageFile = new File(getExternalCacheDir(), "image.png");
try {
FileOutputStream imageFileStream = new FileOutputStream(imageFile);
IOUtils.copyLarge(new ByteArrayInputStream(stream.toByteArray()), imageFileStream);
IOUtils.closeQuietly(imageFileStream);
} catch (Exception e) {
e.printStackTrace();
}
to get the path of your saved bitmap just use the following method :
imageFile.getAbsolutePath()
I'm trying to save bitmap to gallery to open it again from ImagePicker intent.
The problem is - if I'm saving it on external storage, it will not work on devices without it, and when I'm writing it on internal storage - it won't shown in gallery, so i can not pick that image.
Tried so many ways of resolving it, but no success this far.
I mean, is it possible to save bitmap in internal storage and open it from activity, which called to choose image from gallery?
edit: added code
private String saveToInternalStorage(Bitmap bitmapImage, String filename){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Create imageDir
File mypath=new File(directory,filename + ".jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return directory.getAbsolutePath();
}
With that procedure it's seems like saving bitmap is ok, but i can't find that file in gallery.
I am using this code to store image in internal storage but image is not saving in phone storage, instead it is storing in sd card with path : /storage/sdcard0/DCIM/CAMERA/IMG_2345.,jpg
private String saveToInternalMemory(Bitmap bitmap,String imgName){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
File file = new File(getCacheDir(),"imageDirectory");
//File directory = cw.getDir("imageDirectory", Context.MODE_PRIVATE);
//File userDirectory = new File(directory,imgName);
File myPath = new File(file,imgName);
Log.e("path",myPath.getAbsolutePath());
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
bitmap.compress(Bitmap.CompressFormat.PNG,100,fos);
Log.e("img_name",bitmap.toString());
}catch (FileNotFoundException e){}
catch (IOException e){}finally {
try {
fos.close();
}catch (IOException e){}
}
return myPath.getAbsolutePath();
}
Is phone storage and internal memory storage are same?
Actually when i am removing my sdcard then the image is storing in phone storage but if i reconnect my sdcard then by default it is storing in sdcard. How can i store my image by default in phone storage.
Our android's File storage shows two directories sdcard and phone storage, so image is storing in sdcard not in phone storage
I have gotten this message when I try to save an imagen file ...
java.io.FileNotFoundException: /logocte1 (Read-only file system)
My method ...
public static String saveFile(Bitmap bitmap, String filename) {
String stored = null;
File file = new File(filename) ;
if (file.exists())
return stored ;
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
stored = "success";
} catch (Exception e) {
e.printStackTrace();
}
return stored;
}
I want to write the file INTO internal menory ... I don't have external memory in my pone.
I have gotten this message when I try to save an imagen file
You cannot write to arbitrary locations. Please use methods like getFilesDir() and getExternalFilesDir() for directories that you can write to.
I don't have external memory in my pone.
Most likely, you do. External storage is not the same as removable storage, and neither of those are the same as internal storage.
this is a peace of code I've created to save a "library" of images to external storage in order to use that file in another application. This is a binary file which contains ArrayList of objects.
this is method what makes main job.
public void createLib()
{
File fl = new File("/mnt/sdcard/imgs");
File[] rawLib = fl.listFiles();
TextView text = (TextView) findViewById(R.id.txt1);
ArrayList<Block> myList = new ArrayList<Block>();
try{
for (int i = 0; i < rawLib.length; i++)
{
FileInputStream fis = new FileInputStream(rawLib[i]);
Bitmap bmp = BitmapFactory.decodeStream(fis);
Block tmpBlock = new Block();
tmpBlock.bmp = bmp;
tmpBlock.mozColor = findMidColor(bmp);
myList.add(tmpBlock);
}
}
catch(Exception exc)
{
exc.printStackTrace();
}
try
{
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
File file = new File (myDir, "library.lib");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream save = new ObjectOutputStream(fos);
save.writeObject(myList);
save.close();
}
catch (Exception exc)
{
exc.printStackTrace();
}
here is the class I am working with
class Block
{
Bitmap bmp;
int mozColor;
}
findMidColor() is my method and it work pretty fine, so there is no problem with that.
When I pull created file from the emulators external storage, I see that file's size is about two and a half kilobytes, but original folder with images is about 2-3 megabytes.
Conslusion is that program saves only pointers to that bmp's. Is there any way to create bynary file of objects which contain images and ints, and reuse that file in another application like a ArrayList or any other array?
Yes Bitmap's data (pixels) are not saved in the Bitmap object. They live somewhere in the heap. You are now saving only references to wrong locations.
In your Block class instead of having a Bitmap object you can have a path to the Bitmap and a method that returns a Bitmap from that path.
class Block{
String bitmapPath;
int mozColor;
Bitmap bmp(){
//do something here to encode bitmap from file
}
}
You have to save the bitmap to a specific path and store it to Block.bitmapPath every time
You can easily find how to save a Bitmap to a File and retrieve from File