Using Async task
call when you want to download file : new DownloadFileFromURL().execute(file_url);
public class MainActivity extends Activity {
// Progress Dialog
private ProgressDialog pDialog;
public static final int progress_bar_type = 0;
// File url to download
private static String file_url = "http://www.qwikisoft.com/demo/ashade/20001.kml";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadFileFromURL().execute(file_url);
}
/**
* Showing Dialog
* */
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case progress_bar_type: // we set this to 0
pDialog = new ProgressDialog(this);
pDialog.setMessage("Downloading file. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setMax(100);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setCancelable(true);
pDialog.show();
return pDialog;
default:
return null;
}
}
/**
* Background Async Task to download file
* */
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Bar Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
@Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(),
8192);
// Output stream
OutputStream output = new FileOutputStream(Environment
.getExternalStorageDirectory().toString()
+ "/2011.kml");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task Dismiss the progress dialog
* **/
@Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
}
}
}
if not working in 4.0 then add:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Answer from Nirav Ranpara on Stack OverflowUsing Async task
call when you want to download file : new DownloadFileFromURL().execute(file_url);
public class MainActivity extends Activity {
// Progress Dialog
private ProgressDialog pDialog;
public static final int progress_bar_type = 0;
// File url to download
private static String file_url = "http://www.qwikisoft.com/demo/ashade/20001.kml";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadFileFromURL().execute(file_url);
}
/**
* Showing Dialog
* */
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case progress_bar_type: // we set this to 0
pDialog = new ProgressDialog(this);
pDialog.setMessage("Downloading file. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setMax(100);
pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pDialog.setCancelable(true);
pDialog.show();
return pDialog;
default:
return null;
}
}
/**
* Background Async Task to download file
* */
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Bar Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
@Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(),
8192);
// Output stream
OutputStream output = new FileOutputStream(Environment
.getExternalStorageDirectory().toString()
+ "/2011.kml");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task Dismiss the progress dialog
* **/
@Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
}
}
}
if not working in 4.0 then add:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Simple kotlin version
fun download(link: String, path: String) {
URL(link).openStream().use { input ->
FileOutputStream(File(path)).use { output ->
input.copyTo(output)
}
}
}
is there anyway to get the download progress or downloaded size from this method ?
This is the same realization as defined in InputStream.copyTo, but with progress
/*inline*/ fun download(link: String, path: String, progress: ((Long, Long) -> Unit)? = null): Long {
val url = URL(link)
val connection = url.openConnection()
connection.connect()
val length = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) connection.contentLengthLong else
connection.contentLength.toLong()
url.openStream().use { input ->
FileOutputStream(File(path)).use { output ->
val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
var bytesRead = input.read(buffer)
var bytesCopied = 0L
while (bytesRead >= 0) {
output.write(buffer, 0, bytesRead)
bytesCopied += bytesRead
progress?.invoke(bytesCopied, length)
bytesRead = input.read(buffer)
}
return bytesCopied
}
}
}
An example of usage:
val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
// length may be negative because it is based on http header
val (progress, length) = msg.obj as Pair<Long, Long>
}
}
// call this outside of main thread
val totalSize = download("http://example.site/path/to/file", "path/to/file") { progress, length ->
// handling the result on main thread
handler.sendMessage(handler.obtainMessage(0, progress to length))
}
Videos
Give Java NIO a try:
URL website = new URL("http://www.website.com/information.asp");
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream("information.html");
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
Using transferFrom() is potentially much more efficient than a simple loop that reads from the source channel and writes to this channel. Many operating systems can transfer bytes directly from the source channel into the filesystem cache without actually copying them.
Check more about it here.
Note: The third parameter in transferFrom is the maximum number of bytes to transfer. Integer.MAX_VALUE will transfer at most 2^31 bytes, Long.MAX_VALUE will allow at most 2^63 bytes (larger than any file in existence).
Use Apache Commons IO. It is just one line of code:
FileUtils.copyURLToFile(URL, File)
You are declaring DownloadFile object but not initializing it.
private DownloadFile df;
df.Download(); // Throws NPE
Don't forget to initialize it.
private DownloadFile df = new DownloadFile();
df.Download();
EDIT:
Now you initialised the object and avoided NPE but this time you are getting a NetworkOnMainThreadException. After Honeycomb version, Android does not allow you to do network operations on main thread. You can use an AsyncTask to overcome this.
In Kotlin, This function can be useful, here try/catch avoids crash and handle send Toast to user.
After that maybe need UNZIP this file, so please see this link https://stackoverflow.com/a/76032406/12272687
fun downloadZip() {
val url = URL("http://www.Any.com/sub/name.zip")
Thread {
try {
val con: HttpURLConnection = url.openConnection() as HttpURLConnection
con.doInput = true
con.connectTimeout = 1200
con.connect()
val responseCode = con.responseCode
if (responseCode == HttpURLConnection.HTTP_OK) {
val m = con.inputStream
val inStream = BufferedInputStream(m, 1024 * 5)
val myFilename = "newFile"
val myExtensionVar = ".zip"
val file = File(
context.getDir("Music", AppCompatActivity.MODE_PRIVATE),
"/$myFilename$myExtensionVar"
)
Log.i("well", "Downloaded file: $file")
if (file.exists()) {
file.delete()
}else{
val buff = ByteArray(5 * 1024)
// Create File (Copy)
file.createNewFile()
val outStream = FileOutputStream(file)
var len:Int
while (inStream.read(buff).also { len = it } >= 0) {
outStream.write(buff, 0, len)
}
outStream.flush()
outStream.close()
inStream.close()
Log.i("well", "Done file: $file")
handler.post {
Toast.makeText(
context,
context.getString(R.string.mes_end_file), Toast.LENGTH_SHORT
).show()
}
}
}
} catch (ex: Exception) {
ex.printStackTrace()
handler.sendMessage(handler.obtainMessage(22, "OK"))
} catch (ex: IllegalThreadStateException){
println( ex.printStackTrace())
handler.sendMessage(handler.obtainMessage(22, "OK"))
}
}.start()