Android Download Manager is duplicating existing files - android

I am trying to download Audio files into one of the directories owned by the application using DownloadManager.
Here is my code:
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_MUSIC),
audioName + ".mp3");
if (file.exists()) {
return;
} else {
DownloadManager mgr = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(
downloadUri);
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE).setAllowedOverMetered(true)
.setAllowedOverRoaming(true).setVisibleInDownloadsUi(false)
.setDestinationUri(Uri.fromFile(file));
mgr.enqueue(request);
}
The problem is that downloadManager is duplicating already downloaded audios, for exemple if I have an audio file named "test.mp3" I would find both "test.mp3" and "test1.mp3" in my application directory.
Am I doing something wrong?
Please keep in mind that I want to download files in the app directory and this is why I am using setDestinationUri

I had the same issue. Up to date what I have realized is that the download manager rarely stops downloading and will keep doing so and appending values to the same file name. So I suggest going through your destination directory and deleting duplicate files. You can call this method onCreate.
private void cleanUp()
{
String path = "PATH TO YOUR DOWNLOAD DIRECTORY/FOLDER NAME/";
Log.d("Files", "Path: " + path);
File directory = new File(path);
File[] files = directory.listFiles();
Log.d("Files", "Size: "+ files.length);
for (int i = 0; i < files.length; i++)
{
Log.d("Files", "FileName:" + files[i].getName());
for(int j=1;j<files.length;j++)
{
if(files[i].getName().contains("-"+String.valueOf(j)+".mp3")) // format according to how your download manager has renamed the file e.g "-"+String.valueOf(j)+".mp3" for fileName-1.mp3 or String.valueOf(j)+".mp3" for fileName1.mp3
{
toast(files[i].getName());
files[i].delete();
}
}
}
}

Related

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 save files with DownloadManager in private path?

I have downloaded some files with DownloadManager, I want to save them where that no one can access them, I mean they are private, just my application can access them and I want after uninstall my app they get deleted. but according to my search DownloadManager can save files just in SDCard that everyone can see my files.
can anyone tell me what to do?
You should probably use:
request.setDestinationInExternalFilesDir(context, DIRECTORY_DOWNLOADS, File.separator + folderName + File.separator + fileName);
Where request is your DownloadManager.Request
This folder (sdcard/Android/data/your.app.package) is accessible to the user, but not visible in galleries (not scanned by media scanner), it's only accessible using file manager. Also, this folder will be deleted when your app gets deleted.
You can use internal storage path to save data internally and it will get deleted when your app will get uninstalled
String dir = getFilesDir().getAbsolutePath();
For Set Your Path For Download File Use: Work For me (Android 11).
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/YOUR FOLDER/", "YOUR FILE.(mp3|mp4|pdf|...)");
request.setDestinationUri(Uri.fromFile(file));
Complete Code:
First Check Directory
private boolean CreateDirectory() {
boolean ret = false;
File filepath = Environment.getExternalStorageDirectory();
File dir = new File(filepath.getPath() + "/YOUR FOLDER/");
if (!dir.exists()) {
try {
dir.mkdirs();
ret = true;
} catch (Exception e) {
ret = false;
e.printStackTrace();
}
}
return ret;
}
Then:
String URL = " YOUR URL ";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(URL));
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setTitle("YOUR TITLE");
request.setDescription("YOUR DESCRIPTION");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/YOUR FOLDER/", "YOUR FILE.(mp3|mp4|pdf|...)");
request.setDestinationUri(Uri.fromFile(file));
DownloadManager manager=(DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
Long downloadId= manager.enqueue(request);
ok,Finish

Download Image and store it in Gallery app in android

I want to save Image file in Gallery so that Image can be viewed from the Gallery application.
But what I want is to create a separate dir, as like we have for whatsapp Images etc apps in our gallery application.
So far I have written this code to download an image
public void createDir(){
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), DIR_NAME);
Log.d(LOG_TAG, "dir pictr :" + dir.toString());
if (!dir.exists()) {
dir.mkdir();
Log.d(LOG_TAG, "dir not exists and created first time");
} else {
Log.d(LOG_TAG, "dir exists");
}
}
Above code created directory inside gallery dir
Uri imageLink = Uri.parse(downloadUrlOfImage); // this is download link like www.com/abc.jpg
CreateDir();
DownloadManager.Request request = new DownloadManager.Request(imageLink);
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), DIR_NAME);
String absPath = dir.getAbsoultePath();
request.setDestinationUri(Uri.parse(absPath + "image.jpg"));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
DownloadManager dm = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
dm.enqueue(request);
But this gives me error as java.lang.IllegalArgumentException: Not a file URI: /storage/sdcard0/Pictures/FreeWee/1458148582.jpg
Basically what I want is to save Image and that image must be shown in Gallery Application under Some directory I named.
If not understood please ask, so that I can improve my question.
How do I proceed further ?
As #RoyFalk pointed out you got 2 issues in your code.
So you can go with this code snippet
String filename = "filename.jpg";
String downloadUrlOfImage = "YOUR_LINK_THAT_POINTS_IMG_ON_WEBSITE";
File direct =
new File(Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
.getAbsolutePath() + "/" + DIR_NAME + "/");
if (!direct.exists()) {
direct.mkdir();
Log.d(LOG_TAG, "dir created for first time");
}
DownloadManager dm = (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(downloadUrlOfImage);
DownloadManager.Request request = new DownloadManager.Request(downloadUri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle(filename)
.setMimeType("image/jpeg")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES,
File.separator + DIR_NAME + File.separator + filename);
dm.enqueue(request);
And you will see Image inside the gallery application under your DIR_NAME.
Hope this will help you.

Downloads the same file twice?

Hi i've been looking through various parts of my code to try and find out whats happening but can't seem to figure it out. The following code is supposed to be downloading two files one called "clientraw" and one called "clientrawextra" but for some reason when i look in the directory there are 2 versions of each file "clientraw...1..." "clientrawextra...1..."
Therefore it seems like it's downloading the files multiple times and i have no idea why??
Thanks in advance!
distance dis = new distance();
dis.findURL(value);
String url = dis.findURL(value);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
// 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.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "clientraw.txt");
// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
/////////////////////////////////////////////////////
distance disextra = new distance();
disextra.findextra(value);
String urlextra = disextra.findextra(value);
DownloadManager.Request requestextra = new DownloadManager.Request(Uri.parse(urlextra));
// 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) {
requestextra.allowScanningByMediaScanner();
}
requestextra.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "clientrawextra.txt");
manager.enqueue(requestextra);
mDownload = new DownLoadComplte();
registerReceiver(mDownload, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
And the broadcast receiver...
private class DownLoadComplte extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(
DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
Intent myIntent = new Intent(splash.this, MainActivity.class);
myIntent.putExtra("key", value); //Optional parameters
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//unregisterReceiver(mDownload);
splash.this.startActivity(myIntent);
}
}
}
So if anyone has the same issue, apparently this is an ongoing and as of yet unresolved issue with the Download manager. I have used a little bit of a work around which you might want to use if your flow is similar to mine. Basically every time that the user opens the app two files are automatically downloaded to the SD card which overwrites the two files previously downloaded. So all i did was add a couple of extra functions to delete the duplicates...
File sdCard = Environment.getExternalStorageDirectory();
File file = new File(sdCard.getAbsolutePath() +
"/Download/", client);
Log.d("file path", String.valueOf(file));
if(file.exists())
{
boolean flag = file.delete();
Log.d("file", "file deleted " + flag);
}
File sdCardextra = Environment.getExternalStorageDirectory();
File fileextra = new File(sdCardextra.getAbsolutePath() +
"/Download/", clientextra);
boolean exist = fileextra.exists();
Log.d("the file exists = ", String.valueOf(exist));
if(fileextra.exists())
{
boolean flag = fileextra.delete();
Log.d("file", "file deleted " + flag);
}
File sdCard2 = Environment.getExternalStorageDirectory();
File file2 = new File(sdCard2.getAbsolutePath() +
"/Download/", "clientraw-1.txt");
Log.d("file path", String.valueOf(file2));
if(file2.exists())
{
boolean flag = file2.delete();
Log.d("file", "file deleted " + flag);
}
File sdCardextra3 = Environment.getExternalStorageDirectory();
File fileextra3 = new File(sdCardextra3.getAbsolutePath() +
"/Download/", "clientrawextra-1.txt");
boolean exists = fileextra3.exists();
Log.d("the file exists = ", String.valueOf(exists));
if(fileextra3.exists())
{
boolean flag = fileextra3.delete();
Log.d("file", "file deleted " + flag);
}

