add local update check.
authorTrillGates <williamtrillgates@gmail.com>
Wed, 3 Feb 2021 10:36:54 +0000 (18:36 +0800)
committerTrillGates <williamtrillgates@gmail.com>
Wed, 3 Feb 2021 10:36:54 +0000 (18:36 +0800)
14 files changed:
app/FotaBrand8541e/debug/FotaBrand8541e_V1_202101251756_debug.apk [deleted file]
app/FotaBrand8541e/release/FotaBrand8541e_V1_202102031807_release.apk [new file with mode: 0644]
app/FotaBrand8541e/release/output-metadata.json [moved from app/FotaBrand8541e/debug/output-metadata.json with 67% similarity]
app/src/main/java/com/ic/icfotaclient/presenter/OtaService.kt
app/src/main/java/com/ic/icfotaclient/presenter/OtaViewModel.kt
app/src/main/java/com/ic/icfotaclient/repository/CarOtaRepository.kt
app/src/main/java/com/ic/icfotaclient/repository/ICOtaRepository.kt
app/src/main/java/com/ic/icfotaclient/utils/ICOtaApiUtils.kt
app/src/main/java/com/ic/icfotaclient/utils/UpdateActionState.kt
app/src/main/java/com/ic/icfotaclient/utils/VersionInfoUtils.kt
app/src/main/java/com/ic/icfotaclient/view/SystemUpdateActivity.kt
app/src/main/res/layout/activity_main.xml
app/src/main/res/layout/dialog_tips.xml
app/src/main/res/values/strings.xml

diff --git a/app/FotaBrand8541e/debug/FotaBrand8541e_V1_202101251756_debug.apk b/app/FotaBrand8541e/debug/FotaBrand8541e_V1_202101251756_debug.apk
deleted file mode 100644 (file)
index 1c87ee8..0000000
Binary files a/app/FotaBrand8541e/debug/FotaBrand8541e_V1_202101251756_debug.apk and /dev/null differ
diff --git a/app/FotaBrand8541e/release/FotaBrand8541e_V1_202102031807_release.apk b/app/FotaBrand8541e/release/FotaBrand8541e_V1_202102031807_release.apk
new file mode 100644 (file)
index 0000000..9688da4
Binary files /dev/null and b/app/FotaBrand8541e/release/FotaBrand8541e_V1_202102031807_release.apk differ
@@ -5,14 +5,14 @@
     "kind": "Directory"
   },
   "applicationId": "com.ic.icfotaclient",
-  "variantName": "processFotaBrand8541eDebugResources",
+  "variantName": "processFotaBrand8541eReleaseResources",
   "elements": [
     {
       "type": "SINGLE",
       "filters": [],
       "versionCode": 1,
       "versionName": "1.0",
-      "outputFile": "FotaBrand8541e_V1_202101252023_debug.apk"
+      "outputFile": "FotaBrand8541e_V1_202102031807_release.apk"
     }
   ]
 }
\ No newline at end of file
index 1c8a8d3..54aa9b1 100644 (file)
@@ -5,14 +5,13 @@ import android.content.Intent
 import android.os.IBinder
 import android.text.TextUtils
 import android.util.Log
+import android.widget.Toast
 import androidx.lifecycle.*
 import com.ic.icfotaclient.App
 import com.ic.icfotaclient.IOtaCheckCallback
 import com.ic.icfotaclient.IOtaCheckService
