Как многие люди предлагали использовать отложенный вариант, это хороший вариант, если вам неважно, в каком порядке deviceready
и mobileinit
happe. Но в моем случае мне понадобилось несколько pageshow
событий, когда приложение сначала загружены и mobileinit
, и по расширению все события pageshow
/ pagebeforeshow
/ etc были полностью запущены до завершения deviceready
, поэтому я не мог привязываться к ним правильно, используя отложенные на них. Это состояние гонки было не очень хорошим.
Что мне нужно было сделать, так это убедиться, что «mobileinit» не состоялся до тех пор, пока «deviceready
» уже не был запущен. Поскольку mobileinit
срабатывает сразу же при загрузке JQM, я решил использовать jQuery.getScript
для его загрузки ПОСЛЕ deviceready
.
<script src="cordova-2.2.0.js"></script>
<script src="js/jquery-1.8.2.min.js"></script>
<script src="js/async.min.js"></script>
<script src="js/app.js"></script>
<script>
document.addEventListener(
'deviceready',
function () {
$('body').css('visibility', 'hidden');
$(document).one("mobileinit", function () {
app.init();
$('body').css('visibility', '');
});
$.getScript('js/jquery.mobile-1.2.0.min.js');
},
false
);
</script>
Причина, по которой я скрываю тело, заключается в том, что сторона Эффект этого метода составляет половину секунды видимости исходного HTML-документа до загрузки jquery.mobile. В этом случае скрыть его лишнюю половину секунды пустого пространства предпочтительнее видеть неизданный документ.
Вы можете следовать процедуре сохранения файла модифицированного файла вместо менеджера загрузки
https://futurestud.io/tutorials/retrofit-2-how-to-download-files-from-server [ 110]
Я также использовал другой способ загрузки файла с сервера.
Первый, который вы уже используете как 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
}
}
3-й, который, я думаю, лучше всего подходит для больших файлов, чтобы загрузить файл, используя стороннюю библиотеку. Сетевая библиотека 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 каждого файла, при первом запуске загрузки затем получить файл MD5, а затем проверить, соответствуют ли хэши загруженным фрагментам. Если они этого не сделают, удалите этот фрагмент и добавьте его в очередь для загрузки.
После того, как все фрагменты загружены и MD5 работает, вы можете собрать их вместе в один файл.
Если вы хотите загрузить файл на SD-карту, тогда FAT32 является файловой системой по умолчанию.