简体   繁体   English

android studio 中的下载管理器不会在三星设备中下载大文件

[英]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.它适用于 1-2 MB 等小文件,但不适用于 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);
        }
    });

I have also used different way to download a file from server.我还使用了不同的方式从服务器下载文件。

first one which you already are using as DowanloadManager第一个您已经用作DowanloadManager

2nd one was to use AsyncTask to Download a file.第二个是使用 AsyncTask 下载文件。

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我认为第 3 个最适合大文件下载文件使用第三方库Android 网络库首先将该库放入 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    
                    }
                }); 

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.您可以使用任何支持 HTTP 范围选项的库来允许将单个文件分成多个部分,支持恢复等。

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.或者你可以在你的服务器上拆分你的大文件,然后有一个文本文件,每个文件的 MD5 散列,当你第一次开始下载时,然后在完成后获取 MD5 文件,然后检查散列是否与下载的片段匹配。 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.一旦下载了所有片段并且 MD5 正常工作,您就可以将这些片段作为单个文件重新组合在一起。

If you are thinking to download the file in the SD card then FAT32 is the default file system.如果您想下载 SD 卡中的文件,则 FAT32 是默认文件系统。

You can follow the retrofit file saving procedure instead of download manager您可以按照改造文件保存程序而不是下载管理器

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM