So i have used DownloadManager to download a file from the internet using the following code :
public void DownloadFile()
{
Log.d("DownloadFileEntered", "true");
try {
String url = "https://firebasestorage.googleapis.com/v0/b/roti-bank-testing.appspot.com/o/SocialGallery%2Fsome.jpg?alt=media&token=d2ddd40f-0c04-441c-82b1-585fd8743b19";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "somegif.gif");
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
long d = manager.enqueue(request);
}catch (Exception e)
{
Log.d("DownloadFileEntered", "Error."+e.toString());
}
}
Now say, i want to delete this file.
So to do that, i used the following code :
File file = new File("file://" + Environment.DIRECTORY_DOWNLOADS + "/somegif.gif");
boolean d = file.delete();
Log.d("DownloadFileEntered", "D : "+d);
But apparently, the last Log.d gives the output as false, and the file is also not deleted. So, what is the correct way to delete a file from the external storage?
Also, can we run a function when the download is completed ? if yes then how ?
Hope this will help you:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/somegif.gif");
boolean d = file.delete();
Log.d("DownloadFileEntered", "D : "+d);
And don't forget to set this permission in your manifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
i have used the below code to download a video from server in android studio and it works correctly , but when i search the video in my device i cant find it anywhere ... where does it save and how can i change destination directory on "internal storage"?
private DownloadManager downloadManager;
btn_download_video.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse(urlVideo);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalFilesDir(Video_detail_Activity.this, Environment.DIRECTORY_DOWNLOADS, videoName);
Long reference = downloadManager.enqueue(request);
}
});
i used below permissions in my project too:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
thanks for helping ... as pskink said i changed
request.setDestinationInExternalFilesDir(Video_detail_Activity.this, Environment.DIRECTORY_DOWNLOADS, videoName);
to
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS.toString(), videoName+".mp4");
and now i can see downloaded file in "Download" folder.
I'm trying to develop an app which provides many movies and you can play it or download the movie.
I'm using Download Manager to download the movie from server, but it didn't work...
this is my method
public void downloadFileFromUrl(String url, String fileName) {
String filePath=Environment.getExternalStorageDirectory() + File.separator + "BlueNet";
File folder = new File(filePath);
if (!folder.exists()) {
folder.mkdirs();
}
try {
Uri downloadUri = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(downloadUri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
request.allowScanningByMediaScanner();
request.setDestinationInExternalPublicDir("BlueNet", fileName);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE | DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setVisibleInDownloadsUi(true);
DownloadManager downloadManager = (DownloadManager)getApplicationContext().getSystemService(DOWNLOAD_SERVICE);
long id= downloadManager.enqueue(request);
}
catch (Exception ex){
Toast.makeText(this, ex.toString(), Toast.LENGTH_LONG).show();
}
}
this is attribute
url: (http://192.168.1.5:8080/BlueNet_NMC/video_shared/blue_elephant.mp4)
filename: (blue_elephant.mp4)
and I already give this permissions to manifests
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
but when I test it in emulator or in my Galaxy S4 not working.
Please help me.
The following code which consists of downloading a file from a server and save it in the storage works fine when the device has an internal storage.
But when I tried it with a device with no internal storage, only with external storage I get the following exception.
java.io.filenotfoundexception open failed eacces (permission denied)
public void downloadFile(String dlUrl, String dlName) {
int count;
HttpURLConnection con = null;
InputStream is = null;
FileOutputStream fos = null;
try {
URL url = new URL( dlUrl );
con = (HttpURLConnection) url.openConnection();
con.setDoInput(true);
con.connect();
is = url.openStream();
String dir = Environment.getExternalStorageDirectory() + Util.DL_DIRECTORY;
File file = new File( dir );
if( !file.exists() ){
file.mkdir();
}
Util.LOG_W(TAG, "Downloading: " + dlName + " ...");
fos = new FileOutputStream(file + "/" + dlName);
byte data[] = new byte[1024];
while( (count = is.read(data)) != -1 ){
fos.write(data, 0, count);
}
Util.LOG_D(TAG, dlName + " Download Complete!");
} catch (Exception e) {
Util.LOG_E(TAG, "DOWNLOAD ERROR = " + e.toString() );
bServiceDownloading = false;
}
finally{
try {
if( is != null)
is.close();
if( fos != null)
fos.close();
if( con != null)
con.disconnect();
} catch (Exception e) {
Util.LOG_E(TAG, "CLOSE ERROR = " + e.toString() );
}
}
}
And in manifest file I has the following:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Any suggestions what maybe the cause?
By the way Environment.getExternalStorageDirectory() returns /mnt/sdcard/ and file.mkdir() return false.
This attribute is "false" by default on apps targeting
Android 10 or higher.
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
This problem seems to be caused by several factors.
Check#1
First add this permission in your manifest file and check if it is working:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
...
</application>
.....
Check#2:
If you are running on an emulator, check the properties to see if it has an SD card.
Check#3:
Disable file transfer from device to computer. If Enabled, the app wont be able to access the SD card.
Check#4:
If still not working, try the following:
String dir = Environment.getExternalStorageDirectory().getAbsolutePath()
For me the following worked:
The problem is that getExternalStorageDirectory returns /mnt/sdcard whereas I need the actual path of external storage which is /mnt/sdcard-ext and there is no API in android that can get me the absolute path of removable sdcard.
My solution was to hard code the directory as follows:
String dir = "/mnt/sdcard-ext" ;
Since the application is intended to work only on one device, the above did the job.
If you encounter the same problem, use an file explorer application to find out the name of the external directory and hard code it.
Use READ_EXTERNAL_STORAGE permission to read data from the device.
Did you try it on emulator? Check the properties if it has an SD card. I had the same problem, and it was because the emulator did not have an SD card. Check if yours has or not.
I had the same problem, and i solved it by disabling file transfer from device to computer.
Because if u enable file transfer, sd card is not accessible to debugging application.
try
Environment.getExternalStorageDirectory().getAbsolutePath()
and don't forget to add
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Try using mkdirs instead of mkdir. If you are creating a directory path and parent doesn't exist then you should use mkdirs.
I suspect you are running Android 6.0 Marshmallow (API 23) or later. If this is the case, you must implement runtime permissions before you try to read/write external storage.
https://developer.android.com/training/permissions/requesting.html
i have done very silly mistake.
I have already put in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and also add permission in java file,as get permission pragmatically.
But there is mistake of Manifest.permission.READ_EXTERNAL_STORAGE.
Please use Manifest.permission.WRITE_EXTERNAL_STORAGE.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
I had the same problem. I used the write and read permission in the manifest correctly , yet it didn't work! The solution was very silly: unplug your phone from the PC before running the application. It seems when your phone is connected as "Mass storage" to the PC, the application cannot access the external storage.
First in your manifest file declare permissions :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
now in header of application tag of manifest file :
android:requestLegacyExternalStorage="true"
now defines provider for your app in between tag of manifest file. as :
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_path" />
</provider>
now create a folder xml in res folder like this :
now create a xml file provider_path.xml and copy below code in it :
<?xml version="1.0" encoding="utf-8"?>
<path>
<external-path
name="external_files"
path="." />
now in your activity :
String filename = null ;
URL url = null;
try {
url = new URL("http://websitename.com/sample.pdf");
filename = url.getPath();
filename = filename.substring(filename.lastIndexOf('/')+1);
} catch (MalformedURLException e) {
e.printStackTrace();
}
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+"/"+filename);
if(file.exists()){
Uri uri = FileProvider.getUriForFile(context, "com.example.www"+".provider",file);
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(uri, "application/pdf");
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(i);
}
else {
//download file here
new AlertDialog.Builder(context)
.setTitle("Information")
.setMessage("Do you want to download this file ?")
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url+""));
request.setTitle(filename);
request.setMimeType("application/pdf");
request.allowScanningByMediaScanner();
request.setAllowedOverMetered(true);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
DownloadManager downloadManager = (DownloadManager)context.getSystemService(DOWNLOAD_SERVICE);
downloadManager.enqueue(request);
}
}).show();
}
I'm using DownloadManager to download a file from a webService. The download end successfuly, but when I try to open the new file in the "download" folder I've got this error "Impossible to open file" (and I know I can open this type of file).
Also, when I plug my phone to my computer and when I open the download file with it, the file open successfuly and is not corrupted.
I don't have other error, so I'm really lost !
Here my code:
/*Data*/
int filePosition = position - _subFolderNameList.length;
String url = _folder.getFiles().get(filePosition).getUrl();
String FileName = _folder.getFiles().get(filePosition).getName();
String Description = _folder.getFiles().get(filePosition).getUrl();
/*Prepare request*/
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDescription(Description);
request.setTitle(FileName);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, FileName);
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request); // Send request
Edit: Permission in the Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Okay I found the problem !
I had to specify the "MIME content type" of the file using setMimeType().
public DownloadManager.Request setMimeType (String mimeType);
Yes you have to specify the MIME type.
Adding a few more details to the accepted answer.
public DownloadManager.Request setMimeType (String mimeType);
To get MIME type you can use the following function.
private String getMimeFromFileName(String fileName) {
MimeTypeMap map = MimeTypeMap.getSingleton();
String ext = MimeTypeMap.getFileExtensionFromUrl(fileName);
return map.getMimeTypeFromExtension(ext);
}
and the following is the Xamarin.Android implementation of the same :
private static string GetMimeTypeFromFileName(string fileName)
{
var map = MimeTypeMap.Singleton;
var ext = MimeTypeMap.GetFileExtensionFromUrl(fileName);
return map.GetMimeTypeFromExtension(ext);
}