Skip to content

Commit 8d3af6c

Browse files
committed
APP backup
1 parent 98fd966 commit 8d3af6c

File tree

23 files changed

+363
-246
lines changed

23 files changed

+363
-246
lines changed

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ dependencies {
4343
implementation fileTree(include: ['*.jar'], dir: 'libs')
4444
implementation 'androidx.appcompat:appcompat:1.7.0'
4545
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
46+
implementation 'net.dongliu:apk-parser:2.6.10'
4647
testImplementation 'junit:junit:4.12'
4748
androidTestImplementation 'com.android.support.test:runner:1.0.2'
4849
implementation 'com.google.code.gson:gson:2.10'
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.wrbug.developerhelper.model.entity
22

3+
import com.google.gson.annotations.SerializedName
4+
35
data class BackupAppInfo(
4-
var backupApk: Boolean = false,
5-
var backupData: Boolean = false,
6-
var backupAndroidData: Boolean = false,
7-
var versionName: String = "",
8-
var versionCode: Int = 0,
9-
var packageName: String = ""
6+
@SerializedName("appName")
7+
var appName: String = "",
8+
@SerializedName("backupMap")
9+
val backupMap: HashMap<String, BackupAppItemInfo> = hashMapOf()
1010
)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.wrbug.developerhelper.model.entity
2+
3+
import com.google.gson.annotations.SerializedName
4+
5+
data class BackupAppItemInfo(
6+
@SerializedName("backupApk")
7+
var backupApk: Boolean = false,
8+
@SerializedName("backupData")
9+
var backupData: Boolean = false,
10+
@SerializedName("backupAndroidData")
11+
var backupAndroidData: Boolean = false,
12+
@SerializedName("apkFile")
13+
var apkFile: String = "",
14+
@SerializedName("versionName")
15+
var versionName: String = "",
16+
@SerializedName("versionCode")
17+
var versionCode: Long = 0,
18+
@SerializedName("packageName")
19+
var packageName: String = "",
20+
@SerializedName("time")
21+
var time: Long = 0,
22+
@SerializedName("dataFile")
23+
var dataFile: String = "",
24+
@SerializedName("androidDataFile")
25+
var androidDataFile: String = "",
26+
) {
27+
companion object {
28+
val EMPTY = BackupAppItemInfo()
29+
}
30+
}

app/src/main/java/com/wrbug/developerhelper/service/DeveloperHelperAccessibilityService.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,18 @@ class DeveloperHelperAccessibilityService : AccessibilityService() {
6767
return false
6868
}
6969

70-
//todo java.lang.RuntimeException:android.os.TransactionTooLargeException
7170
val nodeMap: HashMap<Long, HierarchyNode> = hashMapOf()
7271
}
7372

7473
override fun onInterrupt() {
7574
}
7675

