在Android Studio中下载Manager不会在三星设备中下载大尺寸文件



我有一个按钮可以从localhost下载文件。它适用于小型文件,例如1-2 MB,但不适用于10-15 MB(例如10-15 MB)。我已经附加了我的代码。

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

我还使用了不同的方式从服务器下载文件。

您已经使用为 dowanloadManager

的第一个

第二个是使用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
    }
}

我认为最适合大型文件下载文件的第三个第三方第三方库 Android网络库首先将图书馆放入gradle

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

然后编写此代码

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

要下载如此大的文件,您需要在块中下载这些文件。您是否可以使用任何支持HTTP范围选项的库来允许在多个零件中拉下单个文件,支持简历等。

或者您可以在服务器上拆分大型文件,然后将每个文件的MD5 Hash带有一个文本文件,当您首次开始下载时,然后在完成后获取MD5文件,然后检查哈希与下载的部分匹配。如果他们不删除该作品,然后将其添加到要下载的物品队列中。

一旦下载了所有零件,并且MD5都可以使用,您可以将这些件作为单个文件放回原处。

如果您想在SD卡中下载文件,则FAT32是默认文件系统。

您可以按照修改文件保存过程而不是下载管理器

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

最新更新