File being downloaded is saved inside data folder

I am using download manager to download MP3 Files from my server.
Here is the code for it.
public String createFilePath()
{
String path;
String dir = "APP_NAME";
path = Environment.getExternalStorageDirectory().getPath();
File file = new File(Environment.getExternalStorageDirectory(),dir);
if(!file.exists())
{
file.mkdir();
}
path += "/" +dir + "/";
System.out.println("-- saving path : " + path);
return path;
}
public void startDownload() {
Uri uri=Uri.parse(URLFixer.Fix(DATA.url));
System.out.println("-- download path : " + createFilePath() + FileNameGetter.getFileName(DATA..url));
DownloadManager.Request request = new Request(uri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI |DownloadManager.Request.NETWORK_MOBILE);
request.setAllowedOverRoaming(false);
request.setTitle(DATA..title);
request.setDescription(DATA.artist + " - " + DATA.album);
request.setDestinationInExternalFilesDir(activity, createFilePath(), FileNameGetter.getFileName(DATA..url));
// request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
lastDownload= mgr.enqueue(request);
isDownloading = true;
Toasts.pop(activity, "Download Started!!");
// v.setEnabled(false);
// findViewById(R.id.query).setEnabled(true);
}
The problem is that it should be saved on SD Card inside folder "APP_NAME", but once the audio is downloaded, I cant see it inside that folder, and when I play the audio, and check its info, it shows path like thie
/sdcard/Android/data/com.X.app/files/mnt/sdcard/APP_NAME/file.mp3
As its being saved inside data folder, user is not able to see the file. How to fix it to move it to main SD Card i.e. /mnt/sdcard/APP_NAME so that user can see it.
DownloadManager.Request.setDestinationUri(Uri uri) should fit your requirement, remember to call allowScanningByMediaScanner() if you want the MP3 to be scanned by MediaScanner.

Categories

Resources