Skip to content

Commit ef822d3

Browse files
committed
Update
1 parent 3be9cae commit ef822d3

File tree

2 files changed

+64
-103
lines changed

2 files changed

+64
-103
lines changed

app/src/main/java/com/tool/tree/MainActivity.kt

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package com.tool.tree
22

3-
import android.Manifest
43
import android.content.ComponentName
54
import android.content.Intent
6-
import android.content.pm.PackageManager
75
import android.net.Uri
8-
import android.os.Build
96
import android.os.Bundle
107
import android.view.LayoutInflater
118
import android.view.Menu
@@ -18,8 +15,7 @@ import androidx.activity.addCallback
1815
import androidx.appcompat.app.AppCompatActivity
1916
import androidx.appcompat.widget.ListPopupWindow
2017
import androidx.appcompat.widget.Toolbar
21-
import androidx.core.app.ActivityCompat
22-
import androidx.core.content.ContextCompat
18+
import androidx.core.app.NotificationManagerCompat
2319
import androidx.lifecycle.lifecycleScope
2420
import com.google.android.material.tabs.TabLayout
2521
import com.google.android.material.tabs.TabLayoutMediator
@@ -38,7 +34,6 @@ import com.tool.tree.ui.TabIconHelper
3834
import kotlinx.coroutines.Dispatchers
3935
import kotlinx.coroutines.launch
4036
import kotlinx.coroutines.withContext
41-
import androidx.core.app.NotificationManagerCompat
4237

