Getting ID of bitmap on SD card - android

My app has a section where some images are displayed in a gridview.
Before the gridview is set up, the following is done:
Download list of image file names from the internet
Compare this list to items already present in the Drawable folder
If the image is not present in the Drawable folder, download it and save it to the SD card.
When setting up the gridview I do it by using the drawable IDs, which are easy to get as they are in a resource folder ("drawable").
But if I need to include the SD card images as well in the gridview, how can I retrive their IDs?

Files anywhere other than those packaged with your app (downloaded to the internal or external storage, for instance) don't have resource ids.
Resource ids are a shorthand way of referencing the packaged resources such as strings, images, whatever. These ids are created at build-time and only have meaning for internal resources.
In order to use images obtained from an external source, you access them by filename and, I presume, you'll then create ImageViews which are added to your GridView.
If you need to discern between the different images of the grid (perhaps for touch/click purposes) then it's the ImageView that you deal with rather than being concerned with resource ids or filenames of the images they contain.

I was having a code to get images from sdcard and convert them into an array of URIs, the ids are like URIs, use them.
private void getData() {
File f = new File("/mnt/sdcard/");
File[] imagelist = f.listFiles(new FilenameFilter(){
public boolean accept(File dir, String name)
{
return ((name.endsWith(".jpg"))||(name.endsWith(".png")));
}
});
mFiles = new String[imagelist.length];
for(int i= 0 ; i< imagelist.length; i++)
{
mFiles[i] = imagelist[i].getAbsolutePath();
}
mUrls = new Uri[mFiles.length];
for(int i=0; i < mFiles.length; i++)
{
mUrls[i] = Uri.parse(mFiles[i]);
}
}
You can use the uri like this:-
ImageView imageView=new ImageView(this);
imageView.setImageURI(mUrls[i]);

Related

Android studio fileFilter with assetManager

I have the following functionality to a desktop application with java and I want to do the same thing for a mobile application.
File f = new File(pathToFiles);
File[] files = f.listFiles(new FileFilter() {
#Override
public boolean accept(File pathname) {
return (pathname.getName().endsWith(".img") ? true : false);
}
});
Now in my android class I access the same files stored in a folder inside assets using the AssetManager with the following way:
AssetManager assetManager = context.getAssets();
String[] files = assetManager.list("folderInsideAssets");
List<String> it = new LinkedList<String>(Arrays.asList(files));
The problem here is that I get them as string in a list instead of a File class like in plain java.
Is a way to convert it to a File[] class and proceed with the same way or I should handle this differently?
Thank you in advance!
Stackoverflow Question on loading pictures from asset
Yes, create another folder in assets directory. use getAssets().list(<folder_name>) for getting all file names from assets:
String[] images =getAssets().list("images");
ArrayList<String> listImages = new ArrayList<String>(Arrays.asList(images));
Now to set image in imageview you first need to get bitmap using image name from assets :
InputStream inputstream=mContext.getAssets().open("images/"
+listImages.get(position));
Drawable drawable = Drawable.createFromStream(inputstream, null);
imageView.setImageDrawable(drawable);

Read images in drawable as File

I want to read all the Images in drawable folder as File object and store them in an array of File.
Is there a way to get list of all images in drawable and read them as File?
Edit: I need to know the following..
How to collect all the images from drawable folder. My images have different meaningful name based on the content. There is no common pattern in the name.
How to read these images as File.
No, because they are not files on the device. They are only files on your development machine. Resources are entries in the APK itself at runtime.
First you need to convert all drawable to bitmap and save to Local Storage then read it as File
You can get all Drawables from this method
public Drawable[] getAllDrawables()
{
Field[] ID_Fields = R.drawable.class.getFields();
Drawable[] drawables = new Drawable[ID_Fields.length];
for(int i = 0; i < ID_Fields.length; i++) {
try {
drawables[i] = ContextCompat.getDrawable(this,ID_Fields[i].getInt(null));
} catch (IllegalArgumentException | IllegalAccessException ignored) {
return null;
}
}
return drawables;
}
Possible Duplicate
Here

How to efficiently create subfolders using Storage Access Framework?

