Md. Iqbal Hosssain
Md. Iqbal Hosssain

Reputation: 33

Download Manager in android studio will not download big size file in Samsung device

I have a button to download file from localhost. It works for small size file like 1-2 MB but not working for big size file like 10-15 MB. I have attached my code.

pdf_download.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
            Uri uri = Uri.parse(base_url+pdf);
            DownloadManager.Request request = new DownloadManager.Request(uri);
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            Long reference = downloadManager.enqueue(request);
        }
    });

Upvotes: 1

Views: 1443

Answers (3)

Aravind V
Aravind V

Reputation: 358

You can follow the retrofit file saving procedure instead of download manager

https://futurestud.io/tutorials/retrofit-2-how-to-download-files-from-server

Upvotes: 0

Mudassir Khan
Mudassir Khan

Reputation: 1782

I have also used different way to download a file from server.

first one which you already are using as DowanloadManager

2nd one was to use AsyncTask to Download a file.

class DownloadTask : AsyncTask<String, Int, String>() {

    lateinit var downloadTaskListener: DownloadTaskListener
    lateinit var pm: PowerManager
    private var mWakeLock: PowerManager.WakeLock? = null
   // private lateinit var mProgressBar: ProgressBar
    private var fileName: String? = null
    private var fileNameWithoutExtn: String? = null
    private val dialog: Dialog? = null
   // private var alertDialog: AlertDialog? = null
    //lateinit var txtFileSize: TextView
    internal var total: Long = 0
    private var fileLength: Int = 0

    //lateinit var btnCancel: Button


    override fun doInBackground(vararg sUrl: String): String? {
        var input: InputStream? = null
        var output: OutputStream? = null
        var connection: HttpURLConnection? = null
        var outPutFile: File? = null
        try {
            val url = URL(sUrl[0])
            connection = url.openConnection() as HttpURLConnection
            connection.connect()

            // expect HTTP 200 OK, so we don't mistakenly save error report
            // instead of the file
            if (connection.responseCode != HttpURLConnection.HTTP_OK) {
                return ("Server returned HTTP " + connection.responseCode
                        + " " + connection.responseMessage)
            }

            // this will be useful to display download percentage
            // might be -1: server did not report the length
            fileLength = connection.contentLength

            // download the file
            input = connection.inputStream
            fileName = sUrl[0].substring(sUrl[0].lastIndexOf('/') + 1, sUrl[0].length)

            fileNameWithoutExtn = fileName!!.substring(0, fileName!!.lastIndexOf('.'))
            Log.d("check", "name $fileName without extention $fileNameWithoutExtn")
            outPutFile = downloadTaskListener.getFilePath("$fileNameWithoutExtn.apk")
            output = FileOutputStream(outPutFile)

            val data = ByteArray(4096)
            total = 0
            var count: Int=input.read(data)
            while (count != -1) {
                // allow canceling with back button or click on Cancel button
                if (isCancelled) {
                    output.flush()
                    output.close()
                    input!!.close()
                    return null
                }
                total += count.toLong()
                // publishing the progress....
                if (fileLength > 0)
                // only if total length is known
                    Log.d("check", total.toString() + "")
                publishProgress((total * 100 / fileLength).toInt())
                output.write(data, 0, count)
            }
        } catch (e: Exception) {
            return e.toString()
        } finally {
            try {
                output?.close()
                input?.close()
               // outPutFile!!.setReadable(true, false)


            } catch (ignored: IOException) {
            }

            connection?.disconnect()
        }
        return null
    }

    override fun onPreExecute() {
        super.onPreExecute()
        // take CPU lock to prevent CPU from going off if the user
        // presses the power button during download
//        val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
        mWakeLock = pm.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,
            javaClass.name
        )
        mWakeLock!!.acquire()

//
//        val dialogBuilder = AlertDialog.Builder(context)
//        // ...Irrelevant code for customizing the buttons and title
//        val inflater = LayoutInflater.from(context)
//        val customProgress = inflater.inflate(R.layout.custom_progress_dialog, null)
//        dialogBuilder.setView(customProgress)
//
//        alertDialog = dialogBuilder.create()
//        alertDialog!!.setCancelable(false)
//
//        mProgressBar = customProgress.findViewById(R.id.downloadProgressBar)
//        mProgressBar!!.progressDrawable = context.resources.getDrawable(R.drawable.custom_progress)
//        txtFileSize = customProgress.findViewById(R.id.txt_file_size)
//        txtFileSize.text = "Downloading is starting ...."
//        btnCancel = customProgress.findViewById(R.id.btnCancel)
       downloadTaskListener.showDialog()
//        txtFileSize= alertDialog!!.txt_file_size
//        mProgressBar= alertDialog!!.downloadProgressBar
//        btnCancel= alertDialog!!.btnCancel
        downloadTaskListener.getCancelButton().setOnClickListener { cancel(true) }
        downloadTaskListener.updateDialogData(0,"Downloading is starting ....")
        //        dialog.show();
      //  alertDialog!!.show()