4338
class MainActivity : AppCompatActivity() {
4439

@@ -52,7 +47,6 @@ class MainActivity : AppCompatActivity() {
5247

5348
private val ACTION_FILE_PATH_CHOOSER = 65400
5449
private val ACTION_FILE_PATH_CHOOSER_INNER = 65300
55-
private val NOTIFICATION_PERMISSION_REQUEST_CODE = 101
5650
private lateinit var adapter: MainPagerAdapter
5751

5852
override fun onCreate(savedInstanceState: Bundle?) {
@@ -64,12 +58,13 @@ class MainActivity : AppCompatActivity() {
6458
setSupportActionBar(findViewById<Toolbar>(R.id.toolbar))
6559
setTitle(R.string.app_name)
6660

67-
// Kiểm tra quyền thông báo dựa trên cài đặt của người dùng
68-
checkNotificationPermission()
69-
7061
progressBarDialog.showDialog(getString(R.string.please_wait))
7162
loadTabs()
7263

64+
if (ThemeConfig(this).getAllowNotificationUI()) {
65+
WakeLockService.startService(applicationContext)
66+
}
67+
7368
onBackPressedDispatcher.addCallback(this) {
7469
startService(Intent(this@MainActivity, WakeLockService::class.java).apply {
7570
action = WakeLockService.ACTION_END_WAKELOCK
@@ -79,25 +74,6 @@ class MainActivity : AppCompatActivity() {
7974
}
8075
}
8176

82-
private fun checkNotificationPermission() {
83-
val themeConfig = ThemeConfig(this)
84-
if (themeConfig.getAllowNotificationUI()) {
85-
if (NotificationManagerCompat.from(this).areNotificationsEnabled()) {
86-
WakeLockService.startService(applicationContext)
87-
} else {
88-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
89-
ActivityCompat.requestPermissions(
90-
this,
91-
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
92-
NOTIFICATION_PERMISSION_REQUEST_CODE
93-
)
94-
} else {
95-
Toast.makeText(this, "Please enable notifications in your device settings.", Toast.LENGTH_SHORT).show()
96-
}
97-
}
98-
}
99-
}
100-
10177
private fun loadTabs() {
10278
lifecycleScope.launch(Dispatchers.IO) {
10379
val favorites = getItems(krScriptConfig.favoriteConfig)

app/src/main/java/com/tool/tree/SplashActivity.kt

Lines changed: 59 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ class SplashActivity : AppCompatActivity() {
5151
binding = ActivitySplashBinding.inflate(layoutInflater)
5252
setContentView(binding.root)
5353

54-
// Edge-to-edge hỗ trợ từ Android 6.0+ qua thư viện Compat
5554
WindowCompat.setDecorFitsSystemWindows(window, false)
5655

5756
if (ScriptEnvironmen.isInited() && isTaskRoot &&
@@ -64,40 +63,57 @@ class SplashActivity : AppCompatActivity() {
6463
showAgreementDialog()
6564
}
6665

67-
// Animation xoay logo
6866
val rotateAnim = AnimationUtils.loadAnimation(this, R.anim.ic_settings_rotate)
6967
binding.startLogoXml.startAnimation(rotateAnim)
7068

7169
applyTheme()
7270
}
7371

74-
// =================== QUẢN LÝ QUYỀN HẠN (SDK 23+) ===================
72+
// =================== PERMISSIONS & STORAGE ===================
7573

74+
private fun getRequiredPermissions(): Array<String> {
75+
return when {
76+
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
77+
arrayOf(Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_VIDEO)
78+
}
79+
else -> arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
80+
}
81+
}
82+
7683
private fun hasPermissions(): Boolean {
77-
// Ưu tiên kiểm tra quyền mạnh nhất trên Android 11+
78-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
79-
if (Environment.isExternalStorageManager()) return true
84+
// 1. Kiểm tra các quyền Runtime cơ bản
85+
val basicPermissions = getRequiredPermissions().all {
86+
ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
8087
}
81-
82-
// Kiểm tra quyền Storage truyền thống
83-
val read = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
84-
val write = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
85-
return read && write
88+
89+
// 2. Kiểm tra quyền MANAGE_EXTERNAL_STORAGE (Android 11+)
90+
val manageStoragePermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
91+
Environment.isExternalStorageManager()
92+
} else {
93+
true // Các bản cũ không có quyền này
94+
}
95+
96+
return basicPermissions && manageStoragePermission
8697
}
8798

8899
private fun requestAppPermissions() {
89100
saveAgreement()
101+
102+
// Bước 1: Xin các quyền Runtime cơ bản trước
103+
val missingBasic = getRequiredPermissions().filter {
104+
ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
105+
}
90106

91-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
92-
// Android 11+: Thử xin quyền All Files Access trước
93-
if (!Environment.isExternalStorageManager()) {
94-
requestManageStoragePermission()
95-
} else {
96-
startLogic()
97-
}
98-
} else {
99-
// Android 6.0 - 10: Xin quyền READ/WRITE
100-
checkFallbackPermissions()
107+
if (missingBasic.isNotEmpty()) {
108+
ActivityCompat.requestPermissions(this, missingBasic.toTypedArray(), REQUEST_CODE_PERMISSIONS)
109+
}
110+
// Bước 2: Nếu quyền cơ bản có rồi nhưng thiếu MANAGE_EXTERNAL_STORAGE trên A11+
111+
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
112+
requestManageStoragePermission()
113+
}
114+
// Bước 3: Đã đủ hết quyền
115+
else {
116+
startLogic()
101117
}
102118
}
103119

@@ -113,19 +129,19 @@ class SplashActivity : AppCompatActivity() {
113129
}
114130
}
115131

116-
private fun checkFallbackPermissions() {
117-
val permissions = arrayOf(
118-
Manifest.permission.READ_EXTERNAL_STORAGE,
119-
Manifest.permission.WRITE_EXTERNAL_STORAGE
120-
)
121-
val missing = permissions.filter {
122-
ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
123-
}
124-
125-
if (missing.isNotEmpty()) {
126-
ActivityCompat.requestPermissions(this, missing.toTypedArray(), REQUEST_CODE_PERMISSIONS)
127-
} else {
128-
startLogic()
132+
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
133+
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
134+
if (requestCode == REQUEST_CODE_PERMISSIONS) {
135+
if (grantResults.isNotEmpty() && grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
136+
// Sau khi có quyền cơ bản, kiểm tra tiếp MANAGE_STORAGE nếu cần
137+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
138+
requestManageStoragePermission()
139+
} else {
140+
startLogic()
141+
}
142+
} else {
143+
finish()
144+
}
129145
}
130146
}
131147

@@ -136,25 +152,12 @@ class SplashActivity : AppCompatActivity() {
136152
if (Environment.isExternalStorageManager()) {
137153
startLogic()
138154
} else {
139-
// FALLBACK: Nếu người dùng không cấp quyền MANAGE, xin quyền READ/WRITE cũ
140-
checkFallbackPermissions()
155+
finish() // Người dùng từ chối cấp quyền All Files Access
141156
}
142157
}
143158
}
144159
}
145160

146-
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
147-
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
148-
if (requestCode == REQUEST_CODE_PERMISSIONS) {
149-
if (grantResults.isNotEmpty() && grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
150-
startLogic()
151-
} else {
152-
// Nếu cả quyền cũ cũng bị từ chối -> Thoát
153-
finish()
154-
}
155-
}
156-
}
157-
158161
private fun startLogic() {
159162
if (!started) {
160163
started = true
@@ -164,13 +167,13 @@ class SplashActivity : AppCompatActivity() {
164167

165168
override fun onResume() {
166169
super.onResume()
167-
// Kiểm tra lại quyền khi người dùng quay lại từ Settings
170+
// Tự động kiểm tra nếu đã đồng nhất thỏa thuận nhưng chưa khởi chạy
168171
if (hasAgreed() && !started && hasPermissions()) {
169172
startLogic()
170173
}
171174
}
172175

173-
// =================== SHELL & LOGS (COROUTINES) ===================
176+
// =================== SHELL & LOGS ===================
174177

175178
private fun runBeforeStartSh(config: KrScriptConfig, hasRoot: Boolean) {
176179
lifecycleScope.launch(Dispatchers.IO) {
@@ -185,7 +188,6 @@ class SplashActivity : AppCompatActivity() {
185188
}
186189
}
187190

188-
// Đọc log song song
189191
val outJob = launch { readStreamAsync(p.inputStream.bufferedReader()) }
190192
val errJob = launch { readStreamAsync(p.errorStream.bufferedReader()) }
191193

@@ -227,12 +229,12 @@ class SplashActivity : AppCompatActivity() {
227229
}
228230
}
229231

230-
// =================== GIAO DIỆN & TIỆN ÍCH ===================
232+
// =================== HELPERS ===================
231233

232234
private fun applyAppLanguage() {
233235
runCatching {
234236
val langFile = File(filesDir, "home/log/language")
235-
val lang = langFile.takeIf { it.exists() }?.readText()?.trim() ?: return
237+
val lang = langFile.takeIf { it.exists() }?.readText()?.trim()?.takeIf { it.isNotEmpty() } ?: return
236238
val appLocale: LocaleListCompat = LocaleListCompat.forLanguageTags(lang.replace("_", "-"))
237239
AppCompatDelegate.setApplicationLocales(appLocale)
238240
}
@@ -242,25 +244,16 @@ class SplashActivity : AppCompatActivity() {
242244
val typedValue = TypedValue()
243245
theme.resolveAttribute(android.R.attr.windowBackground, typedValue, true)
244246
val bgColor = if (typedValue.resourceId != 0) ContextCompat.getColor(this, typedValue.resourceId) else typedValue.data
245-
246247
window.statusBarColor = bgColor
247248
window.navigationBarColor = bgColor
248-
249249
val controller = WindowCompat.getInsetsController(window, window.decorView)
250250
val isDark = ThemeModeState.isDarkMode()
251-
252251
controller.isAppearanceLightStatusBars = !isDark
253252
controller.isAppearanceLightNavigationBars = !isDark
254253
}
255254

256255
private fun showAgreementDialog() {
257-
DialogHelper.warning(
258-
this,
259-
getString(R.string.permission_dialog_title),
260-
getString(R.string.permission_dialog_message),
261-
{ requestAppPermissions() },
262-
{ finish() }
263-
).setCancelable(false)
256+
DialogHelper.warning(this, getString(R.string.permission_dialog_title), getString(R.string.permission_dialog_message), { requestAppPermissions() }, { finish() }).setCancelable(false)
264257
}
265258

266259
private fun hasAgreed() = getSharedPreferences("kr-script-config", MODE_PRIVATE).getBoolean("agreed_permissions", false)
@@ -283,21 +276,13 @@ class SplashActivity : AppCompatActivity() {
283276
private fun startToFinish() {
284277
binding.startStateText.text = getString(R.string.pop_started)
285278
val config = KrScriptConfig().init(this)
286-
if (config.beforeStartSh.isNotEmpty()) {
287-
runBeforeStartSh(config, hasRoot)
288-
} else {
289-
gotoHome()
290-
}
279+
if (config.beforeStartSh.isNotEmpty()) runBeforeStartSh(config, hasRoot) else gotoHome()
291280
}
292281

293282
private fun gotoHome() {
294283
val nextIntent = if (intent?.getBooleanExtra("JumpActionPage", false) == true) {
295-
Intent(this, ActionPage::class.java).apply {
296-
intent?.extras?.let { putExtras(it) }
297-
}
298-
} else {
299-
Intent(this, MainActivity::class.java)
300-
}
284+
Intent(this, ActionPage::class.java).apply { intent?.extras?.let { putExtras(it) } }
285+
} else Intent(this, MainActivity::class.java)
301286
startActivity(nextIntent)
302287
finish()
303288
}

0 commit comments

Comments
 (0)