Not able to check whether file exists - android

I'm trying to download a file and if it exists to delete it and download again. The download works. But the function checkFile never finds the file and I don't know why.
private fun startDownloading() {
checkFile()
val url = etUrl.text.toString()
val request = DownloadManager.Request(Uri.parse(url))
//allow type of networks to download file(s) by default, by default both are allowed
request.setAllowedNetworkTypes((DownloadManager.Request.NETWORK_MOBILE or DownloadManager.Request.NETWORK_WIFI))
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "$folderName/$fileName")
//get download service, and enqueue file
val manager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
manager.enqueue(request)
}
private fun checkFile(){
val file = File(Environment.DIRECTORY_DOWNLOADS, "$folderName/$fileName")
if(file.exists()){
Toast.makeText(this, "File exists", Toast.LENGTH_LONG).show()
file.delete()
}else{
Toast.makeText(this, file.toString() + " doesn't exist", Toast.LENGTH_LONG).show()
}
}
Thanks in advance.

You create the file in the public external storage directory with:
request.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
"$folderName/$fileName"
)
but you try to read it, from a relative (from the application's current directory) path:
val file = File(Environment.DIRECTORY_DOWNLOADS, "$folderName/$fileName")
You need to use the downloads directory, relative to the public external storage directory:
val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "$folderName/$fileName")

Related

Not able to open file(pdf/doc) from my app after downloading in android

I am downloading file(pf/doc) from url. I have read & write permission as well & providers also defined in manifest & provider_path also.
File successfully downloaded in my phone "Download" folder. But when i try to open file with following code it gives me an error "this file could not be accessed. check your connection or make the file name shorter"
var attachmentUri: Uri? = attachmentUri
if (attachmentUri != null) {
if (ContentResolver.SCHEME_FILE == attachmentUri.scheme) { // FileUri - Convert it to contentUri.
val file = File(attachmentUri.path)
attachmentUri =
FileProvider.getUriForFile(context, context.applicationContext
.packageName + ".provider", file)
}
context.grantUriPermission(context.packageName, attachmentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
val openAttachmentIntent = Intent(Intent.ACTION_VIEW)
openAttachmentIntent.setDataAndType(attachmentUri, attachmentMimeType)
openAttachmentIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
openAttachmentIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
try {
context.startActivity(openAttachmentIntent)
} catch (e: ActivityNotFoundException) {
Toast.makeText(context, "Unable to open file", Toast.LENGTH_LONG).show()
}
}
attachmentUri - content://com.hello.provider/external_files/Download/ac_xyz-2.pdf I am also not able to open doc file as well.
File download code :
if (url != null && !url.isEmpty()) {
val uri = Uri.parse(url)
activity.registerReceiver(
attachmentDownloadCompleteReceive, IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE
)
)
val request = DownloadManager.Request(uri)
request.setMimeType(getMimeType(uri.toString()))
request.setTitle(fileName)
request.setDescription("Downloading attachment..")
request.allowScanningByMediaScanner()
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
val dm = activity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
dm.enqueue(request)
}
Is there any way to solve this error ?
You are trying to build up an uri using a file provider for a file in Download folder.
Not needed.
Register a broadcast receiver for action download complete and you will get notified when the download is ready.
Also you will get then a nice uri from the DownloadManager which you can use in an action view intent for a pdf reader.

create a folder in /storage/emulated/0

I would like to create a directory in /storage/emulated/0/ and a save a file there.Since the "getExternalStorageDir()" & "getExternalPublicStorageDir()" are Depreciated I don't know how to implement it.
I have gone through most of the questions and answers but they are all either outdated/open.
All I want is a way to access the "storage/emulated/0/" path.
val extStorageDirectory = requireContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
val folder = File(extStorageDirectory, "Work Logs")
folder.mkdir()
The above code creates a folder in "Android/data/com.xxx.xxx/"
Easy with MediaStore.
binding.createFolderButton.setOnClickListener {
val values = ContentValues()
values.put(MediaStore.MediaColumns.RELATIVE_PATH, "${Environment.DIRECTORY_DOCUMENTS}/myFolder/") //folder name
contentResolver.insert(MediaStore.Files.getContentUri("external"), values)
Toast.makeText(this, "\"myFolder\" created", Toast.LENGTH_SHORT).show()
}
Demo: https://youtu.be/a6Q7IlA_uOs

