Control the download ordering of Download manager in android - android

have an use case like the following:
There are several files to download e.g. A B C D E F
When the downloading is started , say the A B is finished and C is downloading, I would like to interrupt the download of C and start the download of E
Then, after E is finished (if there is no other interruption), continue to C D F.
So far form my research there is only cancel method
downloadManager.remove(downloadReference);
How to achieve this through Download manager or are there other approach ? thanks
private long startDownload(String url) {
Uri DownloadUri = Uri.parse(url);
String fileName = StorageUtils.getFileNameFromUrl(url);
String destination = null;
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(
DownloadUri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setAllowedOverRoaming(false);
request.setTitle(fileName);
request.setDescription("com.example.services");
if (StorageUtils.isSDCardPresent()
&& StorageUtils.isSdCardWrittenable()
&& StorageUtils.checkAvailableStorage()) {
destination = StorageUtils.SDCARD_ROOT;
}
try {
StorageUtils.mkdir();
} catch (IOException e) {
e.printStackTrace();
}
request.setDestinationInExternalPublicDir(destination, fileName);
downloadReference = downloadManager.enqueue(request);
Log.d("Downloader","Start download manager: " + destination + fileName);
return downloadReference;
}

Regarding this answer, it looks like you can cancel the download and then download the rest of the file. For example:
Register a BrodcastReciever to notify you when C is completed:
BroadcastReceiver onComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//check if it is B that is complete
//cancel C
// download E
//check if it is E that is complete
// Open connection to URL.
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
// Specify what portion of file to download.
connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
// here "downloaded" is the data length already previously downloaded.
// Connect to server.
connection.connect();
}
};
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
//download A
//download B
//download C

Related

Android unable to open file after download

I am downloading a pdf file using DownloadManager class. It works fine on a Huawei GRA-L09 with android 5.0.1 but on my Nexus 6p with android 7.1.1 I experience the following behavior:
After the file is downloaded I try to open it via intent Action_View so it will be opened with pdf viewer. But when I try to open it I got an error that the file size is 0 and cannot be opened. If I wait about 10 seconds I am able to open the file.
This is the source code of DownloadManager:
DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir("/Download", "test.pdf");
long enqueue = dm.enqueue(request);
This is the source code of the BroadcastReceiver:
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(enqueue);
Cursor cursor = null;
String uri = null;
String mime = null;
try {
cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
if (status == DownloadManager.STATUS_SUCCESSFUL) {
// process download
uri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
mime = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE));
}
}
} finally {
if (cursor != null) {
cursor.close();
}
}
openFile(Uri.parse(uri), mime);
}
}
};
private void openFile(final Uri fileLocation, final String mimeType) {
Intent objIntent = new Intent(Intent.ACTION_VIEW);
objIntent.setDataAndType(fileLocation, mimeType);
Log.d(Constants.TAG, "Downloaded file Uri: " + fileLocation.toString() + " mime:" + mimeType);
objIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Intent chooserIntent = Intent.createChooser(objIntent, getString(R.string.choose_application));
startActivity(chooserIntent);//Starting the pdf viewer
}
I tried opening it without the intent for pdf, just by pressing the notification icon on the status bar. The same thing happens, as if the file is locked or not downloaded yet.
UPDATE: On the Nexus device I get file size = 0 when i check file.length() after the download is completed. On the Huawei GRA-L09 the file size is 1882670.
So why do I get Download completed broadcast for a file with size 0?

Android : How to pause and resume using DownloadManager?

this is my code and i want to add resumable feature but i couldn't is it posible?
downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
Uri Download_Uri = Uri.parse("http://download.thinkbroadband.com/20MB.zip");
DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
//Restrict the types of networks over which this download may proceed.
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
//Set whether this download may proceed over a roaming connection.
request.setAllowedOverRoaming(false);
//Set the title of this download, to be displayed in notifications (if enabled).
request.setTitle("My Data Download");
//Set a description of this download, to be displayed in notifications (if enabled)
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(this, Environment.DIRECTORY_DOWNLOADS,"20MB.zip");
//Enqueue a new download and same the referenceId
downloadReference = downloadManager.enqueue(request);
I was able to implement Pause/Resume functionality using the following implementation via the Android DownloadManager and Downloads Content Provider:
private boolean resumeDownload(Context context, String downloadTitle) {
int updatedRows = 0;
ContentValues resumeDownload = new ContentValues();
resumeDownload.put("control", 0); // Resume Control Value
try {
updatedRows = context
.getContentResolver()
.update(Uri.parse("content://downloads/my_downloads"),
resumeDownload,
"title=?",
new String[]{ downloadTitle });
} catch (Exception e) {
Log.e(TAG, "Failed to update control for downloading video");
}
return 0 < updatedRows;
}
private boolean pauseDownload(Context context, String downloadTitle) {
int updatedRows = 0;
ContentValues pauseDownload = new ContentValues();
pauseDownload.put("control", 1); // Pause Control Value
try {
updatedRows = context
.getContentResolver()
.update(Uri.parse("content://downloads/my_downloads"),
pauseDownload,
"title=?",
new String[]{ downloadTitle });
} catch (Exception e) {
Log.e(TAG, "Failed to update control for downloading video");
}
return 0 < updatedRows;
}

Download Files Using download manager

