How to get paths of folders that has image or video - java

I want to create an android gallery app .
How to scan and get paths of folders that includes photos or videos .
I used this code and worked . but when i compare it with Quickpic Gallery in play store , i see the count of folders in my app is less than Quickpic folders
Do you see any problem in this code ?
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = ba.context.getContentResolver().query(uri, null, null,
null, MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME);
if (cursor != null) {
cursor.moveToFirst();
int data = cursor
.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
int displayName = cursor
.getColumnIndex(MediaStore.Images.ImageColumns.DISPLAY_NAME);
imageFolders = new HashMap<>();
do {
String imageAddress = cursor.getString(data);
String imageName = cursor.getString(displayName);
String folderAddress = imageAddress.substring(0,
imageAddress.lastIndexOf(imageName) - 1);
if (!imageFolders.containsKey(folderAddress)) {
imageFolders.put(folderAddress, imageAddress);
}
} while (cursor.moveToNext());
for (String str : imageFolders.keySet()) {
ba.raiseEventFromDifferentThread(
null,
null,
0,
"result",
true,
new Object[] { String.format("%s", str),
String.format("%s", imageFolders.get(str)) });
}
}

this way you can find all video and image parents.
ArrayList<String> allFolder;
HashMap<String, ArrayList<String>> listImageByFolder;
ArrayList<String> allVideoFolder;
HashMap<String, ArrayList<String>> listVideoByFolder;
find all images folder path
private void getImageFolderList() {
String[] projection = new String[] { MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATE_TAKEN };
Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
Cursor cur = getContentResolver().query(images, projection, // Which
// columns
// to return
null, // Which rows to return (all rows)
null, // Selection arguments (none)
orderBy + " DESC" // Ordering
);
ArrayList<String> imagePath;
if (cur.moveToFirst()) {
String bucket, date;
int bucketColumn = cur.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
int dateColumn = cur.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN);
do {
bucket = cur.getString(bucketColumn);
date = cur.getString(dateColumn);
if (!allFolder.contains(bucket)) {
allFolder.add(bucket);
}
imagePath = listImageByFolder.get(bucket);
if (imagePath == null) {
imagePath = new ArrayList<String>();
}
imagePath.add(cur.getString(cur
.getColumnIndex(MediaStore.Images.Media.DATA)));
listImageByFolder.put(bucket, imagePath);
} while (cur.moveToNext());
}
}
find all videos folder path
private void getVideoFolderList() {
String[] projection = new String[] { MediaStore.Video.Media.DATA,
MediaStore.Video.Media._ID,
MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
MediaStore.Video.Media.DATE_TAKEN };
Uri images = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
final String orderBy = MediaStore.Video.Media.DATE_TAKEN;
Cursor cur = getContentResolver().query(images, projection, // Which
// columns
// to return
null, // Which rows to return (all rows)
null, // Selection arguments (none)
orderBy + " DESC" // Ordering
);
ArrayList<String> imagePath;
if (cur.moveToFirst()) {
String bucket, date;
int bucketColumn = cur.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME);
int dateColumn = cur.getColumnIndex(MediaStore.Video.Media.DATE_TAKEN);
do {
bucket = cur.getString(bucketColumn);
date = cur.getString(dateColumn);
if (!allVideoFolder.contains(bucket)) {
allVideoFolder.add(bucket);
}
imagePath = listVideoByFolder.get(bucket);
if (imagePath == null) {
imagePath = new ArrayList<String>();
}
imagePath.add(cur.getString(cur
.getColumnIndex(MediaStore.Images.Media.DATA)));
listVideoByFolder.put(bucket, imagePath);
} while (cur.moveToNext());
}
}

