Skip to content

Commit 0ee2026

Browse files
committed
fix data backup
1 parent 350a42f commit 0ee2026

File tree

7 files changed

+136
-85
lines changed

7 files changed

+136
-85
lines changed

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ dependencies {
5151
implementation 'com.google.code.gson:gson:2.10'
5252
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
5353
implementation 'com.github.yhaolpz:FloatWindow:1.0.9'
54-
implementation project(':basecommon')
54+
api project(':basecommon')
5555
kapt "com.android.databinding:compiler:3.1.4"
5656
implementation 'com.elvishew:xlog:1.6.1'
5757
implementation 'org.jetbrains.anko:anko-commons:0.10.8'

app/src/main/AndroidManifest.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55
<uses-permission android:name="android.permission.INTERNET" />
66
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
77
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
8-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
9-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
8+
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
9+
<uses-permission
10+
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
11+
android:maxSdkVersion="32" />
12+
<uses-permission
13+
android:name="android.permission.READ_EXTERNAL_STORAGE"
14+
android:maxSdkVersion="32" />
1015
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
1116
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
1217
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

app/src/main/java/com/wrbug/developerhelper/ui/widget/appsettingview/AppSettingView.kt

Lines changed: 61 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,29 @@ package com.wrbug.developerhelper.ui.widget.appsettingview
22

33
import android.Manifest
44
import android.app.Activity
5-
import android.app.AlertDialog
65
import android.content.Context
7-
import android.content.DialogInterface
6+
import android.net.Uri
87
import android.util.AttributeSet
98
import android.view.LayoutInflater
109
import android.widget.ScrollView
10+
import androidx.appcompat.app.AlertDialog
11+
import com.wrbug.developerhelper.BuildConfig
1112
import com.wrbug.developerhelper.R
13+
import com.wrbug.developerhelper.basecommon.BaseActivity
14+
import com.wrbug.developerhelper.basecommon.requestStoragePermission
1215
import com.wrbug.developerhelper.basecommon.showToast
1316
import com.wrbug.developerhelper.commonutil.AppManagerUtils
1417
import com.wrbug.developerhelper.commonutil.entity.ApkInfo
15-
import com.wrbug.developerhelper.mmkv.ConfigKv
16-
import com.wrbug.developerhelper.mmkv.manager.MMKVManager
17-
import android.content.Intent
18-
import android.net.Uri
19-
import androidx.appcompat.widget.AppCompatButton
20-
import com.wrbug.developerhelper.BuildConfig
21-
import com.wrbug.developerhelper.basecommon.BaseActivity
22-
import com.wrbug.developerhelper.commonutil.shell.ShellManager
23-
import com.wrbug.developerhelper.commonutil.zip
24-
import com.wrbug.developerhelper.util.BackupUtils
2518
import com.wrbug.developerhelper.commonutil.toUri
26-
import com.wrbug.developerhelper.commonwidget.util.setOnDoubleCheckClickListener
19+
import com.wrbug.developerhelper.commonutil.zip
2720
import com.wrbug.developerhelper.commonwidget.util.setOnRootCheckClickListener
2821
import com.wrbug.developerhelper.commonwidget.util.visible
2922
import com.wrbug.developerhelper.databinding.ViewAppSettingBinding
23+
import com.wrbug.developerhelper.mmkv.ConfigKv
24+
import com.wrbug.developerhelper.mmkv.manager.MMKVManager
25+
import com.wrbug.developerhelper.util.BackupUtils
3026
import gdut.bsx.share2.Share2
3127
import gdut.bsx.share2.ShareContentType
32-
import org.jetbrains.anko.doAsync
33-
import org.jetbrains.anko.uiThread
3428
import java.io.File
3529

3630
class AppSettingView : ScrollView {
@@ -93,7 +87,7 @@ class AppSettingView : ScrollView {
9387
apkInfo?.apply {
9488
showNotice(
9589
context.getString(R.string.confirm_delete_app_data)
96-
) { _, _ ->
90+
) {
9791
if (AppManagerUtils.clearAppData(applicationInfo.packageName)) {
9892
activityFinish()
9993
showToast(context.getString(R.string.clear_complete))
@@ -108,7 +102,7 @@ class AppSettingView : ScrollView {
108102
return
109103
}
110104
apkInfo?.apply {
111-
showNotice(context.getString(R.string.confirm_stop_app)) { _, _ ->
105+
showNotice(context.getString(R.string.confirm_stop_app)) {
112106
if (AppManagerUtils.forceStopApp(applicationInfo.packageName)) {
113107
activityFinish()
114108
}
@@ -121,11 +115,12 @@ class AppSettingView : ScrollView {
121115
return
122116
}
123117
apkInfo?.apply {
124-
showNotice(context.getString(R.string.confirm_restart_app),
125-
DialogInterface.OnClickListener { _, _ ->
126-
AppManagerUtils.restartApp(context, applicationInfo.packageName)
127-
activityFinish()
128-
})
118+
showNotice(
119+
context.getString(R.string.confirm_restart_app)
120+
) {
121+
AppManagerUtils.restartApp(context, applicationInfo.packageName)
122+
activityFinish()
123+
}
129124
}
130125
}
131126

@@ -134,8 +129,7 @@ class AppSettingView : ScrollView {
134129
return
135130
}
136131
apkInfo?.apply {
137-
val backupAppData =
138-
BackupUtils.backupAppData(applicationInfo.packageName, applicationInfo.dataDir)
132+
val backupAppData = BackupUtils.backupAppData(applicationInfo.packageName)
139133
if (backupAppData == null) {
140134
showToast(context.getString(R.string.backup_failed))
141135
return
@@ -149,68 +143,58 @@ class AppSettingView : ScrollView {
149143
}
150144

151145
private fun showShareDataNotice(backupAppData: File) {
152-
showNotice(context.getString(R.string.backup_success_and_share_msg),
153-
DialogInterface.OnClickListener { _, _ ->
154-
(context as BaseActivity).requestPermission(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
155-
object : BaseActivity.PermissionCallback() {
156-
override fun granted() {
157-
val zipFile = File(
158-
context.externalCacheDir, "${apkInfo?.getAppName() ?: ""}-data.zip"
159-
)
160-
backupAppData.zip(zipFile)
161-
val uri = zipFile.toUri(context)
162-
if (uri == null) {
163-
showToast(context.getString(R.string.share_failed))
164-
return
165-
}
166-
activityFinish()
167-
Share2.Builder(context as Activity)
168-
.setContentType(ShareContentType.FILE).setShareFileUri(uri)
169-
.setOnActivityResult(10).build().shareBySystem()
146+
showNotice(context.getString(R.string.backup_success_and_share_msg)) {
147+
(context as BaseActivity).requestPermission(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
148+
object : BaseActivity.PermissionCallback() {
149+
override fun granted() {
150+
val zipFile = File(
151+
context.externalCacheDir, "${apkInfo?.getAppName() ?: ""}-data.zip"
152+
)
153+
backupAppData.zip(zipFile)
154+
val uri = zipFile.toUri(context)
155+
if (uri == null) {
156+
showToast(context.getString(R.string.share_failed))
157+
return
170158
}
159+
activityFinish()
160+
Share2.Builder(context as Activity).setContentType(ShareContentType.FILE)
161+
.setShareFileUri(uri).setOnActivityResult(10).build().shareBySystem()
162+
}
171163

172-
})
164+
})
173165

174-
})
166+
}
175167
}
176168

177169
private fun doBackupApk() {
178170
if (checkRoot().not()) {
179171
return
180172
}
181-
apkInfo?.apply {
182-
val uri = BackupUtils.backupApk(
183-
applicationInfo.packageName,
184-
applicationInfo.publicSourceDir,
185-
"${getAppName()}_${packageInfo.versionName}.apk"
186-
)
187-
if (uri == null) {
188-
showToast(context.getString(R.string.backup_failed))
189-
return
190-
}
191-
if (context !is BaseActivity) {
192-
showToast(context.getString(R.string.backup_success_msg))
193-
return
173+
context.requestStoragePermission {
174+
apkInfo?.apply {
175+
val uri = BackupUtils.backupApk(
176+
applicationInfo.packageName,
177+
applicationInfo.publicSourceDir,
178+
"${getAppName()}_${packageInfo.versionName}.apk"
179+
)
180+
if (uri == null) {
181+
showToast(context.getString(R.string.backup_failed))
182+
return@apply
183+
}
184+
if (context !is BaseActivity) {
185+
showToast(context.getString(R.string.backup_success_msg))
186+
return@apply
187+
}
188+
showShareApkDialog(uri)
194189
}
195-
showShareApkDialog(uri)
196-
197190
}
198191
}
199192

200193
private fun showShareApkDialog(uri: Uri) {
201-
showNotice(context.getString(R.string.backup_success_and_share_msg)) { _, _ ->
202-
(context as BaseActivity).requestPermission(arrayOf(
203-
Manifest.permission.READ_EXTERNAL_STORAGE,
204-
Manifest.permission.WRITE_EXTERNAL_STORAGE
205-
), object : BaseActivity.PermissionCallback() {
206-
override fun granted() {
207-
activityFinish()
208-
Share2.Builder(context as Activity).setContentType(ShareContentType.FILE)
209-
.setShareFileUri(uri).setOnActivityResult(10).build().shareBySystem()
210-
}
211-
212-
})
213-
194+
showNotice(context.getString(R.string.backup_success_and_share_msg)) {
195+
activityFinish()
196+
Share2.Builder(context as Activity).setContentType(ShareContentType.FILE)
197+
.setShareFileUri(uri).setOnActivityResult(10).build().shareBySystem()
214198
}
215199
}
216200

@@ -228,9 +212,11 @@ class AppSettingView : ScrollView {
228212
}
229213
}
230214

231-
private fun showNotice(msg: String, listener: DialogInterface.OnClickListener) {
215+
private fun showNotice(msg: String, listener: () -> Unit) {
232216
AlertDialog.Builder(context).setTitle(R.string.notice).setMessage(msg)
233-
.setNegativeButton(R.string.cancel, null).setPositiveButton(R.string.ok, listener)
234-
.create().show()
217+
.setNegativeButton(R.string.cancel, null).setPositiveButton(
218+
R.string.ok
219+
) { _, _ -> listener() }.create().show()
235220
}
221+
236222
}

app/src/main/java/com/wrbug/developerhelper/util/BackupUtils.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ package com.wrbug.developerhelper.util
33
import android.net.Uri
44
import android.os.Environment
55
import com.wrbug.developerhelper.basecommon.BaseApp
6+
import com.wrbug.developerhelper.commonutil.Constant
67
import com.wrbug.developerhelper.commonutil.shell.ShellManager
78
import com.wrbug.developerhelper.commonutil.toUri
89
import java.io.File
910

1011
object BackupUtils {
1112
private val backupDir: File by lazy {
12-
val file = File(Environment.getExternalStorageDirectory(), "com.wrbug.developerHelper/backup")
13+
val file =
14+
File(Environment.getExternalStorageDirectory(), "com.wrbug.developerHelper/backup")
1315
if (file.exists().not()) {
1416
file.mkdirs()
1517
}
@@ -24,9 +26,12 @@ object BackupUtils {
2426
return null
2527
}
2628

27-
fun backupAppData(packageName: String, dataDir: String): File? {
28-
val backupDataDir =
29-
File(backupDir, "datas/$packageName/${System.currentTimeMillis().format("yyyy-MM-dd-HH_mm_ss")}")
29+
fun backupAppData(packageName: String): File? {
30+
val backupDataDir = File(
31+
backupDir,
32+
"datas/$packageName/${System.currentTimeMillis().format("yyyy-MM-dd-HH_mm_ss")}"
33+
)
34+
val dataDir = Constant.getDataDir(packageName)
3035
if (ShellManager.cpFile(dataDir, backupDataDir.absolutePath)) {
3136
return backupDataDir
3237
}

basecommon/src/main/java/com/wrbug/developerhelper/basecommon/AppCompatActivityExt.kt

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,16 @@
1515
*/
1616
package com.wrbug.developerhelper.basecommon
1717

18+
import android.Manifest
19+
import android.content.Context
1820
import android.content.Intent
21+
import android.net.Uri
22+
import android.os.Build
23+
import android.os.Environment
24+
import android.provider.Settings
1925
import androidx.annotation.IdRes
2026
import androidx.appcompat.app.ActionBar
27+
import androidx.appcompat.app.AlertDialog
2128
import androidx.appcompat.app.AppCompatActivity
2229
import androidx.fragment.app.FragmentManager
2330
import androidx.fragment.app.FragmentTransaction
@@ -56,12 +63,54 @@ fun AppCompatActivity.startActivityForResult(intent: Intent, callback: ActivityR
5663
}
5764

5865
fun AppCompatActivity.startActivityForResultOk(
59-
intent: Intent,
60-
action: Intent?.() -> Unit
66+
intent: Intent, action: Intent?.() -> Unit
6167
) {
6268
ActResultRequest(this).startForResult(intent, object : ActivityResultCallback() {
6369
override fun onActivityResultOk(data: Intent?) {
6470
action(data)
6571
}
6672
})
6773
}
74+
75+
76+
fun Context.requestStoragePermission(callback: () -> Unit) {
77+
if (this !is BaseActivity) {
78+
return
79+
}
80+
when {
81+
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
82+
if (!Environment.isExternalStorageManager()) {
83+
AlertDialog.Builder(this).setTitle(R.string.notice)
84+
.setMessage("该功能需要读写内部存储权限,点击前往设置")
85+
.setNegativeButton(R.string.cancel, null).setPositiveButton(
86+
R.string.ok
87+
) { _, _ ->
88+
try {
89+
val intent =
90+
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
91+
intent.addCategory("android.intent.category.DEFAULT")
92+
intent.data = Uri.parse(String.format("package:%s", packageName))
93+
startActivity(intent)
94+
} catch (e: Exception) {
95+
val intent = Intent()
96+
intent.action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
97+
startActivity(intent)
98+
}
99+
}.create().show()
100+
} else {
101+
callback()
102+
}
103+
}
104+
105+
else -> {
106+
requestPermission(arrayOf(
107+
Manifest.permission.WRITE_EXTERNAL_STORAGE,
108+
Manifest.permission.READ_EXTERNAL_STORAGE
109+
), object : BaseActivity.PermissionCallback() {
110+
override fun granted() {
111+
callback()
112+
}
113+
})
114+
}
115+
}
116+
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
<resources>
2-
<string name="app_name">baseCommon</string>
2+
<string name="notice">提示</string>
3+
<string name="ok">确定</string>
4+
<string name="cancel">取消</string>
35
</resources>

commonutil/src/main/java/com/wrbug/developerhelper/commonutil/Constant.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ object Constant {
66
private const val DATA_MIRROR_DIR = "/data_mirror/data_ce/null/0"
77
private const val DATA_DIR = "/data/data"
88

9+
fun getDataDir(packageName: String): String {
10+
return "$dataDir/$packageName"
11+
}
12+
913
val dataDir by lazy {
1014
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
1115
DATA_MIRROR_DIR

0 commit comments

Comments
 (0)