diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a10f8b..939e2f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,5 +71,16 @@ android:name="com.amap.api.navi.AmapRouteActivity" android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:theme="@android:style/Theme.NoTitleBar" /> + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a10f8b..939e2f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,5 +71,16 @@ android:name="com.amap.api.navi.AmapRouteActivity" android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:theme="@android:style/Theme.NoTitleBar" /> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt index 4d4178a..cd14d88 100644 --- a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt @@ -8,11 +8,18 @@ import com.casic.app.smartwell.R import com.casic.app.smartwell.model.ErrorMessageModel import com.casic.app.smartwell.utils.Constant +import com.casic.app.smartwell.utils.FileUtils +import com.casic.app.smartwell.utils.IDownloadListener import com.casic.app.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper +import okhttp3.* import org.json.JSONObject +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream /** * String扩展方法 @@ -61,6 +68,18 @@ return "$defaultValue/static/${this.replace("\\", "/")}" } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this}" +} + //窨井类型转换 fun String.toChinese(): String { return when (this) { @@ -86,4 +105,66 @@ this, object : TypeToken() {}.type ) return errorModel.message.toString() +} + +fun String.downloadFile(listener: IDownloadListener) { + val httpClient = OkHttpClient() + val request = Request.Builder().get().url(this).build() + val newCall = httpClient.newCall(request) + /** + * 如果已被加入下载队列,则取消之前的,重新下载 + * 断点下载以后再考虑 + * */ + if (newCall.isExecuted()) { + newCall.cancel() + } + val downloadPath = this + newCall.enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + call.cancel() + e.printStackTrace() + } + + override fun onResponse(call: Call, response: Response) { + var stream: InputStream? = null + val buf = ByteArray(2048) + var len: Int + var fos: FileOutputStream? = null + try { + val fileBody = response.body + if (fileBody != null) { + stream = fileBody.byteStream() + val total: Long = fileBody.contentLength() + listener.onDownloadStart(total) + val file = File( + FileUtils.downloadFilePath, + downloadPath.substring(downloadPath.lastIndexOf("/") + 1) + ) + fos = FileOutputStream(file) + var current: Long = 0 + while (stream.read(buf).also { len = it } != -1) { + fos.write(buf, 0, len) + current += len.toLong() + listener.onProgressChanged(current) + } + fos.flush() + listener.onDownloadEnd(file) + } + } catch (e: Exception) { + call.cancel() + e.printStackTrace() + } finally { + try { + stream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + try { + fos?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + } + }) } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a10f8b..939e2f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,5 +71,16 @@ android:name="com.amap.api.navi.AmapRouteActivity" android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:theme="@android:style/Theme.NoTitleBar" /> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt index 4d4178a..cd14d88 100644 --- a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt @@ -8,11 +8,18 @@ import com.casic.app.smartwell.R import com.casic.app.smartwell.model.ErrorMessageModel import com.casic.app.smartwell.utils.Constant +import com.casic.app.smartwell.utils.FileUtils +import com.casic.app.smartwell.utils.IDownloadListener import com.casic.app.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper +import okhttp3.* import org.json.JSONObject +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream /** * String扩展方法 @@ -61,6 +68,18 @@ return "$defaultValue/static/${this.replace("\\", "/")}" } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this}" +} + //窨井类型转换 fun String.toChinese(): String { return when (this) { @@ -86,4 +105,66 @@ this, object : TypeToken() {}.type ) return errorModel.message.toString() +} + +fun String.downloadFile(listener: IDownloadListener) { + val httpClient = OkHttpClient() + val request = Request.Builder().get().url(this).build() + val newCall = httpClient.newCall(request) + /** + * 如果已被加入下载队列,则取消之前的,重新下载 + * 断点下载以后再考虑 + * */ + if (newCall.isExecuted()) { + newCall.cancel() + } + val downloadPath = this + newCall.enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + call.cancel() + e.printStackTrace() + } + + override fun onResponse(call: Call, response: Response) { + var stream: InputStream? = null + val buf = ByteArray(2048) + var len: Int + var fos: FileOutputStream? = null + try { + val fileBody = response.body + if (fileBody != null) { + stream = fileBody.byteStream() + val total: Long = fileBody.contentLength() + listener.onDownloadStart(total) + val file = File( + FileUtils.downloadFilePath, + downloadPath.substring(downloadPath.lastIndexOf("/") + 1) + ) + fos = FileOutputStream(file) + var current: Long = 0 + while (stream.read(buf).also { len = it } != -1) { + fos.write(buf, 0, len) + current += len.toLong() + listener.onProgressChanged(current) + } + fos.flush() + listener.onDownloadEnd(file) + } + } catch (e: Exception) { + call.cancel() + e.printStackTrace() + } finally { + try { + stream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + try { + fos?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + } + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 50a3215..138b4c1 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -41,6 +41,7 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val USER_DETAIL_MODEL = "userDetailModel" const val INTENT_PARAM = "intentParam" + const val APP_AUTHORITY = "com.casic.app.smartwell.install.fileProvider" val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf) val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a10f8b..939e2f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,5 +71,16 @@ android:name="com.amap.api.navi.AmapRouteActivity" android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:theme="@android:style/Theme.NoTitleBar" /> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt index 4d4178a..cd14d88 100644 --- a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt @@ -8,11 +8,18 @@ import com.casic.app.smartwell.R import com.casic.app.smartwell.model.ErrorMessageModel import com.casic.app.smartwell.utils.Constant +import com.casic.app.smartwell.utils.FileUtils +import com.casic.app.smartwell.utils.IDownloadListener import com.casic.app.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper +import okhttp3.* import org.json.JSONObject +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream /** * String扩展方法 @@ -61,6 +68,18 @@ return "$defaultValue/static/${this.replace("\\", "/")}" } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this}" +} + //窨井类型转换 fun String.toChinese(): String { return when (this) { @@ -86,4 +105,66 @@ this, object : TypeToken() {}.type ) return errorModel.message.toString() +} + +fun String.downloadFile(listener: IDownloadListener) { + val httpClient = OkHttpClient() + val request = Request.Builder().get().url(this).build() + val newCall = httpClient.newCall(request) + /** + * 如果已被加入下载队列,则取消之前的,重新下载 + * 断点下载以后再考虑 + * */ + if (newCall.isExecuted()) { + newCall.cancel() + } + val downloadPath = this + newCall.enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + call.cancel() + e.printStackTrace() + } + + override fun onResponse(call: Call, response: Response) { + var stream: InputStream? = null + val buf = ByteArray(2048) + var len: Int + var fos: FileOutputStream? = null + try { + val fileBody = response.body + if (fileBody != null) { + stream = fileBody.byteStream() + val total: Long = fileBody.contentLength() + listener.onDownloadStart(total) + val file = File( + FileUtils.downloadFilePath, + downloadPath.substring(downloadPath.lastIndexOf("/") + 1) + ) + fos = FileOutputStream(file) + var current: Long = 0 + while (stream.read(buf).also { len = it } != -1) { + fos.write(buf, 0, len) + current += len.toLong() + listener.onProgressChanged(current) + } + fos.flush() + listener.onDownloadEnd(file) + } + } catch (e: Exception) { + call.cancel() + e.printStackTrace() + } finally { + try { + stream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + try { + fos?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + } + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 50a3215..138b4c1 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -41,6 +41,7 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val USER_DETAIL_MODEL = "userDetailModel" const val INTENT_PARAM = "intentParam" + const val APP_AUTHORITY = "com.casic.app.smartwell.install.fileProvider" val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf) val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt index 509a9c2..855db2e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -23,7 +23,7 @@ } //储存下载文件的目录 - private val downloadFilePath: String + val downloadFilePath: String get() { val downloadDir = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a10f8b..939e2f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,5 +71,16 @@ android:name="com.amap.api.navi.AmapRouteActivity" android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:theme="@android:style/Theme.NoTitleBar" /> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt index 4d4178a..cd14d88 100644 --- a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt @@ -8,11 +8,18 @@ import com.casic.app.smartwell.R import com.casic.app.smartwell.model.ErrorMessageModel import com.casic.app.smartwell.utils.Constant +import com.casic.app.smartwell.utils.FileUtils +import com.casic.app.smartwell.utils.IDownloadListener import com.casic.app.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper +import okhttp3.* import org.json.JSONObject +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream /** * String扩展方法 @@ -61,6 +68,18 @@ return "$defaultValue/static/${this.replace("\\", "/")}" } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this}" +} + //窨井类型转换 fun String.toChinese(): String { return when (this) { @@ -86,4 +105,66 @@ this, object : TypeToken() {}.type ) return errorModel.message.toString() +} + +fun String.downloadFile(listener: IDownloadListener) { + val httpClient = OkHttpClient() + val request = Request.Builder().get().url(this).build() + val newCall = httpClient.newCall(request) + /** + * 如果已被加入下载队列,则取消之前的,重新下载 + * 断点下载以后再考虑 + * */ + if (newCall.isExecuted()) { + newCall.cancel() + } + val downloadPath = this + newCall.enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + call.cancel() + e.printStackTrace() + } + + override fun onResponse(call: Call, response: Response) { + var stream: InputStream? = null + val buf = ByteArray(2048) + var len: Int + var fos: FileOutputStream? = null + try { + val fileBody = response.body + if (fileBody != null) { + stream = fileBody.byteStream() + val total: Long = fileBody.contentLength() + listener.onDownloadStart(total) + val file = File( + FileUtils.downloadFilePath, + downloadPath.substring(downloadPath.lastIndexOf("/") + 1) + ) + fos = FileOutputStream(file) + var current: Long = 0 + while (stream.read(buf).also { len = it } != -1) { + fos.write(buf, 0, len) + current += len.toLong() + listener.onProgressChanged(current) + } + fos.flush() + listener.onDownloadEnd(file) + } + } catch (e: Exception) { + call.cancel() + e.printStackTrace() + } finally { + try { + stream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + try { + fos?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + } + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 50a3215..138b4c1 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -41,6 +41,7 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val USER_DETAIL_MODEL = "userDetailModel" const val INTENT_PARAM = "intentParam" + const val APP_AUTHORITY = "com.casic.app.smartwell.install.fileProvider" val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf) val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt index 509a9c2..855db2e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -23,7 +23,7 @@ } //储存下载文件的目录 - private val downloadFilePath: String + val downloadFilePath: String get() { val downloadDir = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt new file mode 100644 index 0000000..a6e8fda --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt @@ -0,0 +1,11 @@ +package com.casic.app.smartwell.utils + +import java.io.File + +interface IDownloadListener { + fun onDownloadStart(totalBytes: Long) + + fun onProgressChanged(currentBytes: Long) + + fun onDownloadEnd(file: File?) +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a10f8b..939e2f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,5 +71,16 @@ android:name="com.amap.api.navi.AmapRouteActivity" android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:theme="@android:style/Theme.NoTitleBar" /> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt index 4d4178a..cd14d88 100644 --- a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt @@ -8,11 +8,18 @@ import com.casic.app.smartwell.R import com.casic.app.smartwell.model.ErrorMessageModel import com.casic.app.smartwell.utils.Constant +import com.casic.app.smartwell.utils.FileUtils +import com.casic.app.smartwell.utils.IDownloadListener import com.casic.app.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper +import okhttp3.* import org.json.JSONObject +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream /** * String扩展方法 @@ -61,6 +68,18 @@ return "$defaultValue/static/${this.replace("\\", "/")}" } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this}" +} + //窨井类型转换 fun String.toChinese(): String { return when (this) { @@ -86,4 +105,66 @@ this, object : TypeToken() {}.type ) return errorModel.message.toString() +} + +fun String.downloadFile(listener: IDownloadListener) { + val httpClient = OkHttpClient() + val request = Request.Builder().get().url(this).build() + val newCall = httpClient.newCall(request) + /** + * 如果已被加入下载队列,则取消之前的,重新下载 + * 断点下载以后再考虑 + * */ + if (newCall.isExecuted()) { + newCall.cancel() + } + val downloadPath = this + newCall.enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + call.cancel() + e.printStackTrace() + } + + override fun onResponse(call: Call, response: Response) { + var stream: InputStream? = null + val buf = ByteArray(2048) + var len: Int + var fos: FileOutputStream? = null + try { + val fileBody = response.body + if (fileBody != null) { + stream = fileBody.byteStream() + val total: Long = fileBody.contentLength() + listener.onDownloadStart(total) + val file = File( + FileUtils.downloadFilePath, + downloadPath.substring(downloadPath.lastIndexOf("/") + 1) + ) + fos = FileOutputStream(file) + var current: Long = 0 + while (stream.read(buf).also { len = it } != -1) { + fos.write(buf, 0, len) + current += len.toLong() + listener.onProgressChanged(current) + } + fos.flush() + listener.onDownloadEnd(file) + } + } catch (e: Exception) { + call.cancel() + e.printStackTrace() + } finally { + try { + stream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + try { + fos?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + } + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 50a3215..138b4c1 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -41,6 +41,7 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val USER_DETAIL_MODEL = "userDetailModel" const val INTENT_PARAM = "intentParam" + const val APP_AUTHORITY = "com.casic.app.smartwell.install.fileProvider" val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf) val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt index 509a9c2..855db2e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -23,7 +23,7 @@ } //储存下载文件的目录 - private val downloadFilePath: String + val downloadFilePath: String get() { val downloadDir = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt new file mode 100644 index 0000000..a6e8fda --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt @@ -0,0 +1,11 @@ +package com.casic.app.smartwell.utils + +import java.io.File + +interface IDownloadListener { + fun onDownloadStart(totalBytes: Long) + + fun onProgressChanged(currentBytes: Long) + + fun onDownloadEnd(file: File?) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt b/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt new file mode 100644 index 0000000..92c50e9 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt @@ -0,0 +1,5 @@ +package com.casic.app.smartwell.utils.provider + +import androidx.core.content.FileProvider + +class VersionUpgradeFileProvider : FileProvider() \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a10f8b..939e2f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,5 +71,16 @@ android:name="com.amap.api.navi.AmapRouteActivity" android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:theme="@android:style/Theme.NoTitleBar" /> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt index 4d4178a..cd14d88 100644 --- a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt @@ -8,11 +8,18 @@ import com.casic.app.smartwell.R import com.casic.app.smartwell.model.ErrorMessageModel import com.casic.app.smartwell.utils.Constant +import com.casic.app.smartwell.utils.FileUtils +import com.casic.app.smartwell.utils.IDownloadListener import com.casic.app.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper +import okhttp3.* import org.json.JSONObject +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream /** * String扩展方法 @@ -61,6 +68,18 @@ return "$defaultValue/static/${this.replace("\\", "/")}" } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this}" +} + //窨井类型转换 fun String.toChinese(): String { return when (this) { @@ -86,4 +105,66 @@ this, object : TypeToken() {}.type ) return errorModel.message.toString() +} + +fun String.downloadFile(listener: IDownloadListener) { + val httpClient = OkHttpClient() + val request = Request.Builder().get().url(this).build() + val newCall = httpClient.newCall(request) + /** + * 如果已被加入下载队列,则取消之前的,重新下载 + * 断点下载以后再考虑 + * */ + if (newCall.isExecuted()) { + newCall.cancel() + } + val downloadPath = this + newCall.enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + call.cancel() + e.printStackTrace() + } + + override fun onResponse(call: Call, response: Response) { + var stream: InputStream? = null + val buf = ByteArray(2048) + var len: Int + var fos: FileOutputStream? = null + try { + val fileBody = response.body + if (fileBody != null) { + stream = fileBody.byteStream() + val total: Long = fileBody.contentLength() + listener.onDownloadStart(total) + val file = File( + FileUtils.downloadFilePath, + downloadPath.substring(downloadPath.lastIndexOf("/") + 1) + ) + fos = FileOutputStream(file) + var current: Long = 0 + while (stream.read(buf).also { len = it } != -1) { + fos.write(buf, 0, len) + current += len.toLong() + listener.onProgressChanged(current) + } + fos.flush() + listener.onDownloadEnd(file) + } + } catch (e: Exception) { + call.cancel() + e.printStackTrace() + } finally { + try { + stream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + try { + fos?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + } + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 50a3215..138b4c1 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -41,6 +41,7 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val USER_DETAIL_MODEL = "userDetailModel" const val INTENT_PARAM = "intentParam" + const val APP_AUTHORITY = "com.casic.app.smartwell.install.fileProvider" val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf) val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt index 509a9c2..855db2e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -23,7 +23,7 @@ } //储存下载文件的目录 - private val downloadFilePath: String + val downloadFilePath: String get() { val downloadDir = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt new file mode 100644 index 0000000..a6e8fda --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt @@ -0,0 +1,11 @@ +package com.casic.app.smartwell.utils + +import java.io.File + +interface IDownloadListener { + fun onDownloadStart(totalBytes: Long) + + fun onProgressChanged(currentBytes: Long) + + fun onDownloadEnd(file: File?) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt b/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt new file mode 100644 index 0000000..92c50e9 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt @@ -0,0 +1,5 @@ +package com.casic.app.smartwell.utils.provider + +import androidx.core.content.FileProvider + +class VersionUpgradeFileProvider : FileProvider() \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt index 91f598f..fc4c7ac 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt @@ -1,15 +1,19 @@ package com.casic.app.smartwell.view.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import com.casic.app.smartwell.BuildConfig import com.casic.app.smartwell.R +import com.casic.app.smartwell.extensions.appendDownloadUrl +import com.casic.app.smartwell.extensions.downloadFile import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.model.UserDetailModel -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState -import com.casic.app.smartwell.utils.SaveKeyValues +import com.casic.app.smartwell.utils.* import com.casic.app.smartwell.view.AboutUsActivity import com.casic.app.smartwell.view.HelpCenterActivity import com.casic.app.smartwell.view.UserDetailActivity @@ -20,13 +24,15 @@ import com.pengxh.app.multilib.widget.dialog.AlertControlDialog import kotlinx.android.synthetic.main.fragment_mine.* import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + class MinePageFragment : BaseFragment() { - private val kTag = "MinePageFragment" private val gson = Gson() private lateinit var userDataModel: UserDetailModel.DataBean private lateinit var updateVersionViewModel: UpdateVersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -41,6 +47,12 @@ userNameView.text = userDataModel.name } updateVersionViewModel = ViewModelProvider(this).get(UpdateVersionViewModel::class.java) + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -63,8 +75,8 @@ .setContext(requireContext()) .setTitle("提示") .setMessage("有新版本,是否更新?") - .setNegativeButton("立即下载") - .setPositiveButton("稍后再说") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { @@ -94,9 +106,52 @@ } private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() if (url.toString().isBlank()) { "抱歉,版本下载失败".show(requireContext()) return } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(object : IDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apk: File?) { + if (apk == null) { + "安装文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + // 通过FileProvider创建一个content类型的Uri + data = FileProvider.getUriForFile( + requireContext(), Constant.APP_AUTHORITY, apk + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apk) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a10f8b..939e2f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,5 +71,16 @@ android:name="com.amap.api.navi.AmapRouteActivity" android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:theme="@android:style/Theme.NoTitleBar" /> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt index 4d4178a..cd14d88 100644 --- a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt @@ -8,11 +8,18 @@ import com.casic.app.smartwell.R import com.casic.app.smartwell.model.ErrorMessageModel import com.casic.app.smartwell.utils.Constant +import com.casic.app.smartwell.utils.FileUtils +import com.casic.app.smartwell.utils.IDownloadListener import com.casic.app.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper +import okhttp3.* import org.json.JSONObject +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream /** * String扩展方法 @@ -61,6 +68,18 @@ return "$defaultValue/static/${this.replace("\\", "/")}" } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this}" +} + //窨井类型转换 fun String.toChinese(): String { return when (this) { @@ -86,4 +105,66 @@ this, object : TypeToken() {}.type ) return errorModel.message.toString() +} + +fun String.downloadFile(listener: IDownloadListener) { + val httpClient = OkHttpClient() + val request = Request.Builder().get().url(this).build() + val newCall = httpClient.newCall(request) + /** + * 如果已被加入下载队列,则取消之前的,重新下载 + * 断点下载以后再考虑 + * */ + if (newCall.isExecuted()) { + newCall.cancel() + } + val downloadPath = this + newCall.enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + call.cancel() + e.printStackTrace() + } + + override fun onResponse(call: Call, response: Response) { + var stream: InputStream? = null + val buf = ByteArray(2048) + var len: Int + var fos: FileOutputStream? = null + try { + val fileBody = response.body + if (fileBody != null) { + stream = fileBody.byteStream() + val total: Long = fileBody.contentLength() + listener.onDownloadStart(total) + val file = File( + FileUtils.downloadFilePath, + downloadPath.substring(downloadPath.lastIndexOf("/") + 1) + ) + fos = FileOutputStream(file) + var current: Long = 0 + while (stream.read(buf).also { len = it } != -1) { + fos.write(buf, 0, len) + current += len.toLong() + listener.onProgressChanged(current) + } + fos.flush() + listener.onDownloadEnd(file) + } + } catch (e: Exception) { + call.cancel() + e.printStackTrace() + } finally { + try { + stream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + try { + fos?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + } + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 50a3215..138b4c1 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -41,6 +41,7 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val USER_DETAIL_MODEL = "userDetailModel" const val INTENT_PARAM = "intentParam" + const val APP_AUTHORITY = "com.casic.app.smartwell.install.fileProvider" val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf) val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt index 509a9c2..855db2e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -23,7 +23,7 @@ } //储存下载文件的目录 - private val downloadFilePath: String + val downloadFilePath: String get() { val downloadDir = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt new file mode 100644 index 0000000..a6e8fda --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt @@ -0,0 +1,11 @@ +package com.casic.app.smartwell.utils + +import java.io.File + +interface IDownloadListener { + fun onDownloadStart(totalBytes: Long) + + fun onProgressChanged(currentBytes: Long) + + fun onDownloadEnd(file: File?) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt b/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt new file mode 100644 index 0000000..92c50e9 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt @@ -0,0 +1,5 @@ +package com.casic.app.smartwell.utils.provider + +import androidx.core.content.FileProvider + +class VersionUpgradeFileProvider : FileProvider() \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt index 91f598f..fc4c7ac 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt @@ -1,15 +1,19 @@ package com.casic.app.smartwell.view.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import com.casic.app.smartwell.BuildConfig import com.casic.app.smartwell.R +import com.casic.app.smartwell.extensions.appendDownloadUrl +import com.casic.app.smartwell.extensions.downloadFile import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.model.UserDetailModel -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState -import com.casic.app.smartwell.utils.SaveKeyValues +import com.casic.app.smartwell.utils.* import com.casic.app.smartwell.view.AboutUsActivity import com.casic.app.smartwell.view.HelpCenterActivity import com.casic.app.smartwell.view.UserDetailActivity @@ -20,13 +24,15 @@ import com.pengxh.app.multilib.widget.dialog.AlertControlDialog import kotlinx.android.synthetic.main.fragment_mine.* import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + class MinePageFragment : BaseFragment() { - private val kTag = "MinePageFragment" private val gson = Gson() private lateinit var userDataModel: UserDetailModel.DataBean private lateinit var updateVersionViewModel: UpdateVersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -41,6 +47,12 @@ userNameView.text = userDataModel.name } updateVersionViewModel = ViewModelProvider(this).get(UpdateVersionViewModel::class.java) + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -63,8 +75,8 @@ .setContext(requireContext()) .setTitle("提示") .setMessage("有新版本,是否更新?") - .setNegativeButton("立即下载") - .setPositiveButton("稍后再说") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { @@ -94,9 +106,52 @@ } private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() if (url.toString().isBlank()) { "抱歉,版本下载失败".show(requireContext()) return } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(object : IDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apk: File?) { + if (apk == null) { + "安装文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + // 通过FileProvider创建一个content类型的Uri + data = FileProvider.getUriForFile( + requireContext(), Constant.APP_AUTHORITY, apk + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apk) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) } } \ No newline at end of file diff --git a/app/src/main/res/drawable/download_progress.xml b/app/src/main/res/drawable/download_progress.xml new file mode 100644 index 0000000..493d923 --- /dev/null +++ b/app/src/main/res/drawable/download_progress.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a10f8b..939e2f0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -71,5 +71,16 @@ android:name="com.amap.api.navi.AmapRouteActivity" android:configChanges="orientation|keyboardHidden|screenSize|navigation" android:theme="@android:style/Theme.NoTitleBar" /> + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt index 4d4178a..cd14d88 100644 --- a/app/src/main/java/com/casic/app/smartwell/extensions/String.kt +++ b/app/src/main/java/com/casic/app/smartwell/extensions/String.kt @@ -8,11 +8,18 @@ import com.casic.app.smartwell.R import com.casic.app.smartwell.model.ErrorMessageModel import com.casic.app.smartwell.utils.Constant +import com.casic.app.smartwell.utils.FileUtils +import com.casic.app.smartwell.utils.IDownloadListener import com.casic.app.smartwell.utils.SaveKeyValues import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.qmuiteam.qmui.util.QMUIDisplayHelper +import okhttp3.* import org.json.JSONObject +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.InputStream /** * String扩展方法 @@ -61,6 +68,18 @@ return "$defaultValue/static/${this.replace("\\", "/")}" } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + Constant.DEFAULT_SERVER_CONFIG, + "http://111.198.10.15:11304" + ) as String + return "$defaultValue/static/${this}" +} + //窨井类型转换 fun String.toChinese(): String { return when (this) { @@ -86,4 +105,66 @@ this, object : TypeToken() {}.type ) return errorModel.message.toString() +} + +fun String.downloadFile(listener: IDownloadListener) { + val httpClient = OkHttpClient() + val request = Request.Builder().get().url(this).build() + val newCall = httpClient.newCall(request) + /** + * 如果已被加入下载队列,则取消之前的,重新下载 + * 断点下载以后再考虑 + * */ + if (newCall.isExecuted()) { + newCall.cancel() + } + val downloadPath = this + newCall.enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + call.cancel() + e.printStackTrace() + } + + override fun onResponse(call: Call, response: Response) { + var stream: InputStream? = null + val buf = ByteArray(2048) + var len: Int + var fos: FileOutputStream? = null + try { + val fileBody = response.body + if (fileBody != null) { + stream = fileBody.byteStream() + val total: Long = fileBody.contentLength() + listener.onDownloadStart(total) + val file = File( + FileUtils.downloadFilePath, + downloadPath.substring(downloadPath.lastIndexOf("/") + 1) + ) + fos = FileOutputStream(file) + var current: Long = 0 + while (stream.read(buf).also { len = it } != -1) { + fos.write(buf, 0, len) + current += len.toLong() + listener.onProgressChanged(current) + } + fos.flush() + listener.onDownloadEnd(file) + } + } catch (e: Exception) { + call.cancel() + e.printStackTrace() + } finally { + try { + stream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + try { + fos?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + } + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt index 50a3215..138b4c1 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/Constant.kt @@ -41,6 +41,7 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val USER_DETAIL_MODEL = "userDetailModel" const val INTENT_PARAM = "intentParam" + const val APP_AUTHORITY = "com.casic.app.smartwell.install.fileProvider" val HOME_ICONS = arrayOf(R.drawable.ic_well, R.drawable.ic_overtime, R.drawable.ic_bfcf) val HOME_ITEMS = arrayOf("闸井管理", "超时工单", "布防撤防") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt index 509a9c2..855db2e 100644 --- a/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt +++ b/app/src/main/java/com/casic/app/smartwell/utils/FileUtils.kt @@ -23,7 +23,7 @@ } //储存下载文件的目录 - private val downloadFilePath: String + val downloadFilePath: String get() { val downloadDir = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "") diff --git a/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt new file mode 100644 index 0000000..a6e8fda --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/IDownloadListener.kt @@ -0,0 +1,11 @@ +package com.casic.app.smartwell.utils + +import java.io.File + +interface IDownloadListener { + fun onDownloadStart(totalBytes: Long) + + fun onProgressChanged(currentBytes: Long) + + fun onDownloadEnd(file: File?) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt b/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt new file mode 100644 index 0000000..92c50e9 --- /dev/null +++ b/app/src/main/java/com/casic/app/smartwell/utils/provider/VersionUpgradeFileProvider.kt @@ -0,0 +1,5 @@ +package com.casic.app.smartwell.utils.provider + +import androidx.core.content.FileProvider + +class VersionUpgradeFileProvider : FileProvider() \ No newline at end of file diff --git a/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt index 91f598f..fc4c7ac 100644 --- a/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/app/smartwell/view/fragment/MinePageFragment.kt @@ -1,15 +1,19 @@ package com.casic.app.smartwell.view.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider import com.casic.app.smartwell.BuildConfig import com.casic.app.smartwell.R +import com.casic.app.smartwell.extensions.appendDownloadUrl +import com.casic.app.smartwell.extensions.downloadFile import com.casic.app.smartwell.extensions.navigatePageTo import com.casic.app.smartwell.extensions.show import com.casic.app.smartwell.model.UserDetailModel -import com.casic.app.smartwell.utils.Constant -import com.casic.app.smartwell.utils.DialogHelper -import com.casic.app.smartwell.utils.LoadState -import com.casic.app.smartwell.utils.SaveKeyValues +import com.casic.app.smartwell.utils.* import com.casic.app.smartwell.view.AboutUsActivity import com.casic.app.smartwell.view.HelpCenterActivity import com.casic.app.smartwell.view.UserDetailActivity @@ -20,13 +24,15 @@ import com.pengxh.app.multilib.widget.dialog.AlertControlDialog import kotlinx.android.synthetic.main.fragment_mine.* import kotlinx.android.synthetic.main.include_base_title.* +import java.io.File + class MinePageFragment : BaseFragment() { - private val kTag = "MinePageFragment" private val gson = Gson() private lateinit var userDataModel: UserDetailModel.DataBean private lateinit var updateVersionViewModel: UpdateVersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -41,6 +47,12 @@ userNameView.text = userDataModel.name } updateVersionViewModel = ViewModelProvider(this).get(UpdateVersionViewModel::class.java) + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -63,8 +75,8 @@ .setContext(requireContext()) .setTitle("提示") .setMessage("有新版本,是否更新?") - .setNegativeButton("立即下载") - .setPositiveButton("稍后再说") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") .setOnDialogButtonClickListener(object : AlertControlDialog.OnDialogButtonClickListener { override fun onConfirmClick() { @@ -94,9 +106,52 @@ } private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() if (url.toString().isBlank()) { "抱歉,版本下载失败".show(requireContext()) return } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(object : IDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apk: File?) { + if (apk == null) { + "安装文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + // 通过FileProvider创建一个content类型的Uri + data = FileProvider.getUriForFile( + requireContext(), Constant.APP_AUTHORITY, apk + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apk) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) } } \ No newline at end of file diff --git a/app/src/main/res/drawable/download_progress.xml b/app/src/main/res/drawable/download_progress.xml new file mode 100644 index 0000000..493d923 --- /dev/null +++ b/app/src/main/res/drawable/download_progress.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml new file mode 100644 index 0000000..5d6e4d3 --- /dev/null +++ b/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file