diff --git a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt
index 644f4ba..9e0ecd7 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt
@@ -4,6 +4,7 @@ import android.content.Context
 import android.content.Intent
 import android.net.Uri
 import android.os.Build
+import android.os.FileUtils
 import android.provider.Settings
 import com.common.commonlib.db.DBUtils
 import com.common.commonlib.db.entity.Gas
@@ -21,6 +22,7 @@ import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 import java.io.BufferedReader
 import java.io.DataOutputStream
+import java.io.File
 import java.io.IOException
 import java.io.InputStreamReader
 
@@ -105,7 +107,12 @@ object TestUtils {
 //        })
     }
 
-    fun testExportExcel(context: Context, datas: MutableList<Gas>, commonDialog: CommonDialog?) {
+    suspend fun testExportExcel(
+        context: Context,
+        usbPath: String,
+        datas: MutableList<Gas>,
+        commonDialog: CommonDialog?
+    ) {
         val allData = mutableListOf<List<SimpleCellValue>>()
         datas.forEach {
             val row = mutableListOf<SimpleCellValue>()
@@ -115,17 +122,17 @@ object TestUtils {
             row.add(SimpleCellValue(it.unit))
             allData.add(row)
         }
-        val excelPath = ExcelUtils.writeStringListToExcel(allData, context)
-//        val dataPath = LztekUtil.getLztek()?.usbStoragePath + "/"
-//        // 直接copy到机身
-//        val command = arrayOf("remount","cp -r $excelPath $dataPath")
-//        execCommand(command, true, true)
+        val excelPath = ExcelUtils.writeStringListToExcel(allData, usbPath, context)
         commonDialog?.dismiss()
     }
 
 
-
-    fun testExportWarnExcel(context: Context, datas: MutableList<Warning>, loadingDialog: CommonDialog?) {
+    suspend fun testExportWarnExcel(
+        context: Context,
+        usbPath: String,
+        datas: MutableList<Warning>,
+        loadingDialog: CommonDialog?
+    ) {
         val allData = mutableListOf<List<SimpleCellValue>>()
         datas.forEach {
             val row = mutableListOf<SimpleCellValue>()
@@ -135,11 +142,7 @@ object TestUtils {
             row.add(SimpleCellValue(it.unit))
             allData.add(row)
         }
-        val excelPath = ExcelUtils.writeStringListToExcel(allData, context, true)
-//        val dataPath = LztekUtil.getLztek()?.usbStoragePath + "/"
-//        // 直接copy到机身
-//        val command = arrayOf("remount","cp -r $excelPath $dataPath")
-//        execCommand(command, true, true)
+        val excelPath = ExcelUtils.writeStringListToExcel(allData, usbPath, context, true)
         loadingDialog?.dismiss()
     }
 
@@ -202,4 +205,24 @@ object TestUtils {
             process?.destroy()
         }
     }
+
+    suspend fun testCopyVideo(
+        context: Context,
+        usbPath: String,
+        datas: MutableList<Video>,
+        loadingDialog: CommonDialog?
+    ) {
+        val usbVideoPath = usbPath + File.separator + "Video"
+        val dFile = File(usbVideoPath);
+        if (!dFile.exists() || !dFile.isDirectory) {
+            dFile.mkdir()
+        }
+        datas.forEach {
+            FileUtils.copy(
+                File(it.path).inputStream(),
+                File(usbVideoPath + "/${it.name}").outputStream()
+            )
+        }
+        loadingDialog?.dismiss()
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HistoryVideoActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HistoryVideoActivity.kt
index 1c97604..e3880a0 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HistoryVideoActivity.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HistoryVideoActivity.kt
@@ -8,6 +8,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
 import com.common.commonlib.db.DBUtils
 import com.common.commonlib.db.entity.Video
 import com.yinuo.safetywatcher.R
+import com.yinuo.safetywatcher.TestUtils
 import com.yinuo.safetywatcher.databinding.ActivityHistoryVideoBinding
 import com.yinuo.safetywatcher.watcher.player.ProVideoActivity
 import com.yinuo.safetywatcher.watcher.base.BaseActivity
@@ -16,8 +17,10 @@ import com.yinuo.safetywatcher.watcher.ui.adapter.HistoryVideoAdapter
 import com.yinuo.safetywatcher.watcher.ui.view.CommonTopBar
 import com.yinuo.safetywatcher.watcher.utils.DateUtils
 import com.yinuo.safetywatcher.watcher.utils.LztekUtil
+import com.yinuo.safetywatcher.watcher.utils.StorageUtils
 import com.yinuo.safetywatcher.watcher.utils.showToast
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 import java.io.File
 
@@ -40,11 +43,6 @@ class HistoryVideoActivity : BaseActivity() {
         if (0 == type) {
             queryData()
         } else if (1 == type) {
-            val usbStoragePath = LztekUtil.getLztek()?.usbStoragePath
-            if (usbStoragePath.isNullOrEmpty() || !File(usbStoragePath).exists()) {
-                showToast(getString(R.string.no_upan_tip))
-                return
-            }
             export2Upan()
         }
     }
@@ -128,7 +126,18 @@ class HistoryVideoActivity : BaseActivity() {
     }
 
     private fun export2Upan() {
-        // TODO
+        val usbPath = StorageUtils.getStoragePath(this@HistoryVideoActivity)
+        if (usbPath.isNullOrEmpty()) {
+            showToast(getString(R.string.no_upan_tip))
+            return
+        }
+        showLoadingDialog(R.string.export_data_tip)
+        GlobalScope.launch {
+            TestUtils.testCopyVideo(this@HistoryVideoActivity, usbPath, mAdapter._data, loadingDialog)
+            launch(Dispatchers.Main) {
+                showToast(getString(R.string.export_success))
+            }
+        }
     }
 
     fun gotoPlayVideo(path: String) {
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt
index c4c6a5a..8c799e2 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt
@@ -18,6 +18,8 @@ import com.yinuo.safetywatcher.watcher.ui.adapter.HistoryDataAdapter
 import com.yinuo.safetywatcher.watcher.ui.view.CommonTopBar
 import com.yinuo.safetywatcher.watcher.utils.ChartBridge
 import com.yinuo.safetywatcher.watcher.utils.DateUtils
+import com.yinuo.safetywatcher.watcher.utils.StorageUtils
+import com.yinuo.safetywatcher.watcher.utils.showToast
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 
@@ -204,7 +206,17 @@ class QueryDataActivity : BaseActivity() {
     }
 
     private fun doExportData() {
-        showLoadingDialog(R.string.export_data_tip)
-        TestUtils.testExportExcel(this, mAdapter._data, loadingDialog)
+        val usbPath = StorageUtils.getStoragePath(this@QueryDataActivity)
+        if (usbPath.isNullOrEmpty()) {
+            showToast(getString(R.string.no_upan_tip))
+            return
+        }
+        showLoadingDialog(R.string.export_data_tip, false)
+        lifecycleScope.launch {
+            TestUtils.testExportExcel(this@QueryDataActivity, usbPath, mAdapter._data, loadingDialog)
+            launch(Dispatchers.Main) {
+                showToast(getString(R.string.export_success))
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/WarnDataActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/WarnDataActivity.kt
index e75c219..8fa2693 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/WarnDataActivity.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/WarnDataActivity.kt
@@ -14,6 +14,8 @@ import com.yinuo.safetywatcher.watcher.constant.DEFAULT_QUERY_TIME_INTERVAL
 import com.yinuo.safetywatcher.watcher.ui.adapter.WarnDataAdapter
 import com.yinuo.safetywatcher.watcher.ui.view.CommonTopBar
 import com.yinuo.safetywatcher.watcher.utils.DateUtils
+import com.yinuo.safetywatcher.watcher.utils.StorageUtils
+import com.yinuo.safetywatcher.watcher.utils.showToast
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 
@@ -118,7 +120,17 @@ class WarnDataActivity : BaseActivity() {
     }
 
     private fun doExportData() {
-        showLoadingDialog(R.string.export_data_tip)
-        TestUtils.testExportWarnExcel(this, mAdapter._data, loadingDialog)
+        val usbPath = StorageUtils.getStoragePath(this@WarnDataActivity)
+        if (usbPath.isNullOrEmpty()){
+            showToast(getString(R.string.no_upan_tip))
+            return
+        }
+        showLoadingDialog(R.string.export_data_tip, false)
+        lifecycleScope.launch {
+            TestUtils.testExportWarnExcel(this@WarnDataActivity, usbPath, mAdapter._data, loadingDialog)
+            launch(Dispatchers.Main){
+                showToast(getString(R.string.export_success))
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/utils/StorageUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/utils/StorageUtils.kt
new file mode 100644
index 0000000..e8d151b
--- /dev/null
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/utils/StorageUtils.kt
@@ -0,0 +1,48 @@
+package com.yinuo.safetywatcher.watcher.utils
+
+import android.content.Context
+import android.os.storage.StorageManager
+import android.os.storage.StorageVolume
+import java.lang.reflect.InvocationTargetException
+
+
+object StorageUtils {
+    /**
+     * 6.0获取外置sdcard和U盘路径,并区分
+     * @param mContext
+     * @param keyword SD = "内部存储"; EXT = "SD卡"; USB = "U盘"
+     * @return
+     */
+    fun getStoragePath(mContext: Context, keyword: String = "USB"): String? {
+        var targetpath: String? = ""
+        val mStorageManager = mContext
+            .getSystemService(Context.STORAGE_SERVICE) as StorageManager
+        var storageVolumeClazz: Class<*>? = null
+        try {
+            storageVolumeClazz = Class.forName("android.os.storage.StorageVolume")
+            val getVolumeList = mStorageManager.javaClass.getMethod("getVolumeList")
+            val getPath = storageVolumeClazz.getMethod("getPath")
+            val result: Array<StorageVolume> =
+                getVolumeList.invoke(mStorageManager) as Array<StorageVolume>
+            val length: Int = result.size
+            val getUserLabel = storageVolumeClazz.getMethod("getUserLabel")
+            for (i in 0 until length) {
+                val storageVolumeElement: StorageVolume = result[i]
+                val userLabel = getUserLabel.invoke(storageVolumeElement) as String
+                val path = getPath.invoke(storageVolumeElement) as String
+                if (userLabel.contains(keyword)) {
+                    targetpath = path
+                }
+            }
+        } catch (e: ClassNotFoundException) {
+            e.printStackTrace()
+        } catch (e: InvocationTargetException) {
+            e.printStackTrace()
+        } catch (e: NoSuchMethodException) {
+            e.printStackTrace()
+        } catch (e: IllegalAccessException) {
+            e.printStackTrace()
+        }
+        return targetpath
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/xls/utils/ExcelUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/xls/utils/ExcelUtils.kt
index 062f72e..86ad13b 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/xls/utils/ExcelUtils.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/xls/utils/ExcelUtils.kt
@@ -94,6 +94,7 @@ object ExcelUtils {
 
     fun writeStringListToExcel(
         allRowsData: List<List<ICellValue>>,
+        usbPath: String,
         context: Context,
         isWarnData: Boolean = false
     ): String? {
@@ -102,7 +103,7 @@ object ExcelUtils {
                 "气体浓度_${PathUtils.getNowTimeFormat(PathUtils.DATE_TO_STRING_LONG_PATTERN)}.xls"
             else "告警数据_${PathUtils.getNowTimeFormat(PathUtils.DATE_TO_STRING_LONG_PATTERN)}.xls"
         val filePath =
-            PathUtils.getExternalStoragePath(context) + File.separator + fileName
+            usbPath + File.separator + fileName
         val columns = context.resources.getStringArray(R.array.excel_column);
         initExcel(columns, filePath, PathUtils.SHEET_NAME) //需要写入权限
 
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/xls/utils/PathUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/xls/utils/PathUtils.kt
index 2c01b31..b3490c1 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/xls/utils/PathUtils.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/xls/utils/PathUtils.kt
@@ -24,7 +24,6 @@ object PathUtils {
      * 获取应用中文件存储
      */
     fun getExternalStoragePath(context: Context): String? {
-//        return LztekUtil.getLztek()?.usbStoragePath
         return context.getExternalFilesDir(null)?.path
     }
 
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 98d30de..07cf0e2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -55,6 +55,7 @@
     <string name="over_max_interval_tip">开始时间和结束时间间隔不能超过24小时!请调整</string>
     <string name="error_interval_tip">开始时间必须小于结束时间!请调整</string>
     <string name="no_upan_tip">请先插入U盘!</string>
+    <string name="export_success">导出完成!</string>
     <string name="sync_data_tip">数据同步中</string>
     <string name="export_data_tip">数据导出中</string>
 
diff --git a/buildCommon/commonLibConfig.gradle b/buildCommon/commonLibConfig.gradle
index 24cf889..189a62f 100644
--- a/buildCommon/commonLibConfig.gradle
+++ b/buildCommon/commonLibConfig.gradle
@@ -13,8 +13,8 @@ project.ext {
     versions = [
             compileSdkVersion      : 33,
             buildToolsVersion      : "33.0.3",
-            minSdkVersion          : 26,
-            targetSdkVersion       : 28,
+            minSdkVersion          : 30,
+            targetSdkVersion       : 30,
             versionCode            : 1,
             versionName            : "1.0",
             jvmTarget              : "1.8",