Check If File Exists Before downloading the file

I am using download manager to download the file. The code for downloading the file is as follow.
private String DownloadData(Uri uri, View v, String textview) {
long downloadReference;
// Create request for android download manager
dm = (DownloadManager)getContext().getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
//Setting title of request
request.setTitle(textview);
//Setting description of request
request.setDescription("Android Data download using DownloadManager.");
//Set the local destination for the downloaded file to a path within the application's external files directory
request.setDestinationInExternalFilesDir(getContext(), DIRECTORY_DOWNLOADS, File.separator + "Dr_Israr_Ahmad" + File.separator + textview+".mp3");
//Enqueue download and save into referenceId
downloadReference = dm.enqueue(request);
return null
}
The above code works fine. What i need to do now is if the file is already downloaded than i want my app to play it. The code which is used is
String path = String.valueOf(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS+ File.separator+"Dr_Israr_Ahmad" + File.separator +filename+".mp3"));
File file = new File(path);
if(file.exists()){
Toast.makeText(getContext(),path+ "/n exists", Toast.LENGTH_SHORT).show();
} else if (!file.exists()) {
Toast.makeText(getContext(), "Downloading", Toast.LENGTH_SHORT).show();
Uri uri = Uri.parse("http://www.digitalsguide.com/mobile-apps/dr-israr-ahmad/audios/"+filename+".mp3");
String filepath = DownloadData(uri,view,filename);
}
but the problem is the condition is true even if the file doesn't exist. Is there a problem in my path ? kindly help me out,
I detected some strange behavior with exists time ago and changed it to isFile:
File file = new File(path);
if (file.isFile()) {
Toast.makeText(getContext(), path + "/n exists", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), "Downloading", Toast.LENGTH_SHORT).show();
// ...
}
I think the mobile, somehow, created a directory every time new File() was executed.
Check this.
Because getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) returns /storage/emulated/0/Android/data/<PACKAGE_ID>/files/Download. It's not the folder where DownloadManager downloads files when we set Environment.DIRECTORY_DOWNLOADS.
Try to put your path like the example shown below:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+ "/" +filename);
Here filename is example.pdf
you can then check if file exists or not
.getExternalFilesDir(yourFilePath) creates a directory in your code. so use it like this.
String path = String.valueOf(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)+ File.separator+"Dr_Israr_Ahmad" + File.separator +filename+".mp3");

How to store files generated from app in "Downloads" folder of Android?

