Skip to content

Commit

Permalink
添加data备份
Browse files Browse the repository at this point in the history
  • Loading branch information
WrBug committed Jan 6, 2019
1 parent ab18499 commit 4d2b5eb
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ import com.wrbug.developerhelper.mmkv.manager.MMKVManager
import kotlinx.android.synthetic.main.view_app_setting.view.*
import android.content.Intent
import android.net.Uri
import android.os.Environment
import com.wrbug.developerhelper.basecommon.BaseActivity
import com.wrbug.developerhelper.commonutil.zip
import com.wrbug.developerhelper.util.BackupUtils
import com.wrbug.developerhelper.util.DeviceUtils
import com.wrbug.developerhelper.util.toUri
import gdut.bsx.share2.Share2
import gdut.bsx.share2.ShareContentType
import java.io.File


class AppSettingView : ScrollView {
Expand Down Expand Up @@ -70,7 +73,7 @@ class AppSettingView : ScrollView {
}

private fun doUninstallApp() {
apkInfo?.run {
apkInfo?.apply {
AppManagerUtils.uninstallApp(context, applicationInfo.packageName)
}
}
Expand All @@ -79,7 +82,7 @@ class AppSettingView : ScrollView {
if (checkRoot().not()) {
return
}
apkInfo?.run {
apkInfo?.apply {
showNotice(context.getString(R.string.confirm_delete_app_data), DialogInterface.OnClickListener { _, _ ->
if (AppManagerUtils.clearAppData(applicationInfo.packageName)) {
showToast(context.getString(R.string.clear_complete))
Expand All @@ -93,7 +96,7 @@ class AppSettingView : ScrollView {
if (checkRoot().not()) {
return
}
apkInfo?.run {
apkInfo?.apply {
showNotice(context.getString(R.string.confirm_stop_app), DialogInterface.OnClickListener { _, _ ->
AppManagerUtils.forceStopApp(applicationInfo.packageName)
})
Expand All @@ -104,7 +107,7 @@ class AppSettingView : ScrollView {
if (checkRoot().not()) {
return
}
apkInfo?.run {
apkInfo?.apply {
showNotice(context.getString(R.string.confirm_restart_app), DialogInterface.OnClickListener { _, _ ->
if (!AppManagerUtils.forceStopApp(applicationInfo.packageName)) {
showToast(context.getString(R.string.restart_failed))
Expand All @@ -121,16 +124,52 @@ class AppSettingView : ScrollView {
if (checkRoot().not()) {
return
}
apkInfo?.run {

apkInfo?.apply {
val backupAppData = BackupUtils.backupAppData(applicationInfo.packageName, applicationInfo.dataDir)
if (backupAppData == null) {
showToast(context.getString(R.string.backup_failed))
return
}
if (context !is BaseActivity) {
showToast(context.getString(R.string.backup_success_msg))
return
}
showShareDataNotice(backupAppData)
}
}

private fun showShareDataNotice(backupAppData: File) {
showNotice(
context.getString(R.string.backup_success_and_share_msg),
DialogInterface.OnClickListener { _, _ ->
(context as BaseActivity).requestPermission(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
object : BaseActivity.PermissionCallback() {
override fun granted() {
val zipFile = File(context.externalCacheDir, "${apkInfo?.getAppName() ?: ""}-data.zip")
backupAppData.zip(zipFile)
val uri = zipFile.toUri()
if (uri == null) {
showToast(context.getString(R.string.share_failed))
return
}
Share2.Builder(context as Activity)
.setContentType(ShareContentType.FILE)
.setShareFileUri(uri)
.setOnActivityResult(10)
.build()
.shareBySystem()
}

})

})
}

private fun doBackupApk() {
if (checkRoot().not()) {
return
}
apkInfo?.run {
apkInfo?.apply {
val uri = BackupUtils.backupApk(
applicationInfo.packageName,
applicationInfo.publicSourceDir,
Expand All @@ -153,7 +192,10 @@ class AppSettingView : ScrollView {
showNotice(
context.getString(R.string.backup_success_and_share_msg),
DialogInterface.OnClickListener { _, _ ->
(context as BaseActivity).requestPermission(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
(context as BaseActivity).requestPermission(arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
),
object : BaseActivity.PermissionCallback() {
override fun granted() {
Share2.Builder(context as Activity)
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/wrbug/developerhelper/util/BackupUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.wrbug.developerhelper.util
import android.net.Uri
import android.os.Environment
import com.wrbug.developerhelper.commonutil.shell.ShellManager
import com.wrbug.developerhelper.commonutil.zip
import java.io.File

object BackupUtils {
Expand All @@ -21,4 +22,13 @@ object BackupUtils {
}
return null
}

fun backupAppData(packageName: String, dataDir: String): File? {
val backupDataDir =
File(backupDir, "datas/$packageName/${System.currentTimeMillis().format("yyyy-MM-dd-HH_mm_ss")}")
if (ShellManager.cpFile(dataDir, backupDataDir.absolutePath)) {
return backupDataDir
}
return null
}
}
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,5 @@
<string name="backup_success_msg">备份成功,文件已备份到内部存储下com.wrbug.developerHelper目录中</string>
<string name="backup_failed">备份失败</string>
<string name="backup_success_and_share_msg">备份成功,文件已备份到内部存储下com.wrbug.developerHelper目录中,是否立即分享给好友?</string>
<string name="share_failed">分享失败</string>
</resources>
3 changes: 3 additions & 0 deletions app/src/main/res/xml/filepaths.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
<external-path
name="file"
path="com.wrbug.developerHelper" />
<external-cache-path
name="ext_cache"
path="/" />
</paths>
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package com.wrbug.developerhelper.commonutil

import java.io.*
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream

object ZipUtils {
fun zip(src: File, outFile: File) {
//提供了一个数据项压缩成一个ZIP归档输出流
var out: ZipOutputStream? = null
try {
out = ZipOutputStream(FileOutputStream(outFile))
//如果此文件是一个文件,否则为false。
if (src.isFile) {
zipFileOrDirectory(out, src, "")
} else {
//返回一个文件或空阵列。
val entries = src.listFiles()
for (i in entries!!.indices) {
// 递归压缩,更新curPaths
zipFileOrDirectory(out, entries[i], "")
}
}
} catch (ex: IOException) {
ex.printStackTrace()
} finally {
//关闭输出流
if (out != null) {
try {
out.close()
} catch (ex: IOException) {
ex.printStackTrace()
}

}
}
}

fun zip(src: File): File? {
val outFile = File(src.parent, src.name + ".zip")//源文件或者目录
zip(src, outFile)
return outFile
}

@Throws(IOException::class)
private fun zipFileOrDirectory(
out: ZipOutputStream,
fileOrDirectory: File, curPath: String
) {
//从文件中读取字节的输入流
var fileInputStream: FileInputStream? = null
try {
//如果此文件是一个目录,否则返回false。
if (!fileOrDirectory.isDirectory) {
// 压缩文件
val buffer = ByteArray(4096)
fileInputStream = FileInputStream(fileOrDirectory)
//实例代表一个条目内的ZIP归档
val entry = ZipEntry(curPath + fileOrDirectory.name)
//条目的信息写入底层流
out.putNextEntry(entry)
var bytesRead: Int = fileInputStream.read(buffer)
while (bytesRead != -1) {
out.write(buffer, 0, bytesRead)
bytesRead = fileInputStream.read(buffer)
}
out.closeEntry()
} else {
// 压缩目录
val entries = fileOrDirectory.listFiles()
for (i in entries!!.indices) {
// 递归压缩,更新curPaths
zipFileOrDirectory(
out, entries[i], curPath
+ fileOrDirectory.name + "/"
)
}
}
} catch (ex: IOException) {
ex.printStackTrace()
// throw ex;
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close()
} catch (ex: IOException) {
ex.printStackTrace()
}

}
}
}

@Throws(IOException::class)
fun unzip(zipFileName: String, outputDirectory: String) {
var zipFile: ZipFile? = null
try {
zipFile = ZipFile(zipFileName)
val e = zipFile.entries()
var zipEntry: ZipEntry? = null
val dest = File(outputDirectory)
dest.mkdirs()
while (e.hasMoreElements()) {
zipEntry = e.nextElement() as ZipEntry
val entryName = zipEntry.name
var inputStream: InputStream? = null
var out: FileOutputStream? = null
try {
if (zipEntry.isDirectory) {
var name = zipEntry.name
name = name.substring(0, name.length - 1)
val f = File(
outputDirectory + File.separator
+ name
)
f.mkdirs()
} else {
var index = entryName.lastIndexOf("\\")
if (index != -1) {
val df = File(
outputDirectory + File.separator
+ entryName.substring(0, index)
)
df.mkdirs()
}
index = entryName.lastIndexOf("/")
if (index != -1) {
val df = File(
outputDirectory + File.separator
+ entryName.substring(0, index)
)
df.mkdirs()
}
val f = File(
outputDirectory + File.separator
+ zipEntry.name
)
// f.createNewFile();
inputStream = zipFile.getInputStream(zipEntry)
out = FileOutputStream(f)
val by = ByteArray(1024)
var c: Int = inputStream?.read(by) ?: -1
while (c != -1) {
out.write(by, 0, c)
c = inputStream?.read(by) ?: -1
}
out.flush()
}
} catch (ex: IOException) {
ex.printStackTrace()
throw IOException("解压失败:" + ex.toString())
} finally {
if (inputStream != null) {
try {
inputStream.close()
} catch (ex: IOException) {
}

}
if (out != null) {
try {
out.close()
} catch (ex: IOException) {
}

}
}
}
} catch (ex: IOException) {
ex.printStackTrace()
throw IOException("解压失败:" + ex.toString())
} finally {
if (zipFile != null) {
try {
zipFile.close()
} catch (ex: IOException) {
}

}
}
}
}


fun File.zip(): File? {
return ZipUtils.zip(this)
}


fun File.zip(outFile: File) {
return ZipUtils.zip(this, outFile)
}
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@ object ShellManager {
if (commandResult.isSuccessful.not()) {
return false
}
commandResult = ShellUtils.runWithSu("cp $source $dst && chmod $mod $dst")
commandResult = ShellUtils.runWithSu("cp -R $source $dst && chmod $mod $dst")
if (commandResult.isSuccessful.not()) {
}
return commandResult.isSuccessful
}

Expand Down

0 comments on commit 4d2b5eb

Please sign in to comment.