I try, to check if this file exists after i downloaded it, but its says to me that is doesnt exist
#Override
public void handleResult(Result result)
{
myResult = result;
dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse(result.getText());
DownloadManager.Request request = new DownloadManager.Request(uri);
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
String nameOfFile = URLUtil.guessFileName(result.getText(),null, MimeTypeMap.getFileExtensionFromUrl(result.getText()));
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, nameOfFile);
dm.enqueue(request);
String erg = "";
File mPath = new File((Environment.DIRECTORY_DOWNLOADS + "/" + nameOfFile));
if (mPath.getAbsoluteFile().exists()) {
erg = "existiert";
}else
{
erg = "existiert nicht";
}
}
The downloading process is happening on background. So after enqueue() your file doesn't exist cause it's not downloaded yet.
You just need to register BroadcastReceiver with this
ACTION_DOWNLOAD_COMPLETE intent filter. And DownloadManager will broadcast when downloads complete. See documentation here: https://developer.android.com/reference/android/app/DownloadManager.html#ACTION_DOWNLOAD_COMPLETE
Related
I did setOnClickListner for every video in adapter I've gotten from api youtube. I am able to download some videos to storage but when I do the same with some more videos it cannot though all video is displayed in my recyclerview. My code:
String youtubeLink = ("https://www.youtube.com/watch?v=" + videoYT.getId().getVideoId());
YouTubeUriExtractor ytEx = new YouTubeUriExtractor(context) {
#Override
public void onUrisAvailable(String videoId, String videoTitle, SparseArray<YtFile> ytFiles) {
if (ytFiles != null) {
int itag = 22;
if(ytFiles.get(itag)!=null){
String downloadURL = ytFiles.get(itag).getUrl();
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadURL));
String title = URLUtil.guessFileName(downloadURL,null,null);
request.setTitle(title);
request.setDescription("Downloading file...");
String cookie = CookieManager.getInstance().getCookie(downloadURL);
request.addRequestHeader("cookie",cookie);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,title);
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
downloadManager.enqueue(request);
Toast.makeText(context, "Bắt đầu tải xuống...", Toast.LENGTH_SHORT).show();
}
}
}
};
ytEx.execute(youtubeLink);
I have upgraded to android 11. I am having an issue downloading PDF files.
I have used this code:
private void createFile(Uri pickerInitialUri, String title) {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_TITLE, title);
// Optionally, specify a URI for the directory that should be opened in
// the system file picker when your app creates the document.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri);
}
startActivityForResult(intent, CREATE_FILE);
}
The file is created but the file is empty. I am still unable to save the downloaded pdf file.
I used to use DownloadManager request to download the pdf file from web.
DownloadManager downloadManager = (DownloadManager) this.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
if (SDK_INT > Build.VERSION_CODES.Q) {
// Uri uri1 = Uri.fromFile(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "")); //before android 11 this was working fine
// Uri uri1 = Uri.fromFile(new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), ""));
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(true).setTitle(title + strDate + ".pdf")
.setDescription(description)
//.setDestinationUri(uri1) // before android 11 it was working fine.
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, title + strDate + ".pdf") // file is not saved on this directory.
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);//to show the DOWNLOAD notification when completed
// createFile(uri , title + strDate + ".pdf"); // for new scoped storage
} else {
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(true).setTitle(title + strDate + ".pdf")
.setDescription(description)
.setDestinationInExternalPublicDir(FileUtils.downloadPdfDestination(), title + strDate + ".pdf")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //to show the DOWNLOAD notification when completed
}
long PDF_DOWNLOAD_ID = downloadManager.enqueue(request);```
ACTION_CREATE_DOCUMENT is used to create a new document. If one already existed, it will be overwritten. If you want to view an existing document, use ACTION_VIEW.
Of course none of the code you posted actually downloads a PDF. If you need help with that, post your DownloadManager code.
Check this code snippet:
override fun startDownload(url: String, onError: (e: Exception) -> Unit) {
try {
val request = DownloadManager.Request(Uri.parse(url))
request.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
UUID.randomUUID().toString()
)
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION)
(context.getSystemService(DOWNLOAD_SERVICE) as DownloadManager).enqueue(request)
} catch (e: Exception) {
e.printStackTrace()
onError.invoke(e)
}
}
It's working fine on Android 11 by using DownloadManger API.
Use below code to download & view pdf.
First you need to apply rxjava dependency for background task.
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
Don't forgot to check WRITE_EXTERNAL_STORAGE permission before call below method. Also check INTERNET permission as well.
Then use below method to perform operation in background.
private void downloadAndOpenInvoice() {
mDialog.show();
Observable.fromCallable(() -> {
String pdfName = "Invoice_"+ Calendar.getInstance().getTimeInMillis() + ".pdf";
String pdfUrl = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";
File file = CommonUtils.downloadFile(mActivity, pdfUrl, pdfName,mDialog);
return file;
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(file -> {
CommonUtils.viewPdf(file, mActivity, mDialog);
});
}
To download file from url use below snippet
public static File downloadFile(Activity mActivity, String url, String fileName, CustomDialog mDialog) {
// write the document content
File fileDir = new File(CommonUtils.getAppDir(mActivity, "Invoice")); //Invoice folder inside your app directory
if (!fileDir.exists()) {
boolean mkdirs = fileDir.mkdirs();
}
File pdfFile = new File(CommonUtils.getAppDir(mActivity, "Invoice"), fileName); //Invoice folder inside your app directory
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(pdfFile));
fos.write(buffer);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
if (mDialog.isShowing()) {
mDialog.dismiss();
}
Toast.makeText(mActivity, "Something wrong: " + e.toString(), Toast.LENGTH_LONG).show();
}
return pdfFile;
}
for app directory
public static String getAppDir(Context context, String folderName) {
return context.getExternalFilesDir(null).getAbsolutePath() + File.separator + folderName + File.separator;
}
Use below code to view pdf
public static void viewPdf(File pdfFile, Activity mActivity, CustomDialog mDialog) {
Uri uri = FileProvider.getUriForFile(mActivity, mActivity.getApplicationContext().getPackageName() + ".provider", pdfFile);
// Setting the intent for pdf reader
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
pdfIntent.setDataAndType(uri, "application/pdf");
//pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mDialog.isShowing()) {
mDialog.dismiss();
}
}
});
mActivity.startActivity(pdfIntent);
Log.e("Invoice - PDF", pdfFile.getPath());
} catch (ActivityNotFoundException e) {
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
if (mDialog.isShowing()) {
mDialog.dismiss();
}
}
});
e.printStackTrace();
Log.e("Invoice - PDF", "Can't read pdf file");
Toast.makeText(mActivity, "Can't read pdf file", Toast.LENGTH_SHORT).show();
}
}
I'm working on backup and restore SQLite Database to cloud server. I've completed the backup code and it works. However, I have a problem when I'm trying to restore it. The problem is, on Android 11, the Environment.DIRECTORY_DOWNLOADS is in Android/data/package/files/Download, but somehow I cannot access or write to Environment.DIRECTORY_DOWNLOADS, and I don't know why. Here's my code (the download from cloud method, it succeeds).
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse(response.body().getPath());
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setDestinationInExternalFilesDir(getApplicationContext(), Environment.DIRECTORY_DOWNLOADS, sharedPreference.getUser().getEmail() + ".db");
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setTitle(sharedPreference.getUser().getEmail() + ".db");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
Long downloadReference = manager.enqueue(request);
When I'm trying to access them, I cannot access the Environment.DIRECTORY_DOWNLOADS. Here is the code
File internal = new File(Environment.DIRECTORY_DOWNLOADS);
if (internal.canRead()) {
File currentDB = new File("/data/data/" + getPackageName() + "/databases/", DBHelper.DATABASE_NAME);
File backupDB = new File(internal, sharedPreference.getUser().getEmail() + ".db");
Toast.makeText(getApplicationContext(),backupDB.toString(),Toast.LENGTH_SHORT).show();
if (backupDB.exists()) {
FileChannel src = new FileInputStream(backupDB).getChannel();
FileChannel dst = new FileOutputStream(currentDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), backupDB.toString(), Toast.LENGTH_SHORT).show();
} else {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), "Error, file not exist!", Toast.LENGTH_SHORT).show();
}
} else {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), "Error, cannot read the directory!", Toast.LENGTH_SHORT).show();
}
In my application(which is run on a couple of type of tv-boxes from same manufacturer and all deviecs are rooted) I do check last version of my application from a server of my own and if there is a new version available, I download the APK file and try to install it using pm install command.
Though I've never started any activity to install the APK, it automatically opens the activity from intent Intent intent = new Intent(Intent.ACTION_VIEW);.
I've never used Intent.ACTION_VIEW in my whole project, so I assume that the android DownloadManager opens this activity automatically, and I want to stop it from doing so. Any idea how?
Here is my code:
//this is the method where I download the apk
//I'm putting only the important parts to make the question as short as possible
private void downloadApk() {
if (status == State.DOWNLOADING)
return;
setStatus(State.DOWNLOADING);
String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = appType + versionInfo.getVersionName() + ".apk";
destination += fileName;
Uri uri = Uri.parse("file://" + destination);
String url = versionInfo.getUrl();
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDescription("Downloading new Hub version");
request.setTitle("Downloading");
request.setDestinationUri(uri);
downloadId = manager.enqueue(request);
monitorDownloadPercentage();
mContext.registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
This method only calculates how much of the file is downloaded in percentage and calls the callback with the value. This calculated value, on it's path updates one ProgressBar and gets set as the text of a TextView.
private void monitorDownloadPercentage() {
new Thread(new Runnable() {
#Override
public void run() {
downloading = true;
while (downloading) {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(downloadId);
Cursor cursor = manager.query(q);
cursor.moveToFirst();
int bytes_downloaded = cursor.getInt(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = cursor.getInt(cursor.
getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (upgradeStateListener != null) {
upgradeStateListener.onDownloading((float) bytes_downloaded / bytes_total * 100);
}
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
downloading = false;
}
}
}
}).start();
}
This is the broadcast receiver which gets fired when download is completed. And I'm sure this broadcast doesn't cause my problem since the only place in the code where could cause it is the onDownloadCompleted() method(which installs the APK using root privileges and I've commented all of it's body and it still pops up the activity.
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
final Cursor cursor = manager.query( new DownloadManager.Query().setFilterById(downloadId));
if (cursor.moveToFirst()) {
Uri uri ;
final String downloadedTo = cursor.getString(
cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
uri = Uri.parse(downloadedTo);
Log.d(TAG, "onReceive: it's ok " + uri.getPath());
upgradeStateListener.onDownloadCompleted(uri.getPath());
}
setStatus(State.DOWNLOADED);
mContext.unregisterReceiver(this);
}
};
I am using DownloadManager but it puts the download somewhere I don't know. I want to download the file in a specific folder like "mp3" in sdcard.
Here is the code I am using :
private class HelloWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView webview, String url)
{
if(url.endsWith(".mp3") || !url.startsWith("http://xnm")) {
String servicestring = Context.DOWNLOAD_SERVICE;
DownloadManager downloadmanager;
downloadmanager = (DownloadManager) getSystemService(servicestring);
Uri uri = Uri.parse(url);
DownloadManager.Request request = new Request(uri);
Long reference = downloadmanager.enqueue(request);
setProgressBarIndeterminateVisibility(false);
}
else {
mWebView.loadUrl(url);
setProgressBarIndeterminateVisibility(true);
}
return true;
}
#Override
public void onPageFinished(WebView webview, String url){
super.onPageFinished(webview, url);
setProgressBarIndeterminateVisibility(false);
}
}
Thanks in advance !!
Use
File file = new File(Environment.getExternalStorageDirectory(), "mp3")
request.setDestinationUri(Uri.fromFile(file));
to set the download path
Actually I got it working after searching a lot and here it is the code to add in existing.
File folder = new File(Environment.getExternalStorageDirectory() + "/any");
if (!folder.exists()) {
folder.mkdir();
}
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDestinationInExternalPublicDir("/Download/Global Mp3", nameOfFile);
And we need this permission in manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Thats it !!! Maybe it will help someone else
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);