i can see you are trying to get the folder names of all folders containing video files the answer given by #prakash ubhadiya is good an works but for the problem that if the are many of such folders with same name the function will keep only one and ignore the rest, below i have modified his fuction to return not only the folder names but also the folder absolute path in case you will want to use this to get all the video files in that specific folder, i have created a class called floderFacer the holds the folder name and the folder adsolute path, done this way no folders with same names will be ignored below is the class
public class folderFacer {
private String path;
private String folderName;
public folderFacer(){
}
public folderFacer(String path, String folderName) {
this.path = path;
this.folderName = folderName;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getFolderName() {
return folderName;
}
public void setFolderName(String folderName) {
this.folderName = folderName;
}
}
now below is the modified fuction that will return the folder names and paths in a folderFacer object all in an ArrayList<folderFacer>
private ArrayList<folderFacer> getVideoPaths(){
ArrayList<folderFacer> videoFolders = new ArrayList<>();
ArrayList<String> videoPaths = new ArrayList<>();
Uri allVideosuri = android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Video.VideoColumns.DATA ,MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.BUCKET_DISPLAY_NAME,MediaStore.Video.Media.BUCKET_ID};
Cursor cursor = getContentResolver().query(allVideosuri, projection, null, null, null);
try {
cursor.moveToFirst();
do{
folderFacer folds = new folderFacer();
String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));
String folder = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.BUCKET_DISPLAY_NAME));
String datapath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
String folderpaths = datapath.replace(name,"");
if (!videoPaths.contains(folderpaths)) {
videoPaths.add(folderpaths);
folds.setPath(folderpaths);
folds.setFolderName(folder);
videoFolders.add(folds);
}
}while(cursor.moveToNext());
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
for(int i = 0;i < videoFolders.size();i++){
Log.d("video folders",videoFolders.get(i).getFolderName()+" and path = "+videoFolders.get(i).getPath());
}
return videoFolders;
}
hope this helps

Related

How to solve 'Cannot retrieve length of file, path (OS Error: No such file or directory, errno = 2) ' in flutter