I'm currently using the below code to create subfolder in MicroSD on Lollipop using SAF
String[] folders = fullFolderName.replaceFirst(UriFolder + "/", "").split("/");
//fullFolderName is a String which represents full path folder to be created
//Here fullFolderName = /storage/MicroSD/MyPictures/Wallpapers
///storage/MicroSD/MyPictures/ already exists
//Wallpapers is the folder to be created
//UriFolder is String and contains /storage/MicroSD
//folders[] will have folders[0]="MyPictures" folders[1]="Wallpapers"
DocumentFile Directory = DocumentFile.fromTreeUri(context, Uri.parse(treeUri));
//treeUri is the uri pointing to /storage/MicroSD
//treeUri is a Uri converted to String and Stored so it needs to parsed back to Uri
DocumentFile tempDirectory = Directory;
//below loop will iterate and find the MyPictures or the parent
//directory under which new folder needs to be created
for(int i=0; i < folders.length-1; i++)
{
for(DocumentFile dir : Directory.listFiles())
{
if(dir.getName() != null && dir.isDirectory())
{
if (dir.getName().equals(folders[i]))
{
tempDirectory = dir;
break;
}
}
}
Directory = tempDirectory;
}
Directory.createDirectory(folders[folders.length-1]);
The above code works fine and creates subdirectory but it takes ~5 Secs to create the folder. I'm new to SAF so is this the only way to locate subdirectories or is there any other efficient way to create subdirectories?
On internal storage I will use
new File(fullFolderName).mkdir();
Which will create folder in a fraction of second.
Here is a bit efficient way to create
public static boolean createFolderUsingUri(String fullFolderName,String treeUri,
String UriFolder,Context ctx)
{
String[] folders = fullFolderName.replaceFirst(UriFolder + "/", "").split("/");
//fullFolderName is a String which represents full path folder to be created
//Example: fullFolderName = /storage/MicroSD/MyPictures/Wallpapers
//The path /storage/MicroSD/MyPictures/ already exists
//Wallpapers is the folder to be created
//UriFolder is String and contains string like /storage/MicroSD
//folders[] will have folders[0]="MyPictures" folders[1]="Wallpapers"
//treeUri string representation of Uri /storage/MicroSD
//Ex: treeUri content://uritotheMicroSdorSomepath.A33%0A
DocumentFile Directory = DocumentFile.fromTreeUri(ctx, Uri.parse(treeUri));
for(int i=0; i < folders.length-1; i++)
{
Directory=Directory.findFile(folders[i]);
}
Directory.createDirectory(folders[folders.length-1]);
return true;
}
The method described in question took ~5 Secs, whereas this method takes ~ 3 Secs. On CM file manage the folder creation on same path took ~4 Secs so this is comparatively faster method. Yet searching more faster way which will take < 1 Sec

how to store Arraylist of object to store and retrieve from SDCard

I have ArrayList of object like
ArrayList<DataCCHeading>CC1=new ArrayList<DataCCHeading>();
ArrayList<DataCCHeading>hd=new ArrayList<DataCCHeading>(result);
for (DataCCHeading dataCCHeading : hd)
{
if(dataCCHeading.Ownername==TAG_CC1HeadingData)
{
CC1.add(dataCCHeading);
}
}
What I want to do to store external storage SDCard so that I can later get that data other wise I have to request it again from server. My question is how to store Arraylist of object to store and retrieve from SDCard?
You have a few options:
Java Serialization: Just make your class implements Serializable, and write the appropriate serialize and deserialize logic, and you can write them to a file and read it back. See this tutorial: http://www.tutorialspoint.com/java/java_serialization.htm
JSON serialization: Use a library list GSON, you can serialize your objects to a JSON array as a text file, save it to a file. Then read it back as a JSON string and use the GSON library again to convert it back to an arraylist of your object.
Use built-in SQLiteDatabase: Store your objects as rows of data in a sqlite database. Class members will be stored as columns in a table. To convert them back to an array, just retrieve all rows from the table, build the object one by one and add them to an arraylist.
You'd probably want to serialise it into something first (e.g.: using JYaml).
Then you can easily de/serialise, and it's quite space efficient.
You do it like this:
//use getExternalStorageState to determine if there is an sd card
if (Environment.getExternalStorageState() == null) {
directory = new File(Environment.getDataDirectory()
+ "/RobotiumTestLog/");
photoDirectory = new File(Environment.getDataDirectory()
+ "/Robotium-Screenshots/");
/*
* this checks to see if there are any previous test photo files
* if there are any photos, they are deleted for the sake of
* memory
*/
//if the directory exists, delete files in directory
if (photoDirectory.exists()) {
File[] dirFiles = photoDirectory.listFiles();
if (dirFiles.length != 0) {
for (int ii = 0; ii <= dirFiles.length; ii++) {
dirFiles[ii].delete();
}
}
}
// if no directory exists, create new directory
if (!directory.exists()) {
directory.mkdir();
}
// if phone DOES have sd card
} else if (Environment.getExternalStorageState() != null) {
// search for directory on SD card
directory = new File(Environment.getExternalStorageDirectory()
+ "/RobotiumTestLog/");
photoDirectory = new File(
Environment.getExternalStorageDirectory()
+ "/Robotium-Screenshots/");
if (photoDirectory.exists()) {
File[] dirFiles = photoDirectory.listFiles();
if (dirFiles.length > 0) {
for (int ii = 0; ii < dirFiles.length; ii++) {
dirFiles[ii].delete();
}
dirFiles = null;
}
}
// if no directory exists, create new directory to store test
// results
if (!directory.exists()) {
directory.mkdir();
}
}
It is a pretty easy process. What I did here was check to see if there is an SD card, if there is, I search for a directory, if no directory, I create one. If there is a directory and it has content I erase it. You don't have to do all that. If you like, you can use the the Environment.getExternalStorageDirectory(). This will get the SD card. From there you create a bufferedWriter and write. You also need to add <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> in your manifest. If you have any questions, let me know.
I hope this helps!

