I am trying to make an android camera app with image gallery. The images captured are saved to a private directory: Android/data/com.example.newcamera/files/pictures.
Whenever I am using INTERNAL_CONTENT_URI or, EXTERNAL_CONTENT_URI as Uri, The app is bringing all the public pictures of my phone but not the one in the private directory. But I need only those with private directory. How can I get it? Please help me. My code snippet is as follows:
Thanks in advance.
protected String doInBackground(String... args) {
String xml = "";
String path = null;
String album = null;
String timestamp = null;
String countPhoto = null;
Uri uriInternal = MediaStore.Images.Media.INTERNAL_CONTENT_URI;
Uri uriExternal = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri myUri = Uri.fromFile(new File(getApplicationContext().getFilesDir().getAbsolutePath()));
String[] projection = { MediaStore.MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME, MediaStore.MediaColumns.DATE_MODIFIED };
Cursor cursorExternal = getContentResolver().query(uriExternal, projection, "_data IS NOT NULL) GROUP BY (bucket_display_name",
null, null);
Cursor cursorInternal = getContentResolver().query(uriInternal, projection, "_data IS NOT NULL) GROUP BY (bucket_display_name",
null, null);
Cursor myCursor = getContentResolver().query(myUri, projection, "_data IS NOT NULL) GROUP BY (bucket_display_name",
null, null);
Cursor cursor = new MergeCursor(new Cursor[]{cursorExternal, cursorInternal, myCursor});
while (cursor.moveToNext()) {
path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA));
album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
timestamp = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATE_MODIFIED));
countPhoto = Function.getCount(getApplicationContext(), album);
albumList.add(Function.mappingInbox(album, path, timestamp, Function.converToTime(timestamp), countPhoto));
}
cursor.close();
Collections.sort(albumList, new MapComparator(Function.KEY_TIMESTAMP, "dsc")); // Arranging photo album by timestamp decending
return xml;
}
You can fetch your files from particular folder by:
File folder = new File(Environment.getExternalStorageDirectory().toString() + "/Folder Name/");
folder.mkdirs();
File[] allFiles = folder.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".png"));
}
});
You can convert file path to Uri by Uri.fromFile(YOUR FILE)
Related
I Know this is already answered question.But I'm unable to figure it out when using SQLite DB. My app captures some documents and will be stores in phone memory. I'm using SQLite DB in my app which stores the path of the above image. How can i delete the image from phone memory if i delete the image in SQLite DB.
String photoPath = cursor.getString(i_COL_PICTURE);
--My path is
`"content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F153/ORIGINAL/NONE/1743496576"
`
When you want delete some file in your storage, Just do this.
File file = new File(yourFilePathHere);
deleted = file.delete();
I am considering you have required permissions because you are able to write files in storage.
Edit
You are using MediaStore for getting images. So now when you want delete file you should delete file from MediaStore also. I have a method which will help you.
public static int deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) {
String canonicalPath;
try {
canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
canonicalPath = file.getAbsolutePath();
}
final Uri uri = MediaStore.Files.getContentUri("external");
final int result = contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath});
if (result == 0) {
final String absolutePath = file.getAbsolutePath();
if (!absolutePath.equals(canonicalPath)) {
int deletedRow = contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
return deletedRow;
}
} else return result;
return result;
}
Call it in your Activity like
deleteFileFromMediaStore(getContentResolver(), fileToDelete)
Note Check if you are getting absolute path by MediaStore. Here is my method to get all gallery images if you have problem with your code.
public static ArrayList<ModelBucket> getImageBuckets(Context context) {
ArrayList<ModelBucket> list = new ArrayList<>();
String absolutePathOfImage;
String absoluteFolder;
boolean same_folder = false;
int pos = 0;
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name;
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
cursor = context.getContentResolver().query(uri, projection, null, null, orderBy + " DESC");
if (cursor == null) return null;
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
absoluteFolder = cursor.getString(column_index_folder_name);
Log.d("Column", absolutePathOfImage);
Log.d("Folder", absoluteFolder);
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getFolderName().equals(absoluteFolder)) {
same_folder = true;
pos = i;
break;
} else {
same_folder = false;
}
}
if (same_folder) {
ArrayList<String> al_path = new ArrayList<>(list.get(pos).getAllFilesPath());
al_path.add(absolutePathOfImage);
list.get(pos).setAllFilesPath(al_path);
} else {
ArrayList<String> al_path = new ArrayList<>();
al_path.add(absolutePathOfImage);
ModelBucket modelBucket = new ModelBucket();
modelBucket.setFolderName(absoluteFolder);
modelBucket.setAllFilesPath(al_path);
list.add(modelBucket);
}
}
return list;
}
here ModelBucket.class is a model class.
public class ModelBucket {
String folderName;
ArrayList<String> allFilesPath;
ArrayList<ModelFile> files;
// make getter setter
}
before deleting the image get the path of the image and pass the path to below code
File fdelete = new File(path);
if (fdelete.exists()) {
if (fdelete.delete()) {
System.out.println("file Deleted :" + path);
} else {
System.out.println("file not Deleted :" + path);
}
}
after this remove the path from sqlite db
If you have your Uri pointing to the file you can do :
String pathToFile = myUri.getEncodedPath(); // this gives your the real path to the file, like /emulated/0/sdcard/myImageFile.jpg
File file = new File(pathToFile);
if(file.exists()){
file.delete();
}
I have used following code to get list of directories
String ROOT_DIR = Environment.getExternalStorageDirectory().getPath();
ROOT_DIR is passed is as string
public static ArrayList<String> getDirectoryPaths(String directory) {
ArrayList<String> pathArray = new ArrayList<>();
File file = new File(directory);
File[] listfiles = file.listFiles();
if (listfiles != null) {
for (int i = 0; i < listfiles.length; i++) {
if (listfiles[i].isDirectory()) {
pathArray.add(listfiles[i].getAbsolutePath());
}
}
}
return pathArray;
}
`
It returns all directories path but i want to get the path of the directories containing images only like it shows in gallery Eg (Camera, WhatsAppImages, hike,...); I want to get path of all of them.
Any ideas?
Try this:
Create a Bucket Class
public class Bucket {
private String name;
private String firstImageContainedPath;
public Bucket(String name, String firstImageContainedPath) {
this.name = name;
this.firstImageContainedPath = firstImageContainedPath;
}
public String getName() {
return name;
}
public String getFirstImageContainedPath() {
return firstImageContainedPath;
}
}
Then, Add this method, it is going to return all the buckets where there are Images.
public static List<Bucket> getImageBuckets(Context mContext){
List<Bucket> buckets = new ArrayList<>();
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String [] projection = {MediaStore.Images.Media.BUCKET_DISPLAY_NAME, MediaStore.Images.Media.DATA};
Cursor cursor = mContext.getContentResolver().query(uri, projection, null, null, null);
if(cursor != null){
File file;
while (cursor.moveToNext()){
String bucketPath = cursor.getString(cursor.getColumnIndex(projection[0]));
String fisrtImage = cursor.getString(cursor.getColumnIndex(projection[1]));
file = new File(fisrtImage);
if (file.exists() && !bucketSet.contains(bucketName)) {
buckets.add(new Bucket(bucketName, fisrtImage));
}
}
cursor.close();
}
return buckets;
}
Finally, create your custom spinner item and fill your spinner with an adapter.
Next Step is to fill the gridview with images from the selected bucket.
This method is going to return all the images according the bucketpath.
public List<String> getImagesByBucket(#NonNull String bucketPath){
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String [] projection = {MediaStore.Images.Media.DATA};
String selection = MediaStore.Images.Media.BUCKET_DISPLAY_NAME+" =?";
String orderBy = MediaStore.Images.Media.DATE_ADDED+" DESC";
List<String> images = new ArrayList<>();
Cursor cursor = mContext.getContentResolver().query(uri, projection, selection,new String[]{bucketPath}, orderBy);
if(cursor != null){
File file;
while (cursor.moveToNext()){
String path = cursor.getString(cursor.getColumnIndex(projection[0]));
file = new File(path);
if (file.exists() && !images.contains(path)) {
images.add(path);
}
}
cursor.close();
}
return images;
}
Finally, create your adapter and fill your gridview.
I hope, It can help you.
I want to get the pictures which were taken by only device camera.
Maybe, filepath name have DCIM or other things.
Here is code, is this ok? target API is bitween 15~21API.
/**
* #param context
* #returnArrayList with images Path
*/
public static ArrayList<String> getAllShownImagesPath(Context context) {
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name;
ArrayList<String> listOfAllImages = new ArrayList<String>();
String absolutePathOfImage = null;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
final String DCIMPath = android.os.Environment.DIRECTORY_DCIM;
Log.d(TAG, "DCIMPath #"+DCIMPath);
String[] projection = { MediaStore.MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME };
cursor = context.getContentResolver().query(uri, projection, null, null, null);
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
if(absolutePathOfImage.contains(DCIMPath))
listOfAllImages.add(absolutePathOfImage);
}
String filepath = Environment.getExternalStorageDirectory().toString();
Log.d(TAG, "filepath #" + filepath);
return listOfAllImages;
}
I only tests one device it worked. but android device is so many.
If you want to get the default pictures storage directory on your device, try :
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
I'm trying to get the uri and after parse into path of MediaStore image.
I do this to get the uri:
Uri img_uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
And after with this function i convert uri in the path:
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
But the result is that i have the path of the Media storage but with the first element.
For example: /mnt/sdcard/Pictures/Boat.jpg. But i want only /mnt/sdcard/Pictures/.
Please don't tell me to use join and split because isn't what i want.
Use this:
String path = getExternalFilesDir(null).getAbsolutePath();
to get the main directory in your app subfolder where you can put another directory, for example "Images" in this way:
String path = getExternalFilesDir(null).getAbsolutePath() + "/Images";
File folder = new File(path);
if (!folder.exists()) {
folder.mkdir();
}
So now with this:
String path = getExternalFilesDir(null).getAbsolutePath() + "/Images";
you can access to this folder without problems.
What i'm trying to achieve is getting all the mp3 files'URL and Title in an arraylist to return it. All from the folder: /ext_card/Music/ and all subfolders.
the options i've explored all seem to get stuck, and all the answers i've looked up on the internet point to mediastore, but i have no idea how to use it
And don't give me the RTFM bullshit, because the explanations i've found for mediastore is retarded at best.
SO can anyone please help me out or give me an example of a simple working mediastore query for all mp3 files?
Use this it will help you to get all MP3 Song from SD CARD
private static ArrayList<genericSongClass> songs = null;
public void BindAllSongs() {
/** Making custom drawable */
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
final String[] projection = new String[] {
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DATA};
final String sortOrder = MediaStore.Audio.AudioColumns.TITLE
+ " COLLATE LOCALIZED ASC";
try {
// the uri of the table that we want to query
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
// query the db
cursor = getBaseContext().getContentResolver().query(uri,
projection, selection, null, sortOrder);
if (cursor != null) {
songs = new ArrayList<genericSongClass>(cursor.getCount());
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
GSC = new genericSongClass();
GSC.songTitle = cursor.getString(0);
GSC.songArtist = cursor.getString(1);
GSC.songData = cursor.getString(2);
songs.add(GSC);
cursor.moveToNext();
}
}
} catch (Exception ex) {
} finally {
if (cursor != null) {
cursor.close();
}
}
}
public class genericSongClass {
String songTitle = "";
String songArtist = "";
String songData = "";
String isChecked = "false";
}
Here is a recursive way to do such thing,
getMp3s(Arraylist<File> list, File dir){
File[] files = dir.listFiles();
for(File file : files){
if(file.isDirectory()){
getMp3s(list, file);
}else{
//add mp3s to list here
}
}
}