I am building a simple music player app in which I want to fetch all songs available on the users device. I am doing this with my custom method in java
private static List<Map<String, String>> getAllSongs(Context context) {
List<Map<String, String>> songs = new ArrayList<>();
// Set up query to get all audio files
String[] projection = new String[] {
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.ALBUM_ID
};
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
// Execute query
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
null,
sortOrder
);
// Extract metadata from query result
if (cursor != null && cursor.moveToFirst()) {
int idColumnIndex = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
int titleColumnIndex = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int artistColumnIndex = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
int albumColumnIndex = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM);
int durationColumnIndex = cursor.getColumnIndex(MediaStore.Audio.Media.DURATION);
int pathColumnIndex = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
int albumIdColumnIndex = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID);
do {
Map<String, String> song = new HashMap<>();
song.put("id", cursor.getString(idColumnIndex));
song.put("title", cursor.getString(titleColumnIndex));
song.put("artist", cursor.getString(artistColumnIndex));
song.put("album", cursor.getString(albumColumnIndex));
song.put("duration", cursor.getString(durationColumnIndex));
song.put("path", cursor.getString(pathColumnIndex));
long albumId = cursor.getLong(albumIdColumnIndex);
Uri albumArtUri = Uri.withAppendedPath(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, Long.toString(albumId));
song.put("albumArt", albumArtUri.toString());
songs.add(song);
} while (cursor.moveToNext());
cursor.close();
}
return songs;
}
This is then handled in flutter by ->
class Song {
String id;
String title;
String artist;
String album;
String path;
String albumArt;
Song(
{required this.id,
required this.title,
required this.artist,
required this.album,
required this.path,
required this.albumArt});
}
class MusicService {
static const MethodChannel _channel = const MethodChannel('com.mybea.ah');
static Future<List<Song>> getAllSongs() async {
List<Song> songs = [];
try {
final List<dynamic> result = await _channel.invokeMethod('getAllSongs');
if (result.isNotEmpty) {
for (int i = 0; i < result.length; i++) {
songs.add(Song(
id: result[i]['id'],
title: result[i]['title'],
artist: result[i]['artist'],
album: result[i]['album'],
path: result[i]['path'],
albumArt: result[i]['albumArt'],
));
}
}
} on PlatformException catch (e) {
print("Failed to get all songs: '${e.message}'.");
}
return songs;
}
}
When I fetch the songs from the method all is fetched properly but when I try to display the artwork I get the following error->
════════ Exception caught by image resource service
════════════════════════════ Cannot retrieve length of file, path =
'content://media/external/audio/albums/89' (OS Error: No such file or
directory, errno = 2)
This is the code where I try to use the method ->
Future<void> _loadSongs() async {
if (await Permission.storage.request().isGranted) {
List<Song> songs = await MusicService.getAllSongs();
setState(() {
_songs = songs;
} else {
return;
}
}
_songs.length == 0
? Center(
child: Text("No Songs Found"),
)
: ListView.builder(
itemCount: _songs.length,
itemBuilder: (context, index) {
Song song = _songs[index];
return ListTile(
onTap: () {
debugPrint(song.path);
},
leading: CircleAvatar(
backgroundImage: FileImage(File(song.albumArt)),
),
title: Text(song.title),
subtitle: Text(song.artist),
trailing: Icon(Icons.play_arrow),
);
},
),
I tried displaying the image by Image.file() and Image.network() but nothing seemed to work and gave the same error.
Please Help

How to fetch all pdf file from all directories in my Android app

I want to know how to fetch all PDF files from internal storage. Files can be in any directory, like some in DCIM folders or some in Downloads folder, and so on and so forth.
Note: I am using Android Studio (language: Java).
i have search almost all the ans but it was not working in Android 11. so i have a short solution for picking up all file for example image, video, pdf, doc, audio etc. there was a github library which was recently created
Click [here] https://github.com/HBiSoft/PickiT
and if you want to do all this without dependency
Code Below
do it in orderwise
var mimeTypes = arrayOf(
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", // .doc & .docx
"application/vnd.ms-powerpoint",
"application/vnd.openxmlformats-officedocument.presentationml.presentation", // .ppt & .pptx
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // .xls & .xlsx
"application/pdf"
)
findViewById<Button>(R.id.btnclick).setOnClickListener {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*"
putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
// mimeTypes = mimeTypes
}
startActivityForResult(intent, 100)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
Log.e(">>>>>>", "check")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
getFile(this,intentToDocumentFiles(data)[0])
}
}
private fun intentToDocumentFiles(intent: Intent?): List<DocumentFile> {
val uris = intent?.clipData?.run {
val list = mutableListOf<Uri>()
for (i in 0 until itemCount) {
list.add(getItemAt(i).uri)
}
list.takeIf { it.isNotEmpty() }
} ?: listOf(intent?.data ?: return emptyList())
return uris.mapNotNull { uri ->
if (uri.isDownloadsDocument && Build.VERSION.SDK_INT < 28 && uri.path?.startsWith("/document/raw:") == true) {
val fullPath = uri.path.orEmpty().substringAfterLast("/document/raw:")
DocumentFile.fromFile(File(fullPath))
} else {
fromSingleUri(uri)
}
}.filter { it.isFile }
}
#RequiresApi(Build.VERSION_CODES.R)
fun getFile(context: Context, document: DocumentFile): File? {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
return null
}
try {
val volumeList: List<StorageVolume> = context
.getSystemService(StorageManager::class.java)
.getStorageVolumes()
if (volumeList == null || volumeList.isEmpty()) {
return null
}
// There must be a better way to get the document segment
val documentId = DocumentsContract.getDocumentId(document.uri)
val documentSegment = documentId.substring(documentId.lastIndexOf(':') + 1)
for (volume in volumeList) {
val volumePath: String
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
val class_StorageVolume = Class.forName("android.os.storage.StorageVolume")
val method_getPath: Method = class_StorageVolume.getDeclaredMethod("getPath")
volumePath=method_getPath.invoke(volume).toString()
} else {
// API 30
volumePath=volume.directory!!.path
}
val storageFile = File(volumePath + File.separator + documentSegment)
// Should improve with other checks, because there is the
// remote possibility that a copy could exist in a different
// volume (SD-card) under a matching path structure and even
// same file name, (maybe a user's backup in the SD-card).
// Checking for the volume Uuid could be an option but
// as per the documentation the Uuid can be empty.
val isTarget = (storageFile.exists()
&& storageFile.lastModified() == document.lastModified()
&& storageFile.length() == document.length())
if (isTarget) {
Log.e(">>>>>>>",storageFile.absolutePath)
return storageFile
}
}
} catch (e: Exception) {
e.printStackTrace()
}
Log.e(">>>>>>>","null")
return null
}
You can use MediaStore to fetch all PDF Files ,this is an example how to get all your PDF files :
protected ArrayList<String> getPdfList() {
ArrayList<String> pdfList = new ArrayList<>();
Uri collection;
final String[] projection = new String[]{
MediaStore.Files.FileColumns.DISPLAY_NAME,
MediaStore.Files.FileColumns.DATE_ADDED,
MediaStore.Files.FileColumns.DATA,
MediaStore.Files.FileColumns.MIME_TYPE,
};
final String sortOrder = MediaStore.Files.FileColumns.DATE_ADDED + " DESC";
final String selection = MediaStore.Files.FileColumns.MIME_TYPE + " = ?";
final String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf");
final String[] selectionArgs = new String[]{mimeType};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
collection = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL);
}else{
collection = MediaStore.Files.getContentUri("external");
}
try (Cursor cursor = getContentResolver().query(collection, projection, selection, selectionArgs, sortOrder)) {
assert cursor != null;
if (cursor.moveToFirst()) {
int columnData = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);
int columnName = cursor.getColumnIndex(MediaStore.Files.FileColumns.DISPLAY_NAME);
do {
pdfList.add((cursor.getString(columnData)));
Log.d(TAG, "getPdf: " + cursor.getString(columnData));
//you can get your pdf files
} while (cursor.moveToNext());
}
}
return pdfList;
}
This is improvised answer of #Shay Kin.
As we know in latest android versions we have many restrictions to access files in external storage.
MediaStore api and Storage Access Framework apis provides access to shared files. This is explained clearly in this video.
Coming to the answer, in Shay Kin's answer we can able to fetch all pdf files which are there in the shared files but ignores downloads.
Permissions required
READ_EXTERNAL_STORAGE
if api is Q plus you also need MANAGE_EXTERNAL_STORAGE
please find the below code to fetch all pdf files.
protected List<String> getPdfList() {
List<String> pdfList = new ArrayList<>();
final String[] projection = new String[]{
MediaStore.Files.FileColumns.DISPLAY_NAME,
MediaStore.Files.FileColumns.DATE_ADDED,
MediaStore.Files.FileColumns.DATA,
MediaStore.Files.FileColumns.MIME_TYPE,
};
final String sortOrder = MediaStore.Files.FileColumns.DATE_ADDED + " DESC";
final String selection = MediaStore.Files.FileColumns.MIME_TYPE + " = ?";
final String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf");
final String[] selectionArgs = new String[]{mimeType};
Uri collection = MediaStore.Files.getContentUri("external");
pdfList.addAll(getPdfList(collection, projection, selection, selectionArgs, sortOrder));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
collection = MediaStore.Downloads.getContentUri("external");
pdfList.addAll(getPdfList(collection,projection, selection, selectionArgs, sortOrder));
}
return pdfList;
}
private List<String> getPdfList(Uri collection, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
List<String> pdfList = new ArrayList<>();
try (Cursor cursor = getContentResolver().query(collection, projection, selection, selectionArgs, sortOrder)) {
assert cursor != null;
if (cursor.moveToFirst()) {
int columnData = cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA);
do {
pdfList.add((cursor.getString(columnData)));
Log.d(TAG, "getPdf: " + cursor.getString(columnData));
//you can get your pdf files
} while (cursor.moveToNext());
}
}
return pdfList;
}
Hope this works.