        downloadTaskListener.showDialog().show()
    }

    // Display the async tas progress
    override fun onProgressUpdate(vararg values: Int?) {
        downloadTaskListener.updateDialogData(values[0]!!,"Download progress : " + Utils.bytes2String(total) + "/" + Utils.bytes2String(fileLength.toLong()))
//        mProgressBar.progress = values[0]!!
//        mProgressBar.setMax(100)
//        txtFileSize.text = "Download progress : " + Utils.bytes2String(total) + "/" + Utils.bytes2String(fileLength.toLong())
       // downloadTaskListener.showToast("Downloaded ${values[0]} %")
        super.onProgressUpdate(values[0])
    }


    override fun onPostExecute(result: String?) {
        mWakeLock!!.release()
        //mProgressDialog.dismiss();
        //dialog.dismiss();
        downloadTaskListener.showDialog()!!.dismiss()
        if (result != null)
//            Toast.makeText(context, "Download error: $result", Toast.LENGTH_LONG).show()
        downloadTaskListener.showToast("Download error: $result")
        else {
//            Toast.makeText(context, "Apk downloaded", Toast.LENGTH_SHORT).show()
            downloadTaskListener.showToast("Apk downloaded")
           // txtFileSize.text = "APK Downloaded Completely."
            downloadTaskListener.updateDialogData(100,"APK Downloaded Completely.")
           // val file = File(Utils.getAbsoluteFile("", context), "$fileNameWithoutExtn.apk")
            val file=downloadTaskListener.getFilePath("$fileNameWithoutExtn.apk")
            //File file = new File("/sdcard/update.apk");
            var fileUri = Uri.fromFile(file)
            if (file.exists()) {
                Log.d("check", "file exists " + file.absolutePath + fileUri)
            } else {
                Log.d("check", "file does not exist " + file.absolutePath)
            }
            if (Build.VERSION.SDK_INT >= 24) {
//                fileUri = FileProvider.getUriForFile(
//                    context,
//                    context.applicationContext.packageName + ".my.package.name.provider",
//                    file
//                )
            }
            val intent = Intent(Intent.ACTION_VIEW, fileUri)
            intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
            intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive")
            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
//            context.startActivity(intent)
            downloadTaskListener.startActivity(intent)
        }

    }

    override fun onCancelled(s: String) {
        super.onCancelled(s)
        Log.d("TASK TAG", "Cancelled.")
      //  txtFileSize.text = "Downloading Cancelled"
//        Toast.makeText(context, "Downloading Cancelled ", Toast.LENGTH_SHORT).show()
        downloadTaskListener.showToast("Downloading Cancelled ")
//        mProgressBar!!.progress = 0
        //alertDialog!!.dismiss()
        downloadTaskListener.updateDialogData(0, "Downloading Cancelled")
        downloadTaskListener.showDialog().dismiss()

    }

    interface DownloadTaskListener{
        fun showToast(text: String)
        fun startActivity(intent: Intent)
        fun getFilePath(fileName:String):File
        fun showDialog():AlertDialog
        fun updateDialogData(progress:Int,msg:String)
        fun getCancelButton():Button
    }
}

3rd one which i think is best for large files to download a file usig third party Library Android Networking Library first put the library in gradle

implementation 'com.amitshekhar.android:android-networking:1.0.2'

then write this code

AndroidNetworking.download(url,dirPath,fileName)
                 .setTag("downloadTest")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .setDownloadProgressListener(new DownloadProgressListener() {
                    @Override
                    public void onProgress(long bytesDownloaded, long totalBytes) {
                      // do anything with progress  
                    }
                 })
                 .startDownload(new DownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                      // do anything after completion
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error    
                    }
                }); 

Upvotes: 1

Aravind V
Aravind V

Reputation: 358

To download such a large files, you need to download those in chunks. Either you can use any library that support HTTP range options to allow to pull down a single file in multiple pieces , supporting resume etc.

Or you can split your large file on your server then have a text file with MD5 hash of each file, when you first start to download then get the MD5 file once finish then check that hashes matches the downloaded pieces. If they do not then delete that piece and add it to queue of items to download.

Once all pieces downloaded and MD5 works, you can put the pieces back together as single file.

If you are thinking to download the file in the SD card then FAT32 is the default file system.

Upvotes: 0

Related Questions