I am trying to build a Pdf Scanner Android application for api level 21 and above, in the app I have an option to show and manage all the pdf files created by the application through the application.
I want to fetch Pdf files from Documents/PDFScanner folder and show them in a fragment. So far I am getting empty array but I have Pdf files in the folder.
I have tested the code on Android 11 and Android 8.1 devices.
here is my function to get pdf files
private void getPDFFilesFromDirecotry() {
Uri collection = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
collection = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
} else {
collection = MediaStore.Files.getContentUri("external");
}
String[] projection = {MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DISPLAY_NAME};
Cursor mediaCursor = applicationContext.getContentResolver().query(collection,
projection,
MediaStore.MediaColumns.DATA + " LIKE?",
new String[]{Environment.DIRECTORY_DOCUMENTS + "/PDFScanner"},
null);
Log.e("TAG", "Message: " + mediaCursor.getCount());
if (mediaCursor == null || mediaCursor.getCount() <= 0 || !mediaCursor.moveToFirst()) {
Log.e("tag","No data");
return;
}
String mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf");
MediaScannerConnection.scanFile(applicationContext, new String[]{file.getPath()}, new String[]{mimetype}, null);
while (mediaCursor.moveToNext()) {
Log.e("TAG", "Message: ");
String path = mediaCursor.getString(mediaCursor.getColumnIndex(MediaStore.MediaColumns.BUCKET_DISPLAY_NAME));
Log.e("TAG", "getPDFFilesFromDirectory Path: " + path);
if (path != null) {
ivNoData.setVisibility(View.GONE);
file = new File(path);
String name = file.getName();
int position = name.lastIndexOf(".");
if (position > 0 && position < name.length() - 1) {
name = name.substring(0, position);
}
Date dateinMillis = new Date(file.lastModified());
#SuppressLint("SimpleDateFormat")
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yy hh.mm a");
String date = dateFormat.format(dateinMillis);
String size = formatSize(file.length());
viewFilesArray.add(new ViewFilesModel(path, name, size, date));
}
}
mediaCursor.close();
Log.e("TAG", "getPDFFilesFromDirectory: " + viewFilesArray.size());
filesAdapter.notifyDataSetChanged();
}
Thanks for the help.
Related
How can I access all audio files from my storage internal as well as external in android studio and how can I get recent audio files on top of my recyclerview?
public ArrayList<ModelClass> getData() {
ModelClass f;
String targetpath = Environment.getExternalStorageDirectory().getPath() + "/" ;
File targetdir = new File(targetpath);
files = targetdir.listFiles();
if (files.length != 0) {
for (int i = files.length -1 ; i > -1; i--) {
File file = files[i];
f = new ModelClass();
f.setUri(Uri.fromFile(file));
f.setPath(files[i].getAbsolutePath());
f.setDate((file.lastModified()));
f.setFilename(file.getName());
if (!f.getUri().toString().endsWith(".nomedia")) {
fileslist.add(f);
}
}
} else {
Toast.makeText(this, "Make dummy call", Toast.LENGTH_SHORT).show();
dummyCallAlert();
}
return fileslist;
}
image given below
So i have this code for getting images with mediastore :
int dataIndex = mMediaStoreCursor.getColumnIndex(MediaStore.Files.FileColumns.DATA );
mMediaStoreCursor.moveToPosition(position);
String dataString = mMediaStoreCursor.getString(dataIndex);
Uri mediaUri = Uri.parse("file://" + dataString);
return mediaUri;
This good gets all the images in the pictures folder, i would like to change that to get all the images in a specific folder, which will be passed in as a string. e.g { android/picture/specificfolder/}
val DIRECTORY_NAME = "%your_folder_name%"
val selection = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
MediaStore.MediaColumns.RELATIVE_PATH + " like ? "
else MediaStore.Images.Media.DATA + " like ? "
val selectionArgs = arrayOf(APP_RESOURCE_DIRECTORY_NAME)
val cursor = context.contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null,
selection,
selectionArgs,
null)
Check this post
It advice you to use cursor and pass the folder needed in the projection.
the relevant answer from teh post:
mediaCursor = getContentResolver().query( MediaStore.Files.getContentUri("external"),
null,
MediaStore.Images.Media.DATA + " like ? ",
new String[] {"%YOUR_FOLDER_NAME%"},
null);
You can use following method -
public List<String> getFromSdcard()
{
ArrayList<String> imagePaths = new ArrayList<String>();// list of file paths
File[] listFile;
File file= new
File(android.os.Environment.getExternalStorageDirectory(),"android/picture/specificfolder/");
if (file.isDirectory())
{
listFile = file.listFiles();
for (int i = 0; i < listFile.length; i++)
{
imagePaths.add(listFile[i].getAbsolutePath());
}
}
return imagePaths;
}
to retreive the images use
List<String> sample = getFromSdcard();
for(int i=0; i<sample.size() ; i++){
final Uri image = Uri.parse("file://"+sample(i).toString());
}
I am trying to get a list of all Folders that contain MP3 Files on the user's Internal Storage.
Here is the recursive function that I am calling for this purpose -
public void listAllMusicFiles(String pathToDirectory) {
String lastFolderPath = "";
int mp3Count = 0;
File f = new File(pathToDirectory);
File[] files = f.listFiles();
for (File inFile : files) {
if (inFile.isDirectory()) {
//reset last folder path
lastFolderPath = "";
Log.d("Directory ", inFile.getPath());
listAllMusicFiles(inFile.getPath());
} else {
if (inFile.getAbsolutePath().endsWith(".mp3") || inFile.getAbsolutePath().endsWith(".MP3")) {
mp3Count++;
Log.wtf("MP3 Count", mp3Count + " ");
//add each folder only once
String folderName = inFile.getParentFile().getName();
String folderPath = inFile.getParentFile().getPath();
Log.e("FOUND in", folderPath);
//create a new Folder object
Folder currentFolder = new Folder(folderName, folderPath, mp3Count + "");
if (!lastFolderPath.equals(folderPath)) {
Log.d("NEW", folderPath);
lastFolderPath = folderPath;
folderArrayList.add(currentFolder);
} else {
Log.d("OLD", folderPath);
//find a Folder object in folderArrayList where the object's path matches current folderPath
for (Folder folder : folderArrayList) {
String currentPath = folder.getFolder_Path();
if (currentPath.equals(folderPath)) {
//found a match
//update count
folder.setFolder_Song_Count(mp3Count + "");
}
}
}
}
}
}
}
When I run this code on my device, I am able to list the required folders in a RecyclerView, but with a delay of about 6-7 seconds.
I have already moved this task into an AsyncTask, so that my UIThread does not hang because of this intensive operation.
But I am totally at a loss when it comes to improving File System Performance. Kindly help. Thanks !
Instead of storing currentFolder in an ArrayList and in the next step iterating through complete list to find that folder and updating the value, you can simply use HashMap like this
HashMap<String, Folder> folders = new HashMap<>();
public void listAllMusicFiles(String pathToDirectory) {
int mp3Count = 0;
File f = new File(pathToDirectory);
File[] files = f.listFiles();
Folder folder;
String folderName, folderPath;
for (File inFile : files) {
if (inFile.isDirectory()) {
//reset last folder path
Log.d("Directory ", inFile.getPath());
listAllMusicFiles(inFile.getPath());
} else {
if (inFile.getAbsolutePath().endsWith(".mp3") || inFile.getAbsolutePath().endsWith(".MP3")) {
mp3Count++;
Log.wtf("MP3 Count", mp3Count + " ");
//add each folder only once
folderName = inFile.getParentFile().getName();
folderPath = inFile.getParentFile().getPath();
Log.e("FOUND in", folderPath);
if (folders.containsKey(folderPath)) {
folder = folders.get(folderPath);
folder.setFolder_Song_Count(mp3Count + "");
folders.put(folderPath, folder);
} else {
folder = new Folder(folderName, folderPath, mp3Count + "");
folders.put(folderPath, folder);
}
}
}
}
}
I'm developing a music player. I want to get all .mp3 format files from android device.
But this code is not getting any files. My .mp3 files are in 'sdcard/music' folder. If i change the MEDIA_PATH = new String("sdcard/music"); like this it's getting files only from that music folder. But i need to get all .mp3 files from each and every folder in my external/internal memorycard. Please help me.
this is my code.
final String MEDIA_PATH = new String(Environment.getExternalStorageDirectory());
public void Generate_Database(){
File home = new File(MEDIA_PATH);
if (home.listFiles(new FileExtensionFilter()).length > 0) {
for (File file : home.listFiles(new FileExtensionFilter())) {
String title = file.getName().substring(0, (file.getName().length() - 4));
String path = file.getPath();
mediaInfo.setDataSource(path);
String albumName = "unknown",artist = "unknown",genere = "unknown",duration = "unknown",composer = "unknown";
if(mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM) == null)
albumName = "unknown";
else{
albumName = mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM);
}
if(mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST) == null)
artist = "unknown";
else{
artist = mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
}
if(mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE) == null)
genere = "unknown";
else{
genere = mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE);
}
if(mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) == null)
duration = "unknown";
else{
duration = mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
}
if(mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_COMPOSER) == null)
composer = "unknown";
else{
composer = mediaInfo.extractMetadata(MediaMetadataRetriever.METADATA_KEY_COMPOSER);
}
//Toast.makeText(getApplicationContext(), title+path+ albumName+artist+ genere+ duration+ composer, Toast.LENGTH_LONG).show();
ds.createEntry2(title, path, albumName, artist, genere, duration, composer);
}
}
this is used to extract the .mp3 files
class FileExtensionFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return (name.endsWith(".mp3") || name.endsWith(".MP3"));
}
}
Query the media files
Check if the file is an mp3 by checking its extension
The following method will return all the mp3 audio files in your device:
private List<String> scanDeviceForMp3Files(){
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
String[] projection = {
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION
};
final String sortOrder = MediaStore.Audio.AudioColumns.TITLE + " COLLATE LOCALIZED ASC";
List<String> mp3Files = new ArrayList<>();
Cursor cursor = null;
try {
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
cursor = getContentResolver().query(uri, projection, selection, null, sortOrder);
if( cursor != null){
cursor.moveToFirst();
while( !cursor.isAfterLast() ){
String title = cursor.getString(0);
String artist = cursor.getString(1);
String path = cursor.getString(2);
String displayName = cursor.getString(3);
String songDuration = cursor.getString(4);
cursor.moveToNext();
if(path != null && path.endsWith(".mp3")) {
mp3Files.add(path);
}
}
}
// print to see list of mp3 files
for( String file : mp3Files) {
Log.i("TAG", file);
}
} catch (Exception e) {
Log.e("TAG", e.toString());
}finally{
if( cursor != null){
cursor.close();
}
}
return mp3Files;
}
I creating apps with camera function, I call camera with intent snap the shot and saving files in external storage "download" folder, but then I search them they are in another folder "/storage/emulated/0/download/".
Why android needs 2 directors? With same files excep my saved photos.
I'm using Galaxy Nexus phone. For Galaxy tablet everything is allright.
public void openCamera(View view) {
try {
int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1991;
photoName();
String _path = Environment.getExternalStoragePublicDirectory(DOWNLOAD_SERVICE) + "/" + photoFileName;
System.out.println("PATH: "+ _path);
File file = new File( _path );
Uri outputFileUri = Uri.fromFile( file );
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
} catch (Exception e) {
}
private String photoName() {
boolean isWhile = true;
int randomId = 0;
int count = 0;
while (isWhile) {
photoFileName = "MobiliSkaita_" + count + ".jpg";
File fileToCheck = new File(Environment.getExternalStoragePublicDirectory(DOWNLOAD_SERVICE) + "/" + photoFileName);
if (fileToCheck.exists()) {
System.out.println("FAILAS YRA: " + randomId);
randomId++;
photoFileName="MobiliSkaita_" + randomId + ".jpg";
} else {
System.out.println("FAILAS NERA: " + randomId);
isWhile = false;
}
count++;
}
return photoFileName;
From http://developer.android.com/guide/topics/data/data-storage.html#filesExternal, some devices use different directories for external storage.
You should try (API >= 8):
Context.getExternalFilesDir();
or (API < 8)
Context.getExternalStorageDirectory();
to get the external storage directory on the current device (assuming it is mounted).