7776
override fun onAccessibilityEvent(event: AccessibilityEvent?) {
78-
if (event?.eventType != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED || event.className.isNullOrEmpty() || event.packageName.isNullOrEmpty()) {
77+
if (event?.eventType != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
78+
|| event.className.isNullOrEmpty()
79+
|| event.className?.startsWith("android.") == true
80+
|| event.packageName.isNullOrEmpty()
81+
) {
7982
return
8083
}
8184
runCatching {

app/src/main/java/com/wrbug/developerhelper/ui/activity/hierachy/AppInfoPagerAdapter.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
88
import androidx.recyclerview.widget.RecyclerView
99
import androidx.viewpager.widget.PagerAdapter
1010
import com.wrbug.developerhelper.R
11+
import com.wrbug.developerhelper.basecommon.versionCodeLong
1112
import com.wrbug.developerhelper.commonutil.entity.ApkInfo
1213
import com.wrbug.developerhelper.commonutil.shell.ShellManager
1314
import com.wrbug.developerhelper.ui.decoration.SpaceItemDecoration
@@ -86,7 +87,7 @@ class AppInfoPagerAdapter(
8687
itemInfos.add(ItemInfo("Activity", it))
8788
}
8889
itemInfos.add(ItemInfo("VersionName", it.packageInfo.versionName))
89-
itemInfos.add(ItemInfo("VersionCode", it.packageInfo.versionCode))
90+
itemInfos.add(ItemInfo("VersionCode", it.packageInfo.versionCodeLong))
9091
itemInfos.add(ItemInfo("uid", it.applicationInfo.uid))
9192
ShellManager.getPid(it.packageInfo.packageName).takeUnless { it.isEmpty() }?.let {
9293
itemInfos.add(ItemInfo("Pid", it))

app/src/main/java/com/wrbug/developerhelper/ui/activity/sharedpreferencesedit/SharedPreferenceEditActivity.kt

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@ import com.wrbug.developerhelper.R
1111
import com.wrbug.developerhelper.basecommon.BaseActivity
1212
import com.wrbug.developerhelper.basecommon.setupActionBar
1313
import com.wrbug.developerhelper.commonutil.AppManagerUtils
14-
import com.wrbug.developerhelper.commonutil.shell.ShellManager
15-
import com.wrbug.developerhelper.ui.decoration.SpaceItemDecoration
16-
import com.wrbug.developerhelper.util.OutSharedPreferenceManager
17-
import com.wrbug.developerhelper.util.XmlUtil
18-
import com.wrbug.developerhelper.commonutil.dp2px
14+
import com.wrbug.developerhelper.commonutil.addTo
1915
import com.wrbug.developerhelper.commonutil.dpInt
16+
import com.wrbug.developerhelper.commonutil.runOnIO
2017
import com.wrbug.developerhelper.databinding.ActivitySharedPreferenceEditBinding
21-
import org.jetbrains.anko.doAsync
22-
import org.jetbrains.anko.uiThread
18+
import com.wrbug.developerhelper.ui.decoration.SpaceItemDecoration
19+
import com.wrbug.developerhelper.util.OutSharedPreference
2320
import java.io.File
2421

2522
class SharedPreferenceEditActivity : BaseActivity() {
@@ -36,6 +33,7 @@ class SharedPreferenceEditActivity : BaseActivity() {
3633
private lateinit var adapter: SharedPreferenceListAdapter
3734
private var saveMenuItem: MenuItem? = null
3835
private lateinit var binding: ActivitySharedPreferenceEditBinding
36+
private lateinit var outSharedPreference: OutSharedPreference
3937

4038
companion object {
4139

@@ -60,7 +58,7 @@ class SharedPreferenceEditActivity : BaseActivity() {
6058
title = File(filePath).name
6159
}
6260
}
63-
61+
outSharedPreference = OutSharedPreference(this, filePath)
6462
binding.sprefRv.layoutManager = LinearLayoutManager(this)
6563
adapter = SharedPreferenceListAdapter(this)
6664
binding.sprefRv.adapter = adapter
@@ -77,18 +75,15 @@ class SharedPreferenceEditActivity : BaseActivity() {
7775
)
7876
binding.sprefRv.addItemDecoration(spaceItemDecoration)
7977
parseXml()
80-
8178
}
8279

8380
private fun parseXml() {
84-
doAsync {
85-
val xml = ShellManager.catFile(filePath)
86-
val list = XmlUtil.parseSharedPreference(xml)
87-
uiThread {
88-
saveMenuItem?.isVisible = false
89-
adapter.setData(list)
90-
}
91-
}
81+
outSharedPreference.parse().runOnIO().subscribe({
82+
saveMenuItem?.isVisible = false
83+
adapter.setData(it)
84+
}, {
85+
86+
}).addTo(disposable)
9287
}
9388

9489
override fun onBackPressed() {
@@ -104,43 +99,16 @@ class SharedPreferenceEditActivity : BaseActivity() {
10499
private fun showSaveDialog() {
105100
AlertDialog.Builder(this).setMessage(getString(R.string.confirm_shared_preference_save))
106101
.setTitle(R.string.notice).setPositiveButton(R.string.save_and_exit) { _, _ ->
107-
if (doSave()) {
108-
showDialog(R.string.notice,
109-
getString(R.string.save_shared_preference_success, appName),
110-
R.string.ok,
111-
R.string.cancel,
112-
{
113-
AppManagerUtils.restartApp(
114-
this@SharedPreferenceEditActivity, filePackageName
115-
)
116-
finish()
117-
},
118-
{
119-
finish()
120-
})
121-
} else {
122-
showSnack(getString(R.string.save_shared_preference_failed))
123-
}
102+
doSave()
124103
}.setNegativeButton(getString(R.string.do_not_save)) { _, _ ->
125104
finish()
126105
}.show()
127106
}
128107

129-
private fun doSave(): Boolean {
108+
private fun doSave() {
130109
val data = adapter.getData()
131-
val file = OutSharedPreferenceManager.saveToFile(this, data)
132-
val success = ShellManager.catFile(file.absolutePath, filePath, "666")
133-
file.delete()
134-
return success
135-
}
136-
137-
override fun onOptionsItemSelected(item: MenuItem): Boolean {
138-
when (item.itemId) {
139-
R.id.save_menu -> {
140-
if (!doSave()) {
141-
showSnack(getString(R.string.save_shared_preference_failed))
142-
return super.onOptionsItemSelected(item)
143-
}
110+
outSharedPreference.saveToFile(this, data).runOnIO().subscribe({
111+
if (it) {
144112
parseXml()
145113
showDialog(R.string.notice,
146114
getString(R.string.save_shared_preference_success, appName),
@@ -152,11 +120,28 @@ class SharedPreferenceEditActivity : BaseActivity() {
152120
)
153121
finish()
154122
})
123+
} else {
124+
showSnack(getString(R.string.save_shared_preference_failed))
125+
}
126+
}, {
127+
128+
}).addTo(disposable)
129+
}
130+
131+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
132+
when (item.itemId) {
133+
R.id.save_menu -> {
134+
doSave()
155135
}
156136
}
157137
return super.onOptionsItemSelected(item)
158138
}
159139

140+
override fun onDestroy() {
141+
super.onDestroy()
142+
outSharedPreference.deleteTmpFile()
143+
}
144+
160145
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
161146
menuInflater.inflate(R.menu.menu_shared_preference_edit, menu)
162147
saveMenuItem = menu?.findItem(R.id.save_menu)

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

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,32 @@
11
package com.wrbug.developerhelper.ui.widget.appsettingview
22

3-
import android.Manifest
43
import android.app.Activity
54
import android.content.Context
6-
import android.net.Uri
75
import android.util.AttributeSet
86
import android.view.LayoutInflater
97
import android.widget.ScrollView
108
import androidx.appcompat.app.AlertDialog
119
import androidx.fragment.app.FragmentActivity
1210
import com.wrbug.developerhelper.BuildConfig
1311
import com.wrbug.developerhelper.R
14-
import com.wrbug.developerhelper.basecommon.BaseActivity
1512
import com.wrbug.developerhelper.basecommon.requestStoragePermission
1613
import com.wrbug.developerhelper.basecommon.showToast
1714
import com.wrbug.developerhelper.commonutil.AppManagerUtils
1815
import com.wrbug.developerhelper.commonutil.entity.ApkInfo
19-
import com.wrbug.developerhelper.commonutil.toUri
20-
import com.wrbug.developerhelper.commonutil.zip
2116
import com.wrbug.developerhelper.commonwidget.util.setOnRootCheckClickListener
2217
import com.wrbug.developerhelper.commonwidget.util.visible
2318
import com.wrbug.developerhelper.databinding.DialogBackupAppSelectBinding
2419
import com.wrbug.developerhelper.databinding.ViewAppSettingBinding
2520
import com.wrbug.developerhelper.mmkv.ConfigKv
2621
import com.wrbug.developerhelper.mmkv.manager.MMKVManager
27-
import com.wrbug.developerhelper.util.BackupUtils
28-
import gdut.bsx.share2.Share2
29-
import gdut.bsx.share2.ShareContentType
30-
import java.io.File
22+
import io.reactivex.rxjava3.disposables.CompositeDisposable
3123

3224
class AppSettingView : ScrollView {
3325

3426
private var apkInfo: ApkInfo? = null
3527
private val configKv = MMKVManager.get(ConfigKv::class.java)
3628
private lateinit var binding: ViewAppSettingBinding
29+
private lateinit var disposable: CompositeDisposable
3730

3831
constructor(context: Context) : super(context) {
3932
initView()
@@ -57,12 +50,10 @@ class AppSettingView : ScrollView {
5750

5851
private fun initListener() {
5952
binding.backupAppBtn.setOnRootCheckClickListener {
60-
showBackSelect()
61-
// doBackupApk()
53+
showBackupSelect()
54+
}
55+
binding.restoreAppBtn.setOnRootCheckClickListener {
6256
}
63-
// binding.backupApkDataDirBtn.setOnRootCheckClickListener {
64-
// doBackupDataDir()
65-
// }
6657
binding.restartAppBtn.setOnRootCheckClickListener {
6758
doRestartApp()
6859
}
@@ -77,27 +68,39 @@ class AppSettingView : ScrollView {
7768
}
7869
}
7970

80-
private fun showBackSelect() {
81-
val selected = booleanArrayOf(false, false, false)
82-
val binding = DialogBackupAppSelectBinding.inflate(LayoutInflater.from(context))
83-
binding.cbApk.setOnCheckedChangeListener { _, isChecked ->
84-
selected[0] = isChecked
85-
}
86-
binding.cbData.setOnCheckedChangeListener { _, isChecked ->
87-
selected[1] = isChecked
88-
}
89-
binding.cbAndroidData.setOnCheckedChangeListener { _, isChecked ->
90-
selected[2] = isChecked
71+
private fun showBackupSelect() {
72+
context.requestStoragePermission {
73+
val selected = booleanArrayOf(false, false, false)
74+
val binding = DialogBackupAppSelectBinding.inflate(LayoutInflater.from(context))
75+
binding.cbApk.setOnCheckedChangeListener { _, isChecked ->
76+
selected[0] = isChecked
77+
}
78+
binding.cbData.setOnCheckedChangeListener { _, isChecked ->
79+
selected[1] = isChecked
80+
}
81+
binding.cbAndroidData.setOnCheckedChangeListener { _, isChecked ->
82+
selected[2] = isChecked
83+
}
84+
AlertDialog.Builder(context)
85+
.setTitle(R.string.backup_app_file)
86+
.setView(binding.root)
87+
.setNegativeButton(R.string.cancel, null)
88+
.setPositiveButton(
89+
R.string.ok
90+
) { _, _ ->
91+
doBackup(selected)
92+
}.create().show()
9193
}
92-
AlertDialog.Builder(context)
93-
.setTitle(R.string.backup_app_file)
94-
.setView(binding.root)
95-
.setNegativeButton(R.string.cancel, null)
96-
.setPositiveButton(
97-
R.string.ok
98-
) { _, _ ->
99-
doBackup(selected)
100-
}.create().show()
94+
}
95+
96+
override fun onAttachedToWindow() {
97+
super.onAttachedToWindow()
98+
disposable = CompositeDisposable()
99+
}
100+
101+
override fun onDetachedFromWindow() {
102+
super.onDetachedFromWindow()
103+
disposable.dispose()
101104
}
102105

103106
private fun doBackup(selected: BooleanArray) {

0 commit comments

Comments
 (0)