Having issue with file path

I am successfully able to select file programmatically. But, when I am getting uri from that file
content://com.android.providers.downloads.documents/document/3356
content://com.android.providers.downloads.documents/document/3331
Unfortunately, wherever the file is my uri is always locating at downloads.documents
I think it doesn't fact. Cause, everyone get the uri by data.getData(). So, I think the uri is correct.
Last year, I was working with Audio, Video, File and Image uploading to server. I was trying that source code to get path.
String mediaPath, mediaPath1;
String[] mediaColumns = {MediaStore.Video.Media._ID};
// Get the file from data
String path = data.getStringExtra(mediaPath);
File file = new File(path);
Uri selectedFile = Uri.fromFile(new File(file.getAbsolutePath()));
String[] filePathColumn = {MediaStore.Files.FileColumns.MEDIA_TYPE};
Cursor cursor = getContentResolver().query(selectedFile, filePathColumn, null, null, null);
assert cursor != null;
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
mediaPath = cursor.getString(columnIndex);
txt.setText(path);
// Set the Image in ImageView for Previewing the Media
cursor.close();
Unfortunately,That is returning null pointerexception. After researching little bit, I found another source code(PathUtils)
public class PathUtils {
public static String getPath(final Context context, final Uri uri) {
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
if (isExternalStorageDocument(uri)) {// ExternalStorageProvider
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
String storageDefinition;
if("primary".equalsIgnoreCase(type)){
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else {
if(Environment.isExternalStorageRemovable()){
storageDefinition = "EXTERNAL_STORAGE";
} else{
storageDefinition = "SECONDARY_STORAGE";
}
return System.getenv(storageDefinition) + "/" + split[1];
}
} else if (isDownloadsDocument(uri)) {// DownloadsProvider
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
} else if (isMediaDocument(uri)) {// MediaProvider
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {// MediaStore (and general)
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {// File
return uri.getPath();
}
return null;
}
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
}
I am not getting any error. But, Path is always locating at Downloads file. I don't know why. After looking at uri I noticed my uri is always returning downloads.documents. I am not sure is it the issue.
There is lot of question similar to this question in stackoverflow. To tell everyone none worked for me. So, I will request to not flag it.
PATH: /storage/emulated/0/Download/The Road to Reality ( PDFDrive ).pdf
PATH: /storage/emulated/0/Download/The order of time ( PDFDrive ).pdf
PATH: /storage/emulated/0/Download/pdf_495.pdf
First pdf file is in documents file. Second pdf file is in Download third pdf file is in /storage/emulated/0/
I am parsing pdf texts. Here is my code
try {
String parsedText="";
StringBuilder builder = new StringBuilder();
//Here you can see I need path to load the pdf file
PdfReader reader = new PdfReader(PathUtils.getPathFromUri(getApplicationContext(),PathHolder));
int n = reader.getNumberOfPages();
for (int i = 10; i <n ; i++) {
parsedText = parsedText+ PdfTextExtractor.getTextFromPage(reader, i).trim()+"\n";
Log.d("for_loop", String.valueOf(i));
Log.d("PARSED_TEXT",parsedText+" ");
}
builder.append(parsedText);
reader.close();
runOnUiThread(() -> {
txt.setText(builder.toString());
});
// System.out.println("TEXT FROM PDF : "+builder.toString());
} catch (Exception e) {
System.out.println(e);
}
As you can see I need path to load the pdf file. But, I have already told you I am having issue with path. So, if I wanna do something with uri than how can i do that cause, path required.
I tried another way to get the path also.
Uri PathHolder = data.getData();
Cursor cursor = null;
try {
cursor = this.getContentResolver().query(PathHolder, new String[]{MediaStore.Files.FileColumns.DATA}, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
String fileName = cursor.getString(0);
String path = Environment.getExternalStorageDirectory().toString()+"/" + fileName;
Log.d("PATH",path);
if (!TextUtils.isEmpty(path)) {
}else{
Toast.makeText(this, "null return", Toast.LENGTH_SHORT).show();
}
}
}catch (Exception e){
e.printStackTrace();
Log.d("EXCEPTION_ERROR",e.toString());
} finally {
if (cursor != null)
cursor.close();
}
Unfortunately, It's not working also.
Like we do for audio, images or, videos.
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Audio.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
assert cursor != null;
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
mediaPath = cursor.getString(columnIndex);
str1.setText(mediaPath);
// Set the Image in ImageView for Previewing the Media
imgView.setImageBitmap(BitmapFactory.decodeFile(mediaPath));
cursor.close();
Edited :
Uri uri = data.getData();
try{
InputStream in = getContentResolver().openInputStream(uri);
BufferedReader r = new BufferedReader(new InputStreamReader(in));
StringBuilder total = new StringBuilder();
for (String line; (line = r.readLine()) != null; ) {
total.append(line).append('\n');
}
String content = total.toString();
Log.d("CONTENT",content);
}catch (Exception e){
e.printStackTrace();
}
The problem I am facing here is.
As you can see the catch is returning no such file or directory found. I am not sure what I am doing wrong here. Cause, I took the source code from somewhere else and it is first time I am working with InputStream. And, I think the problem is on I am unable to get the file by uri.
Catch exception is returning
no such file or directory
Edited :
Uri uri = data.getData();
File file=new File(uri.toString());
InputStream inputStream = getContentResolver().openInputStream(uri);
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len=inputStream.read(buf))>0){
out.write(buf,0,len);
}
out.close();
inputStream.close();
Starting from Android 10 using Scoped Storage is required. You cannot get absolute path of the file and work with file APIs with external Storage. MediaStore.Audio.Media.DATA that is used to take absolute path is depracated. But with uri returned you can copy that file using inputStream to your app-specific directory and do what you want with that file. For more information please refer to this article.
For reading pdf as I said you can copy that file to your app-specific directory or use that uri like this sample.
Copying file from uri in kotlin:
val uri: Uri = data?.data ?: return
val ins = context?.contentResolver?.openInputStream(uri)
val file = File(context?.filesDir, "image.jpg")
val fileOutputStream = FileOutputStream(file)
ins?.copyTo(fileOutputStream)
ins?.close()
fileOutputStream.close()
val absolutePath = file.absolutePath
Log.d("AAA", absolutePath)
If you use java there is no copyTo function so use this function then you can use the file in Files directory in app-specific storage
private void copyInputStreamToFile( InputStream in, File file ) {
try {
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}}
Copied file in app-specific directory
This is log:
D/AAA: /data/user/0/com.example.pickerapp/files/image.jpg

get mp3 files from path

I'm trying to get mp3 files from a folder path of my system to list it in my listView, but unfortunately there's always the same error. (java.lang.NullPointerException: Attempt to get length of null array)
class Mp3Filter implements FilenameFilter{
public boolean accept(File dir, String name){
return (name.endsWith(".mp3"));
}
}
private static final String SD_PATH = new String(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).toString());
public void searchForSongs() {
ListView listView;
listView = (ListView) findViewById(R.id.listView);
File f = new File(SD_PATH);
try {
if (f.listFiles(new Mp3Filter()).length > 0){
for (File file : f.listFiles(new Mp3Filter())){
list.add(file.getName());
}
}
}
catch(Exception e) {
textView2.setText(""+e);
return;
}
final ArrayAdapter songList = new ArrayAdapter(this, android.R.layout.simple_list_item_1, list);
listView.setAdapter(songList);
}
Here is your solution use the following code to Read the MP3 file from the Specific Folder..
First of all Create 1 Model class as Given Below, to GET and SET Files in list.
AudioModel.class
public class AudioModel {
String aPath;
String aName;
String aAlbum;
String aArtist;
public String getaPath() {
return aPath;
}
public void setaPath(String aPath) {
this.aPath = aPath;
}
public String getaName() {
return aName;
}
public void setaName(String aName) {
this.aName = aName;
}
public String getaAlbum() {
return aAlbum;
}
public void setaAlbum(String aAlbum) {
this.aAlbum = aAlbum;
}
public String getaArtist() {
return aArtist;
}
public void setaArtist(String aArtist) {
this.aArtist = aArtist;
}
}
Now We have our Model Class Now use the below code to Read the all MP3 files from your Folder.
This will return list of all MP3 Files with Music NAME, PATH, ARTIST, ALBUM and if you wants more detail please refer Media.Store.Audio doc..
https://developer.android.com/reference/android/provider/MediaStore.Audio.html
public List<AudioModel> getAllAudioFromDevice(final Context context) {
final List<AudioModel> tempAudioList = new ArrayList<>();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Audio.AudioColumns.DATA, MediaStore.Audio.AudioColumns.ALBUM, MediaStore.Audio.ArtistColumns.ARTIST,};
Cursor c = context.getContentResolver().query(uri, projection, MediaStore.Audio.Media.DATA + " like ? ", new String[]{"%yourFolderName%"}, null);
if (c != null) {
while (c.moveToNext()) {
AudioModel audioModel = new AudioModel();
String path = c.getString(0);
String album = c.getString(1);
String artist = c.getString(2);
String name = path.substring(path.lastIndexOf("/") + 1);
audioModel.setaName(name);
audioModel.setaAlbum(album);
audioModel.setaArtist(artist);
audioModel.setaPath(path);
Log.e("Name :" + name, " Album :" + album);
Log.e("Path :" + path, " Artist :" + artist);
tempAudioList.add(audioModel);
}
c.close();
}
return tempAudioList;
}
To Read Files of Specific Folder, use below Query and write your folder name in Query..
Cursor c = context.getContentResolver().query(uri,
projection,
MediaStore.Audio.Media.DATA + " like ? ",
new String[]{"%yourFolderName%"}, // yourFolderName
null);
If you wants All Files of device use below Query..
Cursor c = context.getContentResolver().query(uri,
projection,
null,
null,
null);
Don't forget to add Storage Permission .. enjoy.

