I created a recording application, user can upload data to google firebase and also can restore the data. That's it, that's all my app does. Now I tested my restoring process with 600 files (mp3 files), then I saw that when I call download manager then the files start downloading but they download one at a time which makes the process very time-consuming. So is there any way to make Download manager to download all the files simultaneously.
void startDownloading(String DownloadUrl, String DownloadPath, String DownloadName) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DownloadUrl));
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setTitle("Data");
request.setDescription("Journals");
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
request.setDestinationInExternalPublicDir(DownloadPath, DownloadName);
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
}
So I download the files by sending the link, path, and name of the file into the above method, and then task get added to DownloadManager in android device.
How to allow download Manager to download all of them simultaneously as we do in other browsers.
See if you are downloading using download manager then we can download a single file at a time and it depends on the device actually. Many phones have advance download manager but some have a simple manager who can download a single file at a time.
So solution is here instead of calling the download manager we can use this code to download files, it is awesome and always works fine. It downloads all the files simultaneously.
Here is the code:
void startDownloading
(final String DownloadUrl, String DownloadPath, String DownloadName) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
final File file = new File(StringManager.phoneStorageLocation + "/"
+ DownloadPath + "/" + DownloadName);
if (file.exists()) { // decide what to do
} else {
new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(DownloadUrl);
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
FileOutputStream fos = new FileOutputStream(file);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
} catch (IOException ignored) {
}
}
}).start();
}
}
The above code will download the file in phone storage, Hope it helps someone.
Related
I am trying to write an app that allows me to connect to my Olympus camera through wifi, and use it's built-in server to pull my raw images from it. My problem is that, when I'm on the camera's wifi, downloadManager doesn't seem to work, only when I connect my phone to the web. Am I missing something here, or is this tool really not fit for this task?
My DownloadManager:
public void getImage(String imageName, Context context) {
File file = new File(Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString(), imageName);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse("http://192.168.0.10/DCIM/100OLYMP/" + imageName))
.setTitle(imageName + ": OlyRaw Image")
.setDescription("Downloading")
.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DCIM, imageName)
.setAllowedOverMetered(true)
.setRequiresCharging(false)
.addRequestHeader("user-agent", "OlympusCameraKit")
.addRequestHeader("host", "192.168.0.10")
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
Log.d("Response", "http://192.168.0.10/DCIM/100OLYMP/" + imageName);
DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
try{
downloadId = downloadManager.enqueue(request);
Log.d("Response", String.valueOf(downloadId));
}
catch (Exception e) {
Log.d("Response", e.toString());
}
}
I have the same issue : as soon as I use my mobile as a hotspot, DownloadManager is not working. I get a download failure notification with no additional information.
There is nothing in the intent get in onReceive method of the registered BroadcastReceiver
I works like a charm if the 2 devices are connected to my home WIFI.
i want to update the sqlite database of the app when clicking on a button using the DownloadManager.
But it says "java.lang.IllegalArgumentException: Not a file URI: /data/user/0/com.example.laudien.listviewtesting/databases/Employees"
What do i make wrong? Do i need a permission for that? The internet permission is already in the manifest.
Here is the code of my updateDb() method:
private void updateDb() {
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); // create download manager
DownloadFinishedReceiver receiver = new DownloadFinishedReceiver(); // create broadcast receiver
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); // register the receiver
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DATABASE_URL)); // create a download request
// delete database file if it exists
File databaseFile = new File(getDatabasePath(DATABASE_NAME).getAbsolutePath());
if(databaseFile.exists())
databaseFile.delete();
request//.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN) // not visible
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI) // only via wifi
.setDestinationUri(Uri.parse("file:" + getDatabasePath(DATABASE_NAME).getAbsolutePath())); // set path in app dir
downloadManager.enqueue(request); // enqueue the download request
}
Your path /data/user/0/com.example.laudien.listviewtesting is private internal memory of your app. You obtained it using getFilesDir(). Other apps have no access. Including the download manager. Use external memory given by getExternalStorageDirectory() instead.
For anyone who wants to download sensitive files to app's private folders, I have to say that download manager doesn't have access to these folders inside internal storage.
But the solution is moving the downloaded file in broadcast receiver.
For example putting such line in BroadcastReceiver:
String destinationFileName = "test.mp4";
String filePath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
copyFile(Uri.parse(filePath).getPath(), context.getFilesDir() + "/" + destinationFileName);
and copyFile is a method like this:
private void copyFile(String inFileName, String outFileName) throws IOException {
InputStream myInput = new FileInputStream(inFileName);
OutputStream myOutput = new FileOutputStream(outFileName);
// Transfer bytes from the input file to the output file
byte[] myBuffer = new byte[1024];
int length;
while ((length = myInput.read(myBuffer)) > 0)
myOutput.write(myBuffer, 0, length);
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
I'm just playing around with Android Studio and I'm trying to figure out how to Download a file into /system.
I understand I need root for this and I already got that part working, the only trouble I'm having is with
request.setDestinationInExternalPublicDir("/system/", "test.jpg");
The goal is to download a file and save it to /system with the file name being test.jpg.
So the end is the file is located at /system/test.jpg.
The issue with this is that DownloadManager is saving it to internal storage and is creating a new folder named 'system'.
I can tell it has something to do with setDestinationInExternalPublicDir but I'm just not sure what to change it to.
Thanks again
What I did is that:
(It's a part in one of my projects)
/*****DOWNLOAD FILE*****/
DownloadManager.Request request = new DownloadManager.Request(Uri.parse("https://github.com/pelya/android-keyboard-gadget/blob/master/hid-gadget-test/hid-gadget-test?raw=true"));
request.setDescription("hid-gadget-test");
request.setTitle("hid-gadget-test");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "hid-gadget-test"); /*****SAVE TO DOWNLOAD FOLDER*****/
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
File mvfile = new File("/sdcard/"+Environment.DIRECTORY_DOWNLOADS+"/hid-gadget-test");
while (!mvfile.exists()) {} /*****WAIT UNTIL DOWNLOAD COMPLETE*****/
try {
Thread.sleep(5000);
} catch (InterruptedException ignored) {}
try { /*****RUN MV-COMMAND TO MOVE TO ROOT DIR*****/
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
outputStream.writeBytes("mv /sdcard/"+Environment.DIRECTORY_DOWNLOADS+"/hid-gadget-test /data/local/tmp/hid-gadget-test\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush();
su.waitFor();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "IOException", Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
Toast.makeText(getApplicationContext(), "InterruptedException", Toast.LENGTH_SHORT).show();
}
The wait-until-download-complete-thingy is a bit hacky, I found it here. It will maybe not work with files that take more than 5 seconds to download
in my Android app I am using the system Download Manager to download a photo, once recieved I process it and then I need to move it to another location. if I just copy it it works fine, if I try to move it/delete it I get an exception about it can't be moved.
Failed to delete original file '/data/user/0/com.android.providers.downloads/cache/a3133p2930-9.jpg' after copy to '/data/data/com.XXXXX.testharness/app_appdata/images/one/two/three/6/a3133p2930.jpg'
also tried:
1) remove it from download manager before trying to move it
2) set the destination directly to the target dir, but got an error I can only use public external folders.
3) tried using JAVA renameTo and Apache commons moveFile
this is a code snippet that show the relevant parts of what I am doing.
any ideas?
appreciated
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
String uriString = c.getString(
c.getColumnIndex(
DownloadManager.COLUMN_LOCAL_URI));
String uri2String = c.getString(
c.getColumnIndex(
DownloadManager.COLUMN_URI));
String localFileString = c.getString(
c.getColumnIndex(
DownloadManager.COLUMN_LOCAL_FILENAME));
File from = new File(localFileString);
File to = new File(appDataDir, localString);
File to2 = new File (appDataDir, localString + "/" + getFileNameFromUrl(uri2String));
if (!to.exists()) {
if (to.mkdirs()) {
Log.d(LCAT, "Directory Created");
}
}
dm.remove(downloadId);
//boolean a = from.renameTo(to2);
try {
FileUtils.copyFile(from, to2);
} catch (Exception e) {
Log.d(LCAT, "rename success? " + e.getMessage());
}
i think you can not delete the cache of downloadmanager, i think it clears itself automatically after you removed the downloadid from its database but if you like to have a control to your file you can set destination folder to your private external storage and then after download completed delete it.
File rootDirectory = new File(getActivity().getExternalFilesDir(null).getAbsoluteFile().toString());
if(!rootDirectory.exists()){
rootDirectory.mkdirs();
}
req.setDestinationInExternalFilesDir(getActivity(),null ,"/" + fileName);
and after your download completed you can delete it like:
from.delete();
and the doc says:
public int remove (long... ids)
Cancel downloads and remove them from
the download manager. Each download will be stopped if it was running,
and it will no longer be accessible through the download manager. If
there is a downloaded file, partial or complete, it is deleted.
http://developer.android.com/reference/android/app/DownloadManager.html#remove%28long...%29
I am writing an application wherein I want to detect if a download has started and retrieve the URI of the file being downloaded and then cancel the download from the Download Manager. I am doing this so that I can send this URI somewhere else.
The trouble is that I can detect when a download begins by querying the Download Manager, but is there a method or a constant variable in Download Manager from which I can also get the URL of the file being downloaded
Ok its weird answering your own question, but I finally figured out how to do this. There is a DownloadManager class in android.app, which stores a list of all http downloads initiated and their statuses. These can be filtered out based on whether the download is 'RUNNING', 'PENDING', 'PAUSED' and so on.
This list can be read into a cursor and one of the columns of the result is 'COLUMN_URI', which is the url from where the file is being downloaded. A sample code where I have used it is as given below:
public void readDownloadManager() {
DownloadManager.Query query = null;
DownloadManager downloadManager = null;
Cursor c = null;
try {
query = new DownloadManager.Query();
downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
//Just for testing I initiated my own download from this url. When an http
// reuest for this url is made, since download is taking place, it gets saved in
// the download manager.
Request request = new Request(Uri.parse("http://ocw.mit.edu/courses" +
"/aeronautics-and-astronautics/16-100-aerodynamics-fall-2005" +
"/lecture-notes/16100lectre1_kvm.pdf"));
downloadManager.enqueue(request);
query.setFilterByStatus(DownloadManager.STATUS_PENDING);
c = downloadManager.query(query);
if(true){
int statusColumnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
int urlColumnIndex = c.getColumnIndex(DownloadManager.COLUMN_URI);
long downloadProcessIdColumnNo = c.getColumnIndex(DownloadManager.COLUMN_ID);
Log.d("Column Count", ((Integer)c.getCount()).toString());
if(c.getCount() > 0){
String url="";
c.moveToLast();
if(c.isLast()){
url = c.getString(urlColumnIndex);
downloadManager.remove(downloadProcessIdColumnNo);
Log.d("Count after remove", ((Integer)c.getCount()).toString());
}
Log.d("After", "Stopped Working");
//Here I am sending the url to another activity, where I can work with it.
Intent intent = new Intent(EasyUploadMainMenu.this, EasyUploadActivity.class);
Bundle b = new Bundle();
b.putString("url", url);
intent.putExtras(b);
startActivity(intent);
Log.d("url:", url);
}
}
} catch (NullPointerException ex) {
ex.printStackTrace();
}
}