Android - How to download a file from a webserver

AndroidWebserverKml

Android Problem Overview


In my app I am downloading a kml file from a webserver. I have set the permission for external storage and internet in my android manifest file. I am new to Android, your help is greatly appreciated.

MainActivity.java

package com.example.demo;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		DownloadFiles();
	}

	public void DownloadFiles(){
		try {
	    	URL u = new URL("http://www.qwikisoft.com/demo/ashade/20001.kml");
	        InputStream is = u.openStream();
	        DataInputStream dis = new DataInputStream(is);

	        byte[] buffer = new byte[1024];
	        int length;

	        FileOutputStream fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/" + "data/test.kml"));
	        while ((length = dis.read(buffer)) > 0) {
	        	fos.write(buffer, 0, length);
			}

	    } catch (MalformedURLException mue) {
	    	Log.e("SYNC getUpdate", "malformed url error", mue);
	    } catch (IOException ioe) {
	    	Log.e("SYNC getUpdate", "io error", ioe);
	    } catch (SecurityException se) {
	    	Log.e("SYNC getUpdate", "security error", se);
	    }
	}
}

Android Manifest File

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.demo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        <activity
            android:name="com.example.demo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Logcat error:

> FATAL EXCEPTION: main java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.demo/com.example.demo.MainActivity}: android.os.NetworkOnMainThreadException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) at android.app.ActivityThread.access$600(ActivityThread.java:123) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4424) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method) Caused by: android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099) at java.net.InetAddress.lookupHostByName(InetAddress.java:391) at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242) at java.net.InetAddress.getAllByName(InetAddress.java:220) at libcore.net.http.HttpConnection.(HttpConnection.java:71) at libcore.net.http.HttpConnection.(HttpConnection.java:50) at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351) at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86) at libcore.net.http.HttpConnection.connect(HttpConnection.java:128) at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308) at libcore.net.http.HttpEngine.connect(HttpEngine.java:303) at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282) at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232) at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273) at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168) at java.net.URL.openStream(URL.java:462) at com.example.demo.MainActivity.DownloadFiles(MainActivity.java:30) at com.example.demo.MainActivity.onCreate(MainActivity.java:24) at android.app.Activity.performCreate(Activity.java:4465) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)

EDIT

package com.example.demo;

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;

public class MainActivity extends Activity {

	private ProgressDialog pDialog;
	public static final int progress_bar_type = 0;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		new DownloadFileFromURL().execute("http://www.qwikisoft.com/demo/ashade/20001.kml");
	}

	@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;
        }
    }

	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 conection = url.openConnection();
                conection.connect();

                // this will be useful so that you can show a tipical 0-100%
                // progress bar
                int lenghtOfFile = conection.getContentLength();

                // download the file
                InputStream input = new BufferedInputStream(url.openStream(),
                        8192);

                // Output stream
                OutputStream output = new FileOutputStream(Environment
                        .getExternalStorageDirectory().toString()
                        + "/data/downloadedfile.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);
        }
    }
}

When I run this code in the emulator the code still does not work - the file is not getting downloaded.

Android Solutions


Solution 1 - Android

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); 

Solution 2 - Android

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))
}

Solution 3 - Android

I would recommend using Android DownloadManager

DownloadManager downloadmanager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse("http://www.example.com/myfile.mp3");

DownloadManager.Request request = new DownloadManager.Request(uri);
request.setTitle("My File");
request.setDescription("Downloading");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setVisibleInDownloadsUi(false);
request.setDestinationUri(Uri.parse("file://" + folderName + "/myfile.mp3"));

downloadmanager.enqueue(request);

Solution 4 - Android

Download File Usind Download Manager

    DownloadManager downloadmanager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
    Uri uri = Uri.parse("https://www.globalgreyebooks.com/content/books/ebooks/game-of-life.pdf");

    DownloadManager.Request request = new DownloadManager.Request(uri);
    request.setTitle("My File");
    request.setDescription("Downloading");//request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"game-of-life");
    downloadmanager.enqueue(request);

Solution 5 - Android

It is bad practice to perform network operations on the main thread, which is why you are seeing the NetworkOnMainThreadException. It is prevented by the policy. If you really must do it for testing, put the following in your OnCreate:

 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
 StrictMode.setThreadPolicy(policy); 

Please remember that is is very bad practice to do this, and should ideally move your network code to an AsyncTask or a Thread.

Solution 6 - Android

Mr.Iam4fun your code answer here..You will use thread...

   findViewById(R.id.download).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           
            new Thread(new Runnable() {
                public void run() {
                    DownloadFiles();
                }
            }).start();

And,then..

 public void DownloadFiles(){

        try {
            URL u = new URL("http://www.qwikisoft.com/demo/ashade/20001.kml");
            InputStream is = u.openStream();

            DataInputStream dis = new DataInputStream(is);

            byte[] buffer = new byte[1024];
            int length;

            FileOutputStream fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/" + "data/test.kml"));
            while ((length = dis.read(buffer))>0) {
              fos.write(buffer, 0, length);
            }

          } catch (MalformedURLException mue) {
            Log.e("SYNC getUpdate", "malformed url error", mue);
          } catch (IOException ioe) {
            Log.e("SYNC getUpdate", "io error", ioe);
          } catch (SecurityException se) {
            Log.e("SYNC getUpdate", "security error", se);
          }
}
}