I am downloading files from server using DownloadManager class
Here is what i am doing
public void downloadPdf(String url, String sem, String title, String branch) {
Uri Download_Uri = Uri.parse(url);
DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
//Restrict the types of networks over which this download may proceed.
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
//Set whether this download may proceed over a roaming connection.
request.setAllowedOverRoaming(false);
//Set the title of this download, to be displayed in notifications (if enabled).
request.setTitle("Downloading");
//Set a description of this download, to be displayed in notifications (if enabled)
request.setDescription("Downloading File");
//Set the local destination for the downloaded file to a path within the application's external files directory
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, title + "_" + branch + "_" + sem + "Year" + System.currentTimeMillis() + ".pdf");
//Enqueue a new download and same the referenceId
downloadReference = downloadManager.enqueue(request);
}
thing is when download is complete if then user clicks on notification it should open that file what should i do in this code
BroadcastReceiver onNotificationClick = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
}
};
Please help
Finally fixed this by just 2 lines
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

Android DownloadManager never returns ERROR_FILE_ALREADY_EXISTS

I am using DonwloadManager in my project, in the official reference there is description about ERROR_FILE_ALREADY_EXISTS. The problem is that I never get this error while using the same URL and Destination URI. DownloadManager is always downloads the same file, just adds some number at the end of the file name so it will be different from the previous download.
The enqueue code is really simple and working great, except this weird thing that allows you to re-download already downloaded file:
Uri uri = Uri.parse(url);
Request request = new Request(uri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE |
DownloadManager.Request.NETWORK_WIFI);
request.setVisibleInDownloadsUi(false);
Uri fileDestinationUri = Uri.parse("file://" + new File(destinationFilePath);
request.setDestinationUri(fileDestinationUri);
long downloadId = downloadManager.enqueue(request);
I have a BroadcastReciever which is listening to android.intent.action.DOWNLOAD_COMPLETE intent:
#Override
public void onReceive(Context context, Intent intent) {
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
Query query = new Query();
query.setFilterById(downloadId);
Cursor cur = dm.query(query);
if (cur.moveToFirst()) {
int columnIndex = cur.getColumnIndex(DownloadManager.COLUMN_STATUS);
switch (cur.getInt(columnIndex)) {
case DownloadManager.STATUS_SUCCESSFUL:
Log.d(Settings.TAG_APP, "Download successfully completed.");
break;
case DownloadManager.STATUS_FAILED:
int columnReasonIndex = cur.getColumnIndex(DownloadManager.COLUMN_REASON);
Log.d(Settings.TAG_APP, "Download failed with error: " + cur.getInt(columnReasonIndex));
break;
}
}
cur.close();
cur = null;
}
I found another 2 questions that somehow connects to my question, but without answers as well :
Android - Overwrite files when downloading via Download Manager
How can i make download manager overwrite an exisiting file instead of renaming the file in android

Downloading an mp3 file from server in android

I am trying to create an app that can download music files, .mp3 to be precise, from the server.As I am a rookie in this Android Development field so I will appreciate any help from you guys.
I need something to start on and I will really appreciate if u can give me some links for useful resources.
Thanks
If you want to play the .mp3 file from any url then follow the code suggested by nik.
But if you want to download a file form the server and store it in any place on sdcard or internal storage device then follow this code,
private class DownloadFile extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... urlParams) {
int count;
try {
URL url = new URL("url of your .mp3 file");
URLConnection conexion = url.openConnection();
conexion.connect();
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// downlod the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/somewhere/nameofthefile.mp3");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int)(total*100/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
EDIT: manifest permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
You can do it this way:
try {
MediaPlayer player = new MediaPlayer();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource("http://xty/MRESC/images/test/xy.mp3");
player.prepare();
player.start();
} catch (Exception e) {
// TODO: handle exception
}
Manifest permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Use this method
private void beginDownload(){
/*
Create a DownloadManager.Request with all the information necessary to start the download
*/
DownloadManager.Request request=new DownloadManager.Request(Uri.parse("http://examplewebsite.com/aaa.mp3"))
.setTitle("Dummy File")// Title of the Download Notification
.setDescription("Downloading")// Description of the Download Notification
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)// Visibility of the download Notification
// Uri of the destination file
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "" + System.currentTimeMillis());
.setRequiresCharging(false)// Set if charging is required to begin the download
.setAllowedOverMetered(true)// Set if download is allowed on Mobile network
.setAllowedOverRoaming(true);// Set if download is allowed on roaming network
DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
downloadID = downloadManager.enqueue(request);// enqueue puts the download request in the queue.
}
Here is the full code
private Button btnDownload;
private long downloadID;
private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Fetching the download id received with the broadcast
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
//Checking if the received broadcast is for our enqueued download by matching download id
if (downloadID == id) {
Toast.makeText(MainActivity.this, "Download Completed", Toast.LENGTH_SHORT).show();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=findViewById(R.id.download);
registerReceiver(onDownloadComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
btnDownload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
beginDownload();
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(onDownloadComplete);
}
private void beginDownload(){
File file=new File(getExternalFilesDir(null),"Dummy");
/*
Create a DownloadManager.Request with all the information necessary to start the download
*/
DownloadManager.Request request=new DownloadManager.Request(Uri.parse("http://speedtest.ftp.otenet.gr/files/test10Mb.db"))
.setTitle("Dummy File")// Title of the Download Notification
.setDescription("Downloading")// Description of the Download Notification
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)// Visibility of the download Notification
.setDestinationUri(Uri.fromFile(file))// Uri of the destination file
.setRequiresCharging(false)// Set if charging is required to begin the download
.setAllowedOverMetered(true)// Set if download is allowed on Mobile network
.setAllowedOverRoaming(true);// Set if download is allowed on roaming network
DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
downloadID = downloadManager.enqueue(request);// enqueue puts the download request in the queue.

Categories

Resources