-import com.ic.icfotaclient.utils.Constants
-import com.ic.icfotaclient.utils.OtaViewModelCreator
-import com.ic.icfotaclient.utils.VersionCheckFrom
-import com.ic.icfotaclient.utils.VersionInfoUtils
+import com.ic.icfotaclient.R
+import com.ic.icfotaclient.utils.*
 
 /**
  * 这个是专门给远程使用的,如果远程需要知道是否有更新的内容,可以通过AIDL通讯
@@ -71,6 +70,8 @@ class OtaService : Service(), ViewModelStoreOwner, LifecycleOwner {
         }
     }
 
+    private var hasCheck = false
+
 
     override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
         //判断指令是啥
@@ -86,28 +87,53 @@ class OtaService : Service(), ViewModelStoreOwner, LifecycleOwner {
                 //以下动作,需要延时执行,因为IMEI号,网络这些还没准备好
                 //检查网络,如果网络okay了,就去检查版本更新
                 //如果网络不okay,那么就等待网络连接的广播,在连接的广播里去检查更新
-                App.sHandler.postDelayed({
-                    checkVersion(VersionCheckFrom.BOOT_CHECK)
-                }, Constants.TIME_DELAY_BOOT)
-                //如果已经更新了,那么通知一下服务器
-                otaViewModel?.checkHasUpdated()
+                doCheck()
             }
             Constants.CMD_ACTION_NET_WORK_CONNECTED -> {
                 //去检查更新
-                otaViewModel?.checkHasUpdated()
+                doCheck()
             }
         }
 
         return super.onStartCommand(intent, flags, startId)
     }
 
-    private fun checkVersion(from: VersionCheckFrom) {
-        val checkNetWork = otaViewModel?.checkNetWork()
-        Log.d(TAG, "checkNetWork == > $checkNetWork")
-        if (checkNetWork == true) {
-            //连接上了,那么就去检查更新
-            otaViewModel?.checkUpdate(from)
+    private fun doCheck() {
+        if (hasCheck) {
+            Log.d(TAG, "has checked..")
+            return
         }
+        hasCheck = true
+        App.sHandler.postDelayed({
+            checkVersion(VersionCheckFrom.BOOT_CHECK)
+        }, Constants.TIME_DELAY_BOOT)
+        OtaViewModelCreator.getOtaViewModel(object : OtaViewModelCreator.OnViewModelInitListener {
+            override fun onViewModelInit(otaViewModel: OtaViewModel?) {
+                //如果已经更新了,那么通知一下服务器
+                otaViewModel?.checkHasUpdated()
+                otaViewModel?.currentActionState?.observe(this@OtaService, Observer {
+                    when (it) {
+                        UpdateActionState.VERIFY_ERROR -> {
+                            Toast.makeText(
+                                App.sContext, App.sContext.getString(R.string.verify_error_text),
+                                Toast.LENGTH_SHORT
+                            ).show()
+                        }
+                        UpdateActionState.VERIFY -> {
+                            Toast.makeText(
+                                App.sContext, App.sContext.getString(R.string.verify_package_text),
+                                Toast.LENGTH_SHORT
+                            ).show()
+                        }
+                    }
+                })
+            }
+        })
+    }
+
+    private fun checkVersion(from: VersionCheckFrom) {
+        //连接上了,那么就去检查更新
+        otaViewModel?.checkUpdate(from)
     }
 
     /**
index 3352323..acc139d 100644 (file)
@@ -4,6 +4,8 @@ import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
 import android.os.BatteryManager
+import android.os.Handler
+import android.os.Looper
 import android.os.RecoverySystem
 import android.text.TextUtils
 import android.util.Log
@@ -92,8 +94,96 @@ class OtaViewModel : ViewModel() {
             Log.d(TAG, "checking....")
             return
         }
+        //检查是否有本地更新
+        if (hasLocalUpdateZip()) {
+            Log.d(TAG, "tips local update zip.")
+            return
+        }
+        checkRemote(from)
+    }
+
+    /**
+     * 检查本地是否有升级包
+     */
+    private fun hasLocalUpdateZip(): Boolean {
+        val file = File(VersionInfoUtils.getLocalUpdateZip())
+        Log.d(TAG, "file is == > ${file.path}")
+        if (file.exists()) {
+            //弹窗询问用户是否进行升级
+            showLocalUpdateTips()
+            return true
+        }
+        return false
+    }
+
+    /**
+     * 展示本地安装和提示框
+     */
+    private fun showLocalUpdateTips() {
+        val manager = App.sContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+        val layoutParams = WindowManager.LayoutParams()
+        layoutParams.gravity = Gravity.CENTER
+        layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
+        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT
+        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
+        layoutParams.alpha = 1.0f
+        layoutParams.packageName = App.sContext.getPackageName()
+        layoutParams.buttonBrightness = 1f
+        layoutParams.windowAnimations = android.R.style.Animation_Dialog
+        val view: View =
+            View.inflate(App.sContext, R.layout.dialog_tips, null)
+        val descText: TextView = view.findViewById(R.id.description)
+        val deleteBtn: TextView = view.findViewById(R.id.button_delete)
+        deleteBtn.visibility = View.VISIBLE
+        val cancelBtn: TextView = view.findViewById(R.id.button_cancel)
+        cancelBtn.text = App.sContext.getString(R.string.btn_cancel_text)
+        val installBtn: TextView = view.findViewById(R.id.button_ok)
+        installBtn.text = App.sContext.getString(R.string.btn_install_text)
+        descText.text = App.sContext.getString(R.string.local_update_desc_text)
+        installBtn.setOnClickListener {
+            //进行安装
+            val file = File(VersionInfoUtils.getLocalUpdateZip())
+            if (file.exists()) {
+                downInfoResult.postValue(DownloadInfo(file.path, file.length()))
+                this.install()
+            } else {
+                Toast.makeText(
+                    App.sContext,
+                    App.sContext.getString(R.string.update_package_not_in_tips_text),
+                    Toast.LENGTH_SHORT
+                ).show()
+            }
+            descText.text = "正在拆解升级包..."
+            installBtn.visibility = View.GONE
+            cancelBtn.visibility = View.GONE
+            deleteBtn.visibility = View.GONE
+            Handler(Looper.getMainLooper()).postDelayed({
+                manager.removeView(view)
+            }, 3000)
+        }
+        deleteBtn.setOnClickListener {
+            //删除
+            viewModelScope.launch {
+                withContext(Dispatchers.IO) {
+                    val file = File(VersionInfoUtils.getLocalUpdateZip())
+                    if (file.exists()) {
+                        file.delete()
+                    }
+                }
+            }
+            manager.removeView(view)
+        }
+        cancelBtn.setOnClickListener {
+            //取消
+            manager.removeView(view)
+        }
+        manager.addView(view, layoutParams)
+    }
+
+    private fun checkRemote(from: VersionCheckFrom) {
         if (!checkNetWork()) {
-            currentActionState.value = UpdateActionState.NO_NETWORK
+            currentActionState.postValue(UpdateActionState.NO_NETWORK)
+            Log.d(TAG, "no network...")
             return
         }
         currentActionState.postValue(UpdateActionState.CHECKING)
@@ -101,7 +191,15 @@ class OtaViewModel : ViewModel() {
             try {
                 //检查更新
                 val result: OtaInfo? = withContext(Dispatchers.IO) {
-                    mFirstRepository.checkHasNewVersion()
+                    val checkHasNewVersion = mFirstRepository.checkHasNewVersion()
+                    if (checkHasNewVersion != null) {
+                        //干掉复制文件的地方,给下载位置
+                        val file = File(VersionInfoUtils.getUpdatePackageFullPath())
+                        if (file.exists()) {
+                            file.delete()
+                        }
+                    }
+                    checkHasNewVersion
                 }
                 //结果
                 Log.d(TAG, "check result ==> $result")
@@ -179,7 +277,8 @@ class OtaViewModel : ViewModel() {
                     mFirstRepository.downloadPackage(mDownloadCallback)
                 }
                 if (downResult == null) {
-                    currentActionState.postValue(UpdateActionState.ERROR)
+                    Log.d(TAG, "downResult is null...")
+                    //currentActionState.postValue(UpdateActionState.ERROR)
                 } else {
                     downInfoResult.value = downResult
                     //下载成功以后,如果是强制升级的,直接走升级流程
@@ -210,13 +309,18 @@ class OtaViewModel : ViewModel() {
         }
 
         override fun onDownloadError(errorCode: Int, msg: String) {
-            Toast.makeText(App.sContext, "errorCode:$errorCode", Toast.LENGTH_LONG).show()
+            // Toast.makeText(App.sContext, "errorCode:$errorCode", Toast.LENGTH_LONG).show()
             Log.d(TAG, "onDownloadError -- > $errorCode == > $msg")
             if (errorCode == 0) {
                 //停止下载了,修改UI为继续下载
                 currentActionState.postValue(UpdateActionState.DOWNLOAD_PAUSE)
             } else {
-                Toast.makeText(App.sContext, "error:$errorCode", Toast.LENGTH_LONG).show()
+                //Toast.makeText(App.sContext, "error:$errorCode", Toast.LENGTH_LONG).show()
+                //这里就是子线程
+                val file = File(VersionInfoUtils.getUpdatePackageFullPath())
+                if (file.exists()) {
+                    file.delete()
+                }
                 //其他错误,都提示用户重启
                 currentActionState.postValue(UpdateActionState.ERROR)
             }
@@ -311,32 +415,45 @@ class OtaViewModel : ViewModel() {
                     level * 100f / scale.toFloat()
                 }
                 Log.d(TAG, "batteryPct == > $batteryPct")
+                //进行电量检查
                 if (batteryPct!! >= 50.0f) {
-                    Log.d(TAG, "otaInfo.value!!.versionCode == > " + otaInfo.value!!.versionCode)
-                    Log.d(TAG, "save target update version.")
+                    currentActionState.postValue(UpdateActionState.UPDATING)
                     //保存一个SP值,升级完了检查,用于通知服务器更新成功了.
-                    val sharePreference = SPUtil.getSharePreference()
-                    sharePreference.edit()
-                        .putString(SPUtil.KEY_TARGET_VERSION_CODE, otaInfo.value!!.versionCode)
-                        .apply()
                     //这里后面要改成我们自己的升级,而不是apk的升级方式
                     withContext(Dispatchers.IO) {
-                        //进行电量检查
                         val path = downInfoResult.value!!.path;
+                        Log.d(TAG, "install path is == > $path")
                         //val path = "/data/media/0/sl8541e_1h10_oversea-ota-04210.zip"
                         val tempFile = File(path)
                         Log.d(TAG, "tempFile.exists() == > ${tempFile.exists()}")
-                        Log.d(TAG, "install path is == > $path")
+                        if (otaInfo.value != null) {
+                            Log.d(
+                                TAG,
+                                "otaInfo.value!!.versionCode == > " + otaInfo.value!!.versionCode
+                            )
+                            val sharePreference = SPUtil.getSharePreference()
+                            sharePreference.edit()
+                                .putString(
+                                    SPUtil.KEY_TARGET_VERSION_CODE,
+                                    otaInfo.value!!.versionCode
+                                )
+                                .apply()
+                        }
+
+                        Log.d(TAG, "save target update version.")
                         //先验证,再安装
                         try {
                             RecoverySystem.verifyPackage(File(path), null, null)
                             Log.d(TAG, "verifyPackageFinished...")
-                            RecoverySystem.installPackage(
-                                App.sContext,
-                                File(path)
-                            )
+                            RecoverySystem.installPackage(App.sContext, File(path))
                         } catch (e: Exception) {
                             e.printStackTrace()
+                            currentActionState.postValue(UpdateActionState.VERIFY_ERROR)
+                            //删除文件
+                            val file = File(path)
+                            if (file.exists()) {
+                                file.delete()
+                            }
                         }
                     }
                 } else {
@@ -346,6 +463,7 @@ class OtaViewModel : ViewModel() {
                 }
             } catch (e: Exception) {
                 Log.e("e", e.toString())
+                currentActionState.postValue(UpdateActionState.ERROR)
             }
         }
     }
@@ -360,10 +478,11 @@ class OtaViewModel : ViewModel() {
         val systemVersion = VersionInfoUtils.getSystemVersion()
         Log.d(TAG, "system version code is == > $systemVersion")
         Log.d(TAG, "versionRecord code is == > $versionRecord")
-        if (TextUtils.isEmpty(versionRecord)) {
+        if (!TextUtils.isEmpty(versionRecord)) {
             if (versionRecord == systemVersion) {
                 try {
                     viewModelScope.launch {
+                        Toast.makeText(App.sContext, "升级成功!", Toast.LENGTH_SHORT).show()
                         withContext(Dispatchers.IO) {
                             Log.d(TAG, "post install result..success.")
                             mFirstRepository.reportInstallResult(true)
@@ -382,6 +501,8 @@ class OtaViewModel : ViewModel() {
                             Log.d(TAG, "post install result..failed.")
                             mFirstRepository.reportInstallResult(false)
                             mFirstRepository.reportResult(versionRecord!!)
+                            //删除文件
+                            mFirstRepository.deletePackage()
                         }
                     }
                 } catch (e: Exception) {
index 801067b..377bd0e 100644 (file)
@@ -59,7 +59,6 @@ class CarOtaRepository : AbstractOtaRepository() {
                 Log.d(TAG, "onDownloaded...$extra")
                 //mCallback?.onDownloadSuccess()
                 //下载完就校验的,内部校验
-                mCallback?.onVerify()
             }
 
             override fun onError(errCode: Int, extra: Bundle?) {
@@ -72,9 +71,10 @@ class CarOtaRepository : AbstractOtaRepository() {
             }
 
         }) ?: return null
+        mCallback?.onVerify()
         //复制到对应的位置
         val sourceFile = download.file
-        val targetFile = VersionInfoUtils.getFlashPath()
+        val targetFile = VersionInfoUtils.getUpdatePackageFullPath()
         Log.d(TAG, "download == > $sourceFile")
         try {
             val fis = FileInputStream(sourceFile)
index 5a02dd1..21b4d44 100644 (file)
@@ -77,7 +77,7 @@ class ICOtaRepository : AbstractOtaRepository() {
 
     override fun deletePackage() {
         //删除flash_root下的
-        val file = File(VersionInfoUtils.getFlashPath())
+        val file = File(VersionInfoUtils.getUpdatePackageFullPath())
         if (file.exists()) {
             file.delete()
         }
index ab031cf..034f572 100644 (file)
@@ -10,8 +10,6 @@ import com.ic.icfotaclient.bean.OtaInfo
 import com.ic.icfotaclient.repository.IOtaRepositoryCallback
 import okhttp3.OkHttpClient
 import okhttp3.Request
-import java.io.BufferedInputStream
-import java.io.BufferedOutputStream
 import java.io.FileOutputStream
 import java.net.HttpURLConnection
 import java.net.URI
@@ -154,6 +152,7 @@ object ICOtaApiUtils {
             initOkHttp()
         }
         if (otaInfo == null) {
+            callback?.onDownloadError(-1, "没有下载信息")
             return null
         }
         val request: Request = Request.Builder().url(
@@ -163,31 +162,35 @@ object ICOtaApiUtils {
             val total = otaInfo!!.OtaPackageLength
             val response = okHttpClient?.newCall(request)?.execute()
             if (response?.code() == HttpURLConnection.HTTP_OK) {
-                val inputStream = response.body()?.byteStream()
-                val outPutStream = FileOutputStream(VersionInfoUtils.getFlashPath())
-                val bis = BufferedInputStream(inputStream)
-                val bos = BufferedOutputStream(outPutStream)
-                val buf = ByteArray(1024)
-                var len: Int
-                var current = 0;
-                while (true) {
-                    len = bis.read(buf)
-                    if (len == -1) break;
-                    current += len;
-                    bos.write(buf, 0, len)
-                    callback?.onDownloadProgressChange(current.toLong(), total.toLong())
+                try {
+                    val fis = response.body()?.byteStream()
+                    val fos = FileOutputStream(VersionInfoUtils.getUpdatePackageFullPath())
+                    val buf = ByteArray(1024)
+                    var len: Int
+                    var current = 0
+                    while (fis?.read(buf).also {
+                            len = it!!
+                        } != -1) {
+                        fos.write(buf, 0, len)
+                        current += len
+                        callback?.onDownloadProgressChange(current.toLong(), total.toLong())
+                    }
+                    fis?.close()
+                    fos.close()
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                    callback?.onDownloadError(-4, "下载中出错")
                 }
-                inputStream?.close()
-                outPutStream.close()
                 //校验文件下载是否正确
                 callback?.onVerify()
-                val checkMd5 = MD5.checkMd5(otaInfo!!.md5sum, VersionInfoUtils.getFlashPath())
+                val checkMd5 = MD5.checkMd5(otaInfo!!.md5sum, VersionInfoUtils.getUpdatePackageFullPath())
                 Log.d(TAG, "checkMd5 =+++= > $checkMd5")
                 if (!checkMd5) {
                     callback?.onDownloadError(-5, "校验失败")
+                    return null
                 }
                 callback?.onDownloadSuccess()
-                return DownloadInfo(VersionInfoUtils.getFlashPath(), total.toLong())
+                return DownloadInfo(VersionInfoUtils.getUpdatePackageFullPath(), total.toLong())
             }
         } catch (e: Exception) {
             e.printStackTrace()
index 557f71e..8c18aee 100644 (file)
@@ -12,4 +12,6 @@ enum class UpdateActionState {
     NO_NETWORK,/*显示无网络,isEnable=false*/
     ERROR,/*恢复默认,显示检查更新 isEnable=false*/
     BATTERY_LEVEL_NOT_ENOUGH,/*电池电量不足50%,isEnable=false*/
+    UPDATING,/*显示:注入升级种子,isEnable=false*/
+    VERIFY_ERROR/*显示:校验出错,isEnable=false*/
 }
\ No newline at end of file
index 1f07ae6..a66599c 100644 (file)
@@ -84,14 +84,22 @@ object VersionInfoUtils {
     var DATA_ROOT = "/data/media/0"
 
     private const val updateFileName = "update_pkg"
+    private const val localUpdateFileName = "update_pkg.zip"
 
 
-    fun getFlashPath(): String {
+    fun getLocalUpdateZip(): String {
+        //移动到对应的位置上
+        // if (getMultiUserState()) {
+        flash_root = DATA_ROOT
+        //  }
+        return flash_root + File.separator + localUpdateFileName
+    }
+
+    fun getUpdatePackageFullPath(): String {
         //移动到对应的位置上
         if (getMultiUserState()) {
             flash_root = DATA_ROOT
         }
-
         return flash_root + File.separator + updateFileName
     }
 }
\ No newline at end of file
index fc0e662..1fd851f 100644 (file)
@@ -64,7 +64,8 @@ class SystemUpdateActivity : AppCompatActivity() {
                     }
                     UpdateActionState.DOWNLOADING -> {
                         //暂停下载
-                        otaViewModel.pauseDownload()
+                        //otaViewModel.pauseDownload()
+                        //不支持暂停先
                     }
                     UpdateActionState.DOWNLOAD_PAUSE -> {
                         //去下载
@@ -91,7 +92,6 @@ class SystemUpdateActivity : AppCompatActivity() {
             otaInfo.observe(that, Observer {
                 if (it != null) {
                     updateText.text = getString(R.string.update_tips_text) + it.updateDesc
-
                 }
             })
             isTipsWifiConnect.observe(that, Observer {
@@ -121,8 +121,8 @@ class SystemUpdateActivity : AppCompatActivity() {
                         checkUpdate.isEnabled = false
                     }
                     UpdateActionState.DOWNLOADING -> {
-                        checkUpdate.text = getString(R.string.pause_download_text)
-                        checkUpdate.isEnabled = true
+                        checkUpdate.text = getString(R.string.try_to_downloading)
+                        checkUpdate.isEnabled = false
                     }
                     UpdateActionState.DOWNLOAD_PAUSE -> {
                         checkUpdate.text = getString(R.string.continue_download_text)
@@ -148,6 +148,14 @@ class SystemUpdateActivity : AppCompatActivity() {
                         checkUpdate.text = getString(R.string.verify_package_text)
                         checkUpdate.isEnabled = false
                     }
+                    UpdateActionState.UPDATING -> {
+                        checkUpdate.text = getString(R.string.inject_update_seed_text)
+                        checkUpdate.isEnabled = false
+                    }
+                    UpdateActionState.VERIFY_ERROR -> {
+                        checkUpdate.text = getString(R.string.verify_error_text)
+                        checkUpdate.isEnabled = false
+                    }
                     else -> {
                         //NONE
                     }
index b94e12d..af9c491 100644 (file)
@@ -80,6 +80,6 @@
         android:padding="10dp"
         android:text="@string/check_has_update_text"
         android:textColor="@color/white"
-        android:textSize="20sp" />
+        android:textSize="18sp" />
 
 </LinearLayout>
\ No newline at end of file
index 0039973..61eb176 100644 (file)
@@ -5,7 +5,9 @@
     android:background="@color/grey"
     android:gravity="center_horizontal"
     android:orientation="vertical"
-    android:padding="4dp">
+    android:padding="4dp"
+    android:paddingLeft="20dp"
+    android:paddingRight="20dp">
 
 
     <TextView
@@ -14,7 +16,7 @@
         android:layout_height="wrap_content"
         android:layout_marginTop="5dp"
         android:gravity="center_vertical|center_horizontal"
-        android:text="有新版本更新啦!"
+        android:text="@string/local_new_version_tips_title"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="@color/white"
         android:textIsSelectable="true" />
@@ -38,7 +40,7 @@
     </ScrollView>
 
     <View
-        android:layout_width="200dp"
+        android:layout_width="match_parent"
         android:layout_height="1px"
         android:background="@color/white" />
 
             android:text="@string/IFIA_btn_no"
             android:textColor="@color/white" />
 
+        <Button
+            android:id="@+id/button_delete"
+            style="?android:attr/buttonBarButtonStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/btn_delete_text"
+            android:textColor="@color/white"
+            android:visibility="gone" />
+
         <Button
             android:id="@+id/button_ok"
             style="?android:attr/buttonBarButtonStyle"
index 3d3f34f..82f2e28 100644 (file)
@@ -2,13 +2,18 @@
     <string name="app_name">ICFotaClient</string>
     <string name="IFIA_btn_yes">是</string>
     <string name="IFIA_btn_no">否</string>
+    <string name="btn_install_text">安装</string>
+    <string name="btn_cancel_text">取消</string>
+    <string name="btn_delete_text">删除</string>
     <string name="pb_title_downloading">正在下载升级包</string>
     <string name="check_has_update_text">检查是否有更新</string>
     <string name="update_text">马上升级</string>
     <string name="no_network_text">无法触及到服务器</string>
     <string name="battery_level_tips_text">请确保电量50%以上</string>
-    <string name="error_tips_text">资源准备失败,请重启尝试</string>
+    <string name="error_tips_text">资源准备失败,请重启尝试</string>
     <string name="verify_package_text">正在校验升级包</string>
+    <string name="inject_update_seed_text">注入升级种子</string>
+    <string name="verify_error_text">校验失败</string>
     <string name="last_version_text">已经是最新版本</string>
     <string name="download_package">下载更新包</string>
     <string name="try_to_downloading">正在玩命下载中…</string>
@@ -20,4 +25,8 @@
     <string name="update_tips_text">更新说明:\n</string>
     <string name="tips_wifi_connect">请连接WI-FI下载</string>
     <string name="unsupport_pause_download">该服务器不支持暂停下载</string>
+    <string name="new_version_tips_title">有新版本更新啦!</string>
+    <string name="local_new_version_tips_title">检查到本地更新!</string>
+    <string name="local_update_desc_text">发现本地更新包,确定更新,或者删除.</string>
+    <string name="update_package_not_in_tips_text">安装文件不存在</string>
 </resources>
\ No newline at end of file