I'm pretty new to programming Android and I have a problem - I'm creating an app which stores "funny" images and enables user to view all of them, rate them (at least I want to make it so ;) ). I was trying to make a very simple database which stores images as BLOBs but someone on forum told me that this is a bad idea - so I decided to store images on SD like (this code is mainly from Stack although):
private void savePicToSD(){
Toast.makeText(getActivity(),"Saving...",Toast.LENGTH_SHORT).show();
//getting BitMap from ImageView
Bitmap imageToSave=((BitmapDrawable)preview.getDrawable()).getBitmap();
// getting env var representing path
String root= Environment.getExternalStorageDirectory().toString();
Toast.makeText(getActivity(),root,Toast.LENGTH_LONG).show();
File dir=new File(root+DIR_NAME_);
dir.mkdirs();
String fileNam="Image-"+FILE_COUNTER_+".jpg";
FILE_COUNTER_=FILE_COUNTER_.add(BigInteger.valueOf(1));
File fileSav=new File(dir,fileNam);
//I don't use try-with-resources because of API lvl
FileOutputStream out=null;
try{
out=new FileOutputStream(fileSav);
//saving compressed file ot the dir
imageToSave.compress(Bitmap.CompressFormat.JPEG,90,out);
out.flush();
out.close();
}catch(Exception ex) {
ex.printStackTrace();
Toast.makeText(getActivity(), "Error during saving.", Toast.LENGTH_SHORT).show();
}
Toast.makeText(getActivity(),"Image saved.",Toast.LENGTH_LONG).show();
}
after making it I now don't know how to store this "reference" and how to implement "fetching data from DB" - I was thinking about storing (with some sort of other data releated to specific photo) in DB string contatining path to the image and later while reading data from DB, read also the image - but how to do this efficiently? (I know that fetching data from DB has to be done as a Thread (AsyncTask ? ))?
I think the best you can do is storing the path of the image in BDD or a relative path and then access it
Store imagePath/fileName in your local database along with saving the image in the file system(SD card), and then when you want to get back that image just fetch that image from the file system by using imagePath/fileName stored in database.
I hope that you know how to create file and store in SD card.
Related
An Android novice here.
I'm trying to complete a task which involves creating a simple app containing buttons on a single page. Each button, when clicked, should display the corresponding image.
One thing I don't understand in the instructions is that "the images should be stored on the phone filesystem rather than compiled into the application under
resources". What exactly does this mean? Do I need to load the images into the phone manually every time I try running the application? Any guidance would be appreciated.
private void saveImage(Bitmap finalBitmap, int i ) {
File file = new File (path+name.jpg);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 50, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
This method will save bitmap as a jpeg file on your phone.
P.S.
path - path of place where you want to save
name - name of image
Apps can include images in their resources/drawable folder that get added into the actual app .apk file. That makes them retrievable using R.drawable.image_name. Sounds like the instructions you are following does not want you do this. They want you to store them on the phone in the data/data/package file structure. If this is the case you can find plenty of examples on how to do this. The answer by Arsen Sench here does this.
I am making a quiz app which requires me to be able to get an image from a database BLOB or image path stored in the database. However i have looked around and a lot of people suggest using a file path, the problem is i don't know where to store the image if i use the file path method.
Do i store it somewhere in the app such as the resources folder?, a lot of examples use SD cards but is it possible to save an image to SD card from a database and if so surely that would mean i have two images one in database and one on SD card.
Where is the best place to store a images for a quiz app that i can use on any phone an will have access to said images? and how ?.
Thanks in advance.
Image storage must be performed in some directory and the corresponding paths of the image must be stored in the database.
There will be times when you will accessing your images from one acivity then the other, in that case you will just need to pass the path of the image from activity one to activity two and then retrieve the image from the directory to display in activity two.
Image storing and loading from databases may turn out to be a pain when the size of the images will start increasing.
For learning how to store images, Give an eye to this
CODE EXAMPLE
private void SaveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
In the above code, the line
Environment.getExternalStorageDirectory()
is refering to android/data folder. you can create folder inside upto any level, like android/data/folderone/folderTwo/folderThree
.
Note: However you need to first fetch the images from server for the first time and store them in device.If you are thinking of bundling up the images along with the app, put all of your images in res/drawable folders.(if no web server functionality is involved)
After searching about "How to save Layout views as images", I've found some solution to save in Internal and External Storage. But It seems the image file created is going to save in some data/data/... folder that is not visible normally. Actually I want the image visible in gallery for the user. I've found some code like below, but I even can't check if the image is created or not:
View content = findViewById(R.id.relativeLayout);
String yourimagename = "MyImageFile";
content.setDrawingCacheEnabled(true);
Bitmap bitmap = content.getDrawingCache();
File file = new File("/" + yourimagename + ".png");
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 10, ostream);
ostream.close();
content.invalidate();
} catch (Exception e) {
e.printStackTrace();
} finally {
content.setDrawingCacheEnabled(false);
}
But It seems the image file created is going to save in some data/data/... folder that is not visible normally.
The file will be saved where the programmer elects to save it.
Actually I want the image visible in gallery for the user. I've found some code like below, but I even can't check if the image is created or not
That code will not work on any version of Android, as new File("/" + yourimagename + ".png") is not going to give you a usable File, as it points to a place that you can neither read nor write.
You are welcome to save the image to internal storage or external storage. Since you want this image to be picked up by "gallery"-type apps, you are best off choosing external storage, then using MediaScannerConnection and its scanFile() method to get the file indexed by the MediaStore, since gallery apps will tend to use the MediaStore as their source of images.
On the whole, I worry that getDrawingCache() will be unreliable. You may be better served telling your root View to draw to your own Bitmap-backed Canvas instead.
My application allows users to take a photo using the camera and save it as their profile picture. There can be only 1 image stored at a time?
Is it a bad idea to use SharedPrefertences for this purpose although I am only storing 1 image? (Converting image to Base64). What are the cons?
If storing the image using shared preferences is not a good idea, what are the alternatives?
I think storing binary data in SharedPreferences is not a good idea. Instead save it to the filesystem. Example for that, if the data is coming from an InputStream:
storeImage( new File(context.getFilesDir().getAbsolutePath() + fileDir),
is,
"profile.png" );
public static void storeImage(
File fileDir,
InputStream inputStream,
String fileName ) throws IOException {
File file = new File( fileDir,fileName );
FileOutputStream fos = new FileOutputStream( file );
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
inputStream.close();
fos.close();
bitmap.recycle();
bitmap = null;
}
Where context can be the Application/Activity context.
There is no reason why you can't use SharedPreferences to store a single image as a Base64 String, Of course this isn't really a scalable approach as when the SharedPreferences are loaded, every image would be loaded into memory at once, but that's not what your looking for.
The other possible approaches you can take is to store the images either using the internal or external storage APIs or to store them in a database
In general for this kind of thing you should be looking to use something other than shared preferences, however in this case, I can't see there been an actual issue to the approach your suggesting.
As the title states, I'm trying to launch the camera and take a picture that I can use with the APP locally. This is for the Motorola Xoom and, by default, they do not come with SD cards. Or at least the ones my client is looking into purchasing do not have SD cards.
I've found a pretty nice tutorial on how to launch the camera and I can get it to launch and everything up to it physically saving the image and then being able to re-use that image.
A lot of the solutions or other tutorials I've found only show how to save to an SD card -- not to resident memory or local to the app. It looks like it is possible to do so but am stumped. :-/
You could perhaps load it to ContentProvider so that you could use the images later for anything:
// Add some parameters to the image that will be stored in the Image ContentProvider
int UNIQUE_BUCKET_ID = 1337;
ContentValues values = new ContentValues(7);
values.put(MediaStore.Images.Media.DISPLAY_NAME,"name of the picture");
values.put(MediaStore.Images.Media.TITLE,"Thats the title of the image");
values.put(MediaStore.Images.Media.DESCRIPTION, "Some description");
values.put(MediaStore.Images.Media.BUCKET_DISPLAY_NAME,"Album name");
values.put(MediaStore.Images.Media.BUCKET_ID,UNIQUE_BUCKET_ID);
values.put(MediaStore.Images.Media.DATE_TAKEN,System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
// Inserting the image meta data inside the content provider
Uri uri = getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
// Filling the real data returned by the picture callback function into the content provider
try {
OutputStream outStream = getContentResolver().openOutputStream(uri);
outStream.write(buffer); // buffer is the data stream returned by the picture callback
outStream.close();
}catch (Exception e) {
Log.e(TAG, "Exception while writing image", e);
}
Check out Activity.getFilesDir() and Activity.getCacheDir() they provide access to storage where the app is stored. Also check out Environment.getExternalStoragePublicDirectory (), external, here, means outside the application's private directories. There are several others so look around the API's similarly named methods to find the best fit for you.
So one thing you should note is that when you call Environment.getExternalStorageDirectory(), this does not necessarily correspond to an external memory space (i.e. and SD card) and would return a local memory space on devices without SD card slots.
Note: don't be confused by the word "external" here. This directory can better be thought as media/shared storage. It is a filesystem that can hold a relatively large amount of data and that is shared across all applications (does not enforce permissions). Traditionally this is an SD card, but it may also be implemented as built-in storage in a device that is distinct from the protected internal storage and can be mounted as a filesystem on a computer.
http://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory()
The same applies for Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);