Solution 7 - Android

use AsyncTask and

put your download file code in doinbackground of it..

android don't allow anymore to do heavy tasks on main thread to avoid ANR(Application not responding) error

Solution 8 - Android

You should use an AsyncTask (or other way to perform a network operation on background).

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //create and execute the download task
    MyAsyncTask async = new MyAsyncTask();
    async.execute();
    
}

private class MyAsyncTask extends AsyncTask<Void, Void, Void>{

    //execute on background (out of the UI thread)
    protected Long doInBackground(URL... urls) {
        DownloadFiles();
    }

}

More info about AsyncTask on Android documentation

Hope it helps.

Solution 9 - Android

Run these codes in thread or AsyncTask. In order to avoid duplicated callings of same _url(one time for getContentLength(), one time of openStream()), use IOUtils.toByteArray of Apache.

void downloadFile(String _url, String _name) {
	try {
		URL u = new URL(_url);
		DataInputStream stream = new DataInputStream(u.openStream());
		byte[] buffer = IOUtils.toByteArray(stream);
		FileOutputStream fos = mContext.openFileOutput(_name, Context.MODE_PRIVATE);
		fos.write(buffer);
		fos.flush();
		fos.close();
	} catch (FileNotFoundException e) {
		e.printStackTrace();
		return;
	} catch (IOException e) {
		e.printStackTrace();
		return;
	}
}

Solution 10 - Android

Apart from using AsyncTask you can put the operation in runnable-

Runnable r=new Runnable()
{

public void run()
{
///-------network operation code
}
};

//--------call r in this way--
Thread t=new Thread(r);`enter code here`
t.start();

Also put the UI work in a handler..such as updating a textview etc..

Solution 11 - Android

Here is the code help you to download file from server at the same time you can see the progress of downloading on your status bar.

See the functionality in below image of my code:

enter image description here enter image description here

STEP - 1 : Create on DownloadFileFromURL.java class file to download file content from server. Here i create an asynchronous task to download file.

public class DownloadFileFromURL extends AsyncTask<String, Integer, String> {

private NotificationManager mNotifyManager;
private NotificationCompat.Builder build;
private File fileurl;
int id = 123;
OutputStream output;
private Context context;
private String selectedDate;
private String ts = "";

public DownloadFileFromURL(Context context, String selectedDate) {
    this.context = context;
    this.selectedDate = selectedDate;

}

protected void onPreExecute() {
    super.onPreExecute();

    mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    build = new NotificationCompat.Builder(context);
    build.setContentTitle("Download")
            .setContentText("Download in progress")
            .setChannelId(id + "")
            .setAutoCancel(false)
            .setDefaults(0)
            .setSmallIcon(R.drawable.ic_menu_download);

    // Since android Oreo notification channel is needed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(id + "",
                "Social Media Downloader",
                NotificationManager.IMPORTANCE_HIGH);
        channel.setDescription("no sound");
        channel.setSound(null, null);
        channel.enableLights(false);
        channel.setLightColor(Color.BLUE);
        channel.enableVibration(false);
        mNotifyManager.createNotificationChannel(channel);

    }
    build.setProgress(100, 0, false);
    mNotifyManager.notify(id, build.build());
    String msg = "Download started";
    //CustomToast.showToast(context,msg);
}

@Override
protected String doInBackground(String... f_url) {
    int count;
    ts = selectedDate.split("T")[0];
    try {
        URL url = new URL(f_url[0]);
        URLConnection conection = url.openConnection();
        conection.connect();
        int lenghtOfFile = conection.getContentLength();

        InputStream input = new BufferedInputStream(url.openStream(),
                8192);
        // Output stream
        output = new FileOutputStream(Environment
                .getExternalStorageDirectory().toString()
                + Const.DownloadPath + ts + ".pdf");
        fileurl = new File(Environment.getExternalStorageDirectory()
                + Const.DownloadPath + ts + ".pdf");
        byte[] data = new byte[1024];

        long total = 0;

        while ((count = input.read(data)) != -1) {
            total += count;
            int cur = (int) ((total * 100) / lenghtOfFile);

            publishProgress(Math.min(cur, 100));
            if (Math.min(cur, 100) > 98) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Log.d("Failure", "sleeping failure");
                }
            }
            Log.i("currentProgress", "currentProgress: " + Math.min(cur, 100) + "\n " + cur);

            output.write(data, 0, count);
        }

        output.flush();

        output.close();
        input.close();

    } catch (Exception e) {
        Log.e("Error: ", e.getMessage());
    }

    return null;
}

protected void onProgressUpdate(Integer... progress) {
    build.setProgress(100, progress[0], false);
    mNotifyManager.notify(id, build.build());
    super.onProgressUpdate(progress);
}

