I have project using downloadManager, i already can show the download progress in screen, but the problem is when after i download the file then click the download complete notif it said that "Can't open file"
This is my code,
public class MainActivity extends AppCompatActivity {
Button tombolDownload;
DownloadManager downloadManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tombolDownload = (Button) findViewById(R.id.btnDownload);
tombolDownload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downloadManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse("http://192.168.1.64/FileAPK/app1.apk");
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
Long reference = downloadManager.enqueue(request);
}
});
}
}
How i can fix this problem?
I think you should declare the MIME type also of APK file.
MIME type is : application/vnd.android.package-archive .
Use this as following:
request.setMimeType("application/vnd.android.package-archive");
Edit: Add the following line also so that it knows where to store it. In your code it was saving the file with some random number without extension, hence the can't open file problem was happening.
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"app1.apk");
Where app1.apk is name of file with extension and also add setMimeType()
dont forget the persmissions WRITE_EXTERNAL_STORAGE
hope it helps
I had a similar issue with the download of a zip file.
Upon attempting to open the downloaded file by clicking on the Download Manager's notification, I would get the same Can't open file notification.
In my particular case, I learned that it had nothing to do with the code itself – as the file was indeed being properly downloaded – but with the fact that the device being used did not have an installed app which could handle zip files.
After I installed a 3rd-party app which was enabled to handle zip files, I wouldn't have this issue anymore, as the the downloaded file would now be opened by that app.
Related
I have an application where i have a feature to download a file already stored in firebase. i have implemented the code to download using download manager and at the same time show the user the notification of downloading that file but for some reason it is not working.
This is my code
val downloadRequest = DownloadManager.Request(Uri.parse(model.document.substringBeforeLast(".")))
downloadRequest.setTitle("الملف")
downloadRequest.setDescription("تحميل الملف")
downloadRequest.setVisibleInDownloadsUi(true)
downloadRequest.setDestinationUri(uri.toUri())
downloadRequest.allowScanningByMediaScanner()
downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
downloadManager.enqueue(downloadRequest)
Is the file getting downloaded but notification is not visible or file is not getting downloaded either?
try this and let me know if it still doesn't work :)
downloadRequest.setNotificationVisibility(
DownloadManager.Request.VISIBILITY_VISIBLE
)
EDIT
it seems that the last time I used it there was a difference in the destination that you are specifying.
val directory: File = File(Environment.getExternalStorageDirectory().path + "/myFile")
if(!directory.exists()) {
directory.mkdir()
}
...
downloadRequest.setDestinationInExternalPublicDir("/myFile","android")
What I'm trying to achieve is to check before download if the file exists so i don't have to re-download it again. For example, i have to open for the first time this pdf from the Internet "history-of-comics.pdf", in order to do so i have to download it and open inside my app, the second time i choose to re-read it, i have to be sure that "history-of-comics.pdf" if exists inside Downloads/MyDocs, i don't have to waste resources and let the user wait to download it again. Currently the app targetSdkVersion is 29 and what i have done so far is:
Give permissions for READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE
Included in manifest android:requestLegacyExternalStorage="true" inside application tag
Download the pdf file in the MyDocs inside Downloads folder
Below is a quick sample of my code (i have commented the other combinations i have tried):
private void checkIfPdfExists(String pdfFileName) {
String uriFile = String.valueOf(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS+File.separator+"MyDocs"+File.separator+pdfFileName+".pdf"));
File file = new File(uriFile);
//File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)+"/MyDocs", pdfFileName+".pdf");
//File file = new File(Environment.DIRECTORY_DOWNLOADS+File.separatorChar+"MyDocs"+File.separatorChar+pdfFileName+".pdf");
//File file = new File(Environment.DIRECTORY_DOWNLOADS+File.separatorChar+"MyDocs", pdfFileName+".pdf");
if (file.exists() && file!=null) {
Toast.makeText(getApplicationContext(), file.getPath() + "/n exists", Toast.LENGTH_SHORT).show();
displayFromUri(Uri.parse(file.getPath()));
} else {
beginDownload("https://www.heritagestatic.com/comics/d/history-of-comics.pdf",pdfFileName);
}
}
And this is how i define the path when i download the pdf, the downloader works as it should:
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.addRequestHeader("Accept", "application/pdf");
request.setDescription(file_name);
request.setTitle("Getting your doc");
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"MyDocs/"+file_name+".pdf");
I did some research before posting the question and in some threads i found that is related to Android Q, but i can't find a real solution for it. Any help would be appreciated, thanks in advance!
The solution to my problem was how i was referring to file path and the method used for download. As #blackapps mentioned that if you use "setDestinationInExternalFilesDir" to save the file, the proper way to check if the file exist is with "getExternalFilesDir", in my case:
File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)+File.separator+"MyDocs"+File.separator+pdfFileName+".pdf");
I am creating an app that displays PDF. I want to create one button that will both download the PDF (if it does not exist) and open it (if it already exists). I am able to download a PDF but how do I proceed further?
public class Download {
DownloadManager downloadManager;
long queid;
public Download(Context context, String downloadurl, String filename){
downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadurl));
request.setDestinationInExternalFilesDir(context.getApplicationContext(), Environment.DIRECTORY_DOWNLOADS, filename);
queid = downloadManager.enqueue(request);
}
}
You have downloaded the pdf. Save it or move it to a fixed folder location on SDCard. In button click event, check if the pdf file is present on the same location. If it is present then you should open it in your pdf viewer activity in app.
You may find few libraries to enable viewing pdf in your app. One of the library which I use is AndroidPdfViewer. You can get help on how to integrate it in your app from the gitbhub link.
Regards.
I have a problem when receiving a file from an external app. I've been following the tutorial on https://developer.android.com/training/sharing/receive.html and it works fine until I want to handle the image in my code.
The problem I have is if I select and send only one file to my app, I am not able to read it after converting it from URI to a FILE object. However, if I send two or more images (the very same image selected before plus an additional one from the same directory), then I actually can read the files (all of them).
Why is that? Even setting the file to setReadable(true); I can not read it afterwards.
Target SDK is 23 and yes, I already implemented the request for permission in the code that is needed from API 23+. So this can't be the problem.
I need to be able to read the received files no matter if it was only one or a list of multiple.
On a side note: if I send any amount of images from the Google Photos app (one or multiple), I never can read the file. Images sent from the "ES File Explorer" app are readable in the code but not readable if I only send one single file to my app.
Here is my code snippet of the problematic part:
// THIS PART WORKS. RECEIVING MULTIPLE FILES ARE READABLE IN THE CODE BELOW.
void handleSendMultipleImages(Intent intent) {
ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (imageUris != null) {
addImagesToNewOrExistingContact(imageUris);
}
}
// THIS PART DOES NOT WORK. I CAN NOT READ THE FILE IN THE CODE BELOW.
private void addImageToNewOrExistingContactDialog(Uri imageUri) {
ArrayList imageUris = new ArrayList<>();
imageUris.add(imageUri);
addImagesToNewOrExistingContact(imageUris);
}
private void addImagesToNewOrExistingContact(final ArrayList<Uri> imageUris) {
for (Uri uri : imageUris) {
File f = new File(uri.getPath());
f.setReadable(true);
f.setWritable(true);
boolean readd = f.canRead(); // FALSE, but why?
boolean exec = f.canExecute(); // FALSE, but why?
}
}
Files I tested this with:
Selected two files from "ES File Explorer" and sent them to my app:
file:///storage/emulated/0/Pictures/Adobe%C2%AE%20Photoshop%C2%AE%20Touch/1452348875289.jpg
file:///storage/emulated/0/Pictures/Adobe%C2%AE%20Photoshop%C2%AE%20Touch/1455733673513.jpg
Both canRead() = TRUE
Selected one file from "ES File Explorer" and sent it to my app:
content://media/external/images/media/33675
canRead() = FALSE
Actually the files content://media/external/images/media/33675 and file:///storage/emulated/0/Pictures/Adobe%C2%AE%20Photoshop%C2%AE%20Touch/1455733673513.jpg are the exact same files.
Selected two files from "Google Photos" and send them to my app:
content://com.google.android.apps.photos.contentprovider/0/1/shared%3A%2Flocal%253A4541959b-3222-4ee0-b838-67049141b864%2FV2xDV01jNWhWVDRCQXRMY202YTh3NFNES1N4M01R/REQUIRE_ORIGINAL/NONE/1290260075
content://com.google.android.apps.photos.contentprovider/0/1/shared%3A%2Flocal%253A20e65034-795f-4300-9472-64a598afc4c1%2FV2xDV01jNWhWVDRCQXRMY202YTh3NFNES1N4M01R/REQUIRE_ORIGINAL/NONE/1096770166
Both canRead() = FALSE
Thanks for any help in advance.
Use openInputStream(uri) on getContentResolver(). No need for a File class.
I am creating a simple Android app. To run properly, it needs the contents of a file (example.xml) that is currently on my PC.
On creation, the app would look for the file, and then do some stuff with it.
#Override
protected void onCreate(Bundle savedInstanceState)
{
...
File file = new File("I wish I knew what to put here");
doStuffWithFile(file);
}
Unfortunately, I don't know where to put the file.
I need a location in internal storage to which both my PC and my Android app have access.
Is there such a location? If so, what file path String would I use to access it?
You can get the Download folder by using Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
Then you can add a filename and use this e.g. with DownloadManager
You could include the file in the assets folder of your project and then retrieve it with this.getContext().getAssets().open("example.xml")