Android device specific camera path issue

I know that my question is a duplicate of this question and this one. But still I have some problems, so don't try to close or downvote my question friends. Please go through the question fully.
In my app I want to store Images into the same folder as where the device native Camera stores them. As per my research, I have found out that each device stores the Images into a different name and in different folder.
That is:
Nexus-One stores its camera files into a folder named Camera (/sdcard/DCIM/Camera).
All HTC devices store their camera files into a folder named 100MEDIA (/sdcard/DCIM/100MEDIA).
Sony Xperia x10 stores its camera files into a folder named 100ANDRO (/sdcard/DCIM/100ANDRO).
Motorola MilesStone stores its camera files into a folder named Camera (/sdcard/DCIM/Camera).
So I wanted to know if it's programmatically possible to get this path so that I can store the images taken from my app to the same location?
When I was googling I found out that it's better to create an external folder of my own so that I can store the images in that path with the name I am specifying. After that also in HTC device of API version 3 (Android 1.5) I found out that only the folder is getting created but the image gets saved in its default place with a name of its own.
How to solve this issue? Is it not possible to find the specific path and name of the image that gets saved for each device? Please help me friends.
Use getExternalStorageDirectory() if API level is below 7 and then append /Pictures to get the path of Photos storage.
for API level > 7 use getExternalStoragePublicDirectory (DIRECTORY_PICTURES).
I use the following code
String pictures_path = Utils.getRealPathFromURI(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
File path = new File(pictures_path);
if (path.isFile())
path = path.getParentFile();
Where Utils:
public static String getRealPathFromURI(Uri content_uri, int media_type) {
String column = MediaType.MEDIA_TYPE_PICTURE;
ContentResolver content_resolver = getContext().getContentResolver();
String [] proj = { column };
Cursor cursor = content_resolver.query(content_uri,
proj, // Which columns to return
null, // WHERE clause; which rows to return (all rows)
null, // WHERE clause selection arguments (none)
null); // Order-by clause (ascending by name)
int column_index = cursor.getColumnIndexOrThrow(column);
if (!cursor.moveToFirst())
return null;
return cursor.getString(column_index);
}
EDIT: Unfortunatelly, the approach above may not always work :( ...
Eventually I did manual checkings:
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
if (path.exists()) {
File test1 = new File(path, "100MEDIA/");
if (test1.exists()) {
path = test1;
} else {
File test2 = new File(path, "100ANDRO/");
if (test2.exists()) {
path = test2;
} else {
File test3 = new File(path, "Camera/");
if (!test3.exists()) {
test3.mkdirs();
}
path = test3;
}
}
} else {
path = new File(path, "Camera/");
path.mkdirs();
}
This is the function that I am using. It doesnt specifically name 100Media or Camera directories. It simply starts in the /DCIM folder and looks at its children. If the child is not a .thumbnails directory (or is, depending on what youre doing), then look at its children and get them. It also gets pictures in the /DCIM directory itself.
File dcim = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File thumbnails = new File(dcim, "/.thumbnails");
File[] listOfImg = dcim.listFiles();
if (dcim.isDirectory()){
//for each child in DCIM directory
for (int i = 0; i < listOfImg.length; ++i){
//no thumbnails
if( !listOfImg[i].getAbsolutePath().equals(thumbnails.getAbsolutePath()) ){
//only get the directory (100MEDIA, Camera, 100ANDRO, and others)
if(listOfImg[i].isDirectory()) {
//is a parent directory, get children
File[] temp = listOfImg[i].listFiles();
for(int j = 0; j < temp.length; ++j) {
f.add(temp[j].getAbsolutePath());
}
}else if(listOfImg[i].isFile()){
//is not a parent directory, get files
f.add(listOfImg[i].getAbsolutePath());
}
}
}
}
I have been looking for a solution to this problem myself. Since different manufacturers have differnet naming conventions for camera folders, this seems to cover all ground best. It works for me pretty well.

Categories

Resources