I am generating an excelsheet in my app which when generated should be automatically saved in the "Downloads" folder of any android device where all the downloads are typically saved.
I have the following which saves the file under "My Files" folder -
File file = new File(context.getExternalFilesDir(null), fileName);
resulting in -
W/FileUtils﹕ Writing file/storage/emulated/0/Android/data/com.mobileapp/files/temp.xls
I rather want to save the generated file automatically in the "Downloads" folder when the excel sheet is generated.
Update # 1: Please see the snapshot here. What I want is the one circled in red and what you suggested gets stored in the one circled blue (/storage/emulated/0/download) if that makes sense. Please advise on how I can save a file in the one circled red i.e., "Downloads" folder which is different from /storage/emulated/0/Download under "MyFiles"
Use this to get the directory:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
And don't forget to set this permission in your manifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Now from your question edit I think understand better what you want.
Files shown on the Downloads menu from the one circled in red are ones that are actually downloaded via the DownloadManager, though the previos steps I gave you will save files in your downloads folder but they will not show in this menu because they weren't downloaded. However to make this work, you have to initiate a download of your file so it can show here.
Here is an example of how you can start a download:
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "fileName");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // to notify when download is complete
request.allowScanningByMediaScanner();// if you want to be available from media players
DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
manager.enqueue(request);
This method is used to download from a Uri and i have not used it with a local file.
If your file is not from the internet you could try saving a temporary copy and get the Uri of the file for this value.
Just use the DownloadManager to download your generated file like this:
File dir = new File("//sdcard//Download//");
File file = new File(dir, fileName);
DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
downloadManager.addCompletedDownload(file.getName(), file.getName(), true, "text/plain",file.getAbsolutePath(),file.length(),true);
The "text/plain" is the mime type you pass so it will know which applications can run the downloadedfile. That did it for me.
I used the following code to get this to work in my Xamarin Droid project with C#:
// Suppose this is your local file
var file = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
var fileName = "myFile.pdf";
// Determine where to save your file
var downloadDirectory = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
var filePath = Path.Combine(downloadDirectory, fileName);
// Create and save your file to the Android device
var streamWriter = File.Create(filePath);
streamWriter.Close();
File.WriteAllBytes(filePath, file);
// Notify the user about the completed "download"
var downloadManager = DownloadManager.FromContext(Android.App.Application.Context);
downloadManager.AddCompletedDownload(fileName, "myDescription", true, "application/pdf", filePath, File.ReadAllBytes(filePath).Length, true);
Now your local file is "downloaded" to your Android device, the user gets a notification, and a reference to the file is being added to the downloads folder. Make sure, though, to ask the user for permission before you write to the file system, otherwise an 'access denied' exception will be thrown.
For API 29 and above
According to documentation, it is required to use Storage Access Framework for Other types of shareable content, including downloaded files.
System file picker should be used to save file to External storage directory.
Copy file to external storage example:
// use system file picker Intent to select destination directory
private fun selectExternalStorageFolder(fileName: String) {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*"
putExtra(Intent.EXTRA_TITLE, name)
}
startActivityForResult(intent, FILE_PICKER_REQUEST)
}
// receive Uri for selected directory
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
FILE_PICKER_REQUEST -> data?.data?.let { destinationUri ->
copyFileToExternalStorage(destinationUri)
}
}
}
// use ContentResolver to write file by Uri
private fun copyFileToExternalStorage(destination: Uri) {
val yourFile: File = ...
try {
val outputStream = contentResolver.openOutputStream(destination) ?: return
outputStream.write(yourFile.readBytes())
outputStream.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
As Oluwatumbi have answered this question correctly but First you need to check for permission is granted for WRITE_EXTERNAL_STORAGE by following code:
int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
// Request for permission
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
}else{
Uri uri = Uri.parse(yourUrl);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "fileName");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // to notify when download is complete
request.allowScanningByMediaScanner();// if you want to be available from media players
DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
manager.enqueue(request);
}
This is running code download files using DownloadManager for Xamarin android api version 29
public bool DownloadFileByDownloadManager(string imageURL)
{
try
{
string file_ext = Path.GetExtension(imageURL);
string file_name = "MyschoolAttachment_" + DateTime.Now.ToString("yyyy MM dd hh mm ss").Replace(" ", "") + file_ext;
var path = global::Android.OS.Environment.DirectoryDownloads;
Android.Net.Uri uri = Android.Net.Uri.Parse(imageURL);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.SetDestinationInExternalPublicDir(path, file_name);
request.SetTitle(file_name);
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted); // to notify when download is complete
// Notify the user about the completed "download"
var downloadManager = DownloadManager.FromContext(Android.App.Application.Context);
var d_id = downloadManager.Enqueue(request);
return true;
}
catch (Exception ex)
{
UserDialogs.Instance.Alert("Error in download attachment.", "Error", "OK");
System.Diagnostics.Debug.WriteLine("Error !" + ex.ToString());
return false;
}
}
WORKING ON API 29 AND 30
To get the directory:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
Set this permission in your AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Add requestLegacyExternalStorage to your application tag in AndroidManifest.xml (for API 29):
<application
...
android:requestLegacyExternalStorage="true">

how to check if file is available in internal storage

I am trying to download a file from the internet and it succeeded but now
I want to check if the file exists in the internal storage.
else if (arg0.getId() == R.id.btn_download)
{
Toast.makeText(this, "download button clicked", Toast.LENGTH_SHORT).show();
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(names[b]));
request.setDescription("Downloading..");
request.setTitle("Futsing Magazine Issue " + (this.mPictureManager.getCurrentIndex() +1) );
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "Futsing Magazine Issue " + (this.mPictureManager.getCurrentIndex()
+1) +".pdf");
// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
The items retrieved are downloaded to /mnt/sdcard/Download.
How do I check if the file exists or not using code?
Let's say following is your file's path
String path=context.getFilesDir().getAbsolutePath()+"/filename";
File file = new File ( path );
if ( file.exists() )
{
// Toast File is exists
}
else
{
// Toast File is not exists
}
File applictionFile = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS)+ "/"+<file-name>);
if(applictionFile != null && applictionFile.exists()){
}
if file is getting downloads in to default donwload directory

Categories

Resources