@Override
protected void onPostExecute(String file_url) {
    build.setContentText("Download complete");
    build.setProgress(0, 0, false);
    mNotifyManager.notify(id, build.build());
} }

Note: If you want code with import package then Click Here

Now Step 2: You need to call above ayncronous task on your click event. for example i have set on pdf image icon. To call AsyncTask use below code:

 new DownloadFileFromURL(fContext,filename).execute(serverFileUrl);

Note: Here You can see filename variable in file parameter. This is the name which i use to save my downloaded file in local device. currently i am downloading only pdf file but you can use you url in serverFileUrl parameter.

Solution 12 - Android

When you click on download button, first you have to create local storage path where you want to save it, we should put download file functionality into ExecutorService(that is used instead of AsyncTask because AsyncTask is deprecated).

// Create bamchik folder if not created yet
val folder = File(context?.getExternalFilesDir(null)?.absoluteFile, "MusicTrack")
val check = folder.mkdirs()
Log.v(mTAG, "check: $check")
var path = context?.getExternalFilesDir(null)?.absolutePath + "/MusicTrack/music." + fileExt
val SDK_INT = Build.VERSION.SDK_INT
if (SDK_INT > 8) {
    val policy: StrictMode.ThreadPolicy = StrictMode.ThreadPolicy.Builder().permitAll().build()
    StrictMode.setThreadPolicy(policy)
    val executor: ExecutorService = Executors.newSingleThreadExecutor()
    val handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            // Length is the total size of file and progress is how much file have been downloaded, now you can show progress according to this
            val (progress, length) = msg.obj as Pair<Long, Long> 
            Log.v(mTAG, "Progress: $progress, Length: $length")
        }

    }

    executor.execute {
        //Background work here
        download(link, path) { progress, length ->
            // handling the result on main thread
            handler.sendMessage(handler.obtainMessage(0, progress to length))
        }
        handler.post {
            //UI Thread work here
        }
    }
}

Function of download file from url

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
        }
    }
}

Solution 13 - Android

This is how I download using retrofit, save and return a file to the viewmodel :)

interface FileDownloader { companion object { private val instance: FileDownloader by lazy {

        val loggingInterceptor = HttpLoggingInterceptor()
        loggingInterceptor.level = HttpLoggingInterceptor.Level.HEADERS

        val client = OkHttpClient.Builder()
            .connectTimeout(120, TimeUnit.SECONDS)
            .readTimeout(300, TimeUnit.SECONDS)
            .callTimeout(300, TimeUnit.SECONDS)
            .addInterceptor(loggingInterceptor)
            .build()

        val downloaderApi = Retrofit.Builder()
            .baseUrl("https://exmaple.com")
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build()
            .create(FileDownloader::class.java)

        downloaderApi
    }

    suspend fun downloadAndSaveFile(
        url: String
    ): File {
        val file = getPdfFile()
        val responseBody = try {
            instance.downloadFile(url)
        } catch (e: Exception) {
            throw FileDownloadException(url, e)
        }
        @Suppress("BlockingMethodInNonBlockingContext")
        try {
            FileOutputStream(file).use { outputStream ->
                responseBody.byteStream().use { inputStream ->
                    inputStream.copyTo(outputStream)
                }
            }
        } catch (e: Exception) {
            throw FileDownloadException(url, e)
        }
        return file
    }


}

@GET
@Streaming
suspend fun downloadFile(@Url utl: String): ResponseBody
}

fun getPdfFile(): File {
    File(App.appContext.filesDir, "pdfs").apply { mkdirs() }
    return File(App.appContext.filesDir, "tempPDF.pdf")
}

class FileDownloadException(url: String, e: Exception) : Throwable()

Solution 14 - Android

Starting from api level 11 or Honeycomb doing network operations on main thread is forbidden. Use thread or asynctask. For more info visit https://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIam4funView Question on Stackoverflow
Solution 1 - AndroidNirav RanparaView Answer on Stackoverflow
Solution 2 - AndroidVladView Answer on Stackoverflow
Solution 3 - AndroidAwsom3DView Answer on Stackoverflow
Solution 4 - AndroidAnkush ShrivastavaView Answer on Stackoverflow
Solution 5 - Androidtristan2468View Answer on Stackoverflow
Solution 6 - AndroidMathan ChinnaView Answer on Stackoverflow
Solution 7 - AndroidDeltaCap019View Answer on Stackoverflow
Solution 8 - AndroidsabadowView Answer on Stackoverflow
Solution 9 - AndroidTeeTrackerView Answer on Stackoverflow
Solution 10 - Androiduser6823720View Answer on Stackoverflow
Solution 11 - AndroidNimesh PatelView Answer on Stackoverflow
Solution 12 - AndroidsunnyView Answer on Stackoverflow
Solution 13 - AndroidAmin KeshavarzianView Answer on Stackoverflow
Solution 14 - AndroidBekView Answer on Stackoverflow