List all music in MediaStore with the PATHs

Ok so I've been working on this project for a few days now and most of my time has been working out how to list all the music on a device in a LIST VIEW or something else, I have searched for a few days now and this is killing me. I did get so close at one point with all the music in one folder showing, though since most people will have sub folders for things like artiest and albums I need a way to search sub folders for MP3s or music files.
Here is what I have so far for Music collection:
package com.androidhive.musicplayer;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.HashMap;
import android.provider.MediaStore;
public class SongsManager {
// SDCard Path
final String MEDIA_PATH = new String(MediaStore.Audio.Media.getContentUri("external").toString());
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
// Constructor
public SongsManager(){
}
/**
* Function to read all mp3 files from sdcard
* and store the details in ArrayList
* */
public ArrayList<HashMap<String, String>> getPlayList(){
File home = new File(MEDIA_PATH);
if (home.listFiles(new FileExtensionFilter()).length > 0) {
for (File file : home.listFiles(new FileExtensionFilter())) {
HashMap<String, String> song = new HashMap<String, String>();
song.put("songTitle", file.getName().substring(0, (file.getName().length() - 4)));
song.put("songPath", file.getPath());
// Adding each song to SongList
songsList.add(song);
}
}
// return songs list array
return songsList;
}
/**
* Class to filter files which are having .mp3 extension
* */
class FileExtensionFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return (name.endsWith(".mp3") || name.endsWith(".MP3"));
}
}
}
Thanks to anyone who can help. :)
Although, the post is old, for other people like me to get the idea of creating a list of music with their file path, I added the solution here. MediaStore.Audio.Media.DATA column actually contains media file path. You can get necessary information by using the following snippet:
ContentResolver cr = getActivity().getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
Cursor cur = cr.query(uri, null, selection, null, sortOrder);
int count = 0;
if(cur != null)
{
count = cur.getCount();
if(count > 0)
{
while(cur.moveToNext())
{
String data = cur.getString(cur.getColumnIndex(MediaStore.Audio.Media.DATA));
// Add code to get more column here
// Save to your list here
}
}
cur.close();
}
You can list all the music files using this code
//Some audio may be explicitly marked as not being music
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
String[] projection = {
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION
};
cursor = this.managedQuery(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
null,
null);
private List<String> songs = new ArrayList<String>();
while(cursor.moveToNext()) {
songs.add(cursor.getString(0) + "||"
+ cursor.getString(1) + "||"
+ cursor.getString(2) + "||"
+ cursor.getString(3) + "||"
+ cursor.getString(4) + "||"
+ cursor.getString(5));
}
I have not tried this code, but it seems correct. You'll be on the right track with that.
I'm working on same project right now and already solved the problem.
You will need a custom class to store your songs data:
package YOUR_PACKAGE;
public class Songs
{
private long mSongID;
private String mSongTitle;
public Songs(long id, String title){
mSongID = id;
mSongTitle = title;
}
public long getSongID(){
return mSongID;
}
public String getSongTitle(){
return mSongTitle;
}
}
Then you have to define ArrayList in activity with List View which you will populate with data:
private ArrayList<Songs> arrayList;
and in onCreate:
arrayList = new ArrayList<Songs>();
Then you have to retrieve data from your device:
public void YOUR_METHOD_NAME(){
ContentResolver contentResolver = getContentResolver();
Uri songUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor songCursor = contentResolver.query(songUri, null, null, null, null);
if(songCursor != null && songCursor.moveToFirst())
{
int songId = songCursor.getColumnIndex(MediaStore.Audio.Media._ID);
int songTitle = songCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
do {
long currentId = songCursor.getLong(songId);
String currentTitle = songCursor.getString(songTitle);
arrayList.add(new Songs(currentId, currentTitle, currentArtist));
} while(songCursor.moveToNext());
}
}
Then call this method from onCreate:
YOUR_METHOD_NAME();
And finally you have to create custom adapter class, define this adapter in onCreate (in activity with ListView) and set this adapter on your ListView object.
I see that it was asked 3 years ago and the problem I think already solved, but maybe it will be usefull for someone. Thanks.
Here is a simple function who gives you all audio files in File Object.
public static List<File> getAllAudios(Context c) {
List<File> files = new ArrayList<>();
String[] projection = { MediaStore.Audio.AudioColumns.DATA ,MediaStore.Audio.Media.DISPLAY_NAME};
Cursor cursor = c.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
try {
cursor.moveToFirst();
do{
files.add((new File(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)))));
}while(cursor.moveToNext());
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
return files;
}

Categories

Resources