Skip to content

Commit 713f0b1

Browse files
committed
Upload file
1 parent bda5e38 commit 713f0b1

2 files changed

Lines changed: 360 additions & 0 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class MainActivity : AppCompatActivity() {
4949
ThemeModeState.switchTheme(this)
5050
binding = ActivityMainBinding.inflate(layoutInflater)
5151
setContentView(binding.root)
52+
53+
throw RuntimeException("Test crash")
5254

5355
val toolbar = findViewById<View>(R.id.toolbar) as Toolbar
5456
setSupportActionBar(toolbar)
Lines changed: 358 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
1+
package com.tool.tree
2+
3+
import android.app.Activity
4+
import android.Manifest
5+
import android.content.ComponentName
6+
import android.content.Intent
7+
import android.content.pm.PackageManager
8+
import android.net.Uri
9+
import android.os.Build
10+
import android.os.Bundle
11+
import android.os.Handler
12+
import android.provider.Settings
13+
import android.util.DisplayMetrics
14+
import android.view.LayoutInflater
15+
import android.view.Menu
16+
import android.view.MenuItem
17+
import android.view.View
18+
import android.widget.CompoundButton
19+
import android.widget.Toast
20+
import androidx.appcompat.app.AppCompatActivity
21+
import androidx.appcompat.widget.Toolbar
22+
import androidx.core.content.ContextCompat
23+
import com.omarea.common.shared.FilePathResolver
24+
import com.omarea.common.ui.DialogHelper
25+
import com.omarea.common.ui.ProgressBarDialog
26+
import com.omarea.krscript.config.PageConfigReader
27+
import com.omarea.krscript.config.PageConfigSh
28+
import com.omarea.krscript.model.*
29+
import com.omarea.krscript.ui.ActionListFragment
30+
import com.omarea.krscript.ui.ParamsFileChooserRender
31+
import com.omarea.vtools.FloatMonitor
32+
import com.tool.tree.databinding.ActivityMainBinding
33+
import com.omarea.common.shell.KeepShellPublic
34+
import com.tool.tree.ui.TabIconHelper
35+
import androidx.core.view.isVisible
36+
import androidx.activity.OnBackPressedDispatcher
37+
import androidx.activity.ComponentActivity
38+
import androidx.activity.OnBackPressedCallback
39+
40+
class MainActivity : AppCompatActivity() {
41+
private val progressBarDialog = ProgressBarDialog(this)
42+
private var handler = Handler()
43+
private var krScriptConfig = KrScriptConfig()
44+
private val hasRoot by lazy { KeepShellPublic.checkRoot() }
45+
private lateinit var binding: ActivityMainBinding
46+
47+
override fun onCreate(savedInstanceState: Bundle?) {
48+
super.onCreate(savedInstanceState)
49+
ThemeModeState.switchTheme(this)
50+
binding = ActivityMainBinding.inflate(layoutInflater)
51+
setContentView(binding.root)
52+
53+
val toolbar = findViewById<View>(R.id.toolbar) as Toolbar
54+
setSupportActionBar(toolbar)
55+
setTitle(R.string.app_name)
56+
krScriptConfig = KrScriptConfig()
57+
binding.mainTabhost.setup()
58+
59+
val tabIconHelper = TabIconHelper(binding.mainTabhost, this)
60+
if (tabIconHelper != null) {
61+
if (hasRoot && krScriptConfig.allowHomePage) {
62+
tabIconHelper.newTabSpec(getString(R.string.tab_home), getDrawable(R.drawable.tab_home)!!, R.id.main_tabhost_cpu)
63+
} else {
64+
binding.mainTabhostCpu.visibility = View.GONE
65+
}
66+
}
67+
binding.mainTabhost.setOnTabChangedListener {
68+
tabIconHelper.updateHighlight()
69+
}
70+
71+
progressBarDialog.showDialog(getString(R.string.please_wait))
72+
Thread {
73+
val page2Config = krScriptConfig.pageListConfig
74+
val favoritesConfig = krScriptConfig.favoriteConfig
75+
76+
val pages = getItems(page2Config)
77+
val favorites = getItems(favoritesConfig)
78+
handler.post {
79+
progressBarDialog.hideDialog()
80+
81+
if (favorites != null && favorites.isNotEmpty()) {
82+
updateFavoritesTab(favorites, favoritesConfig)
83+
tabIconHelper.newTabSpec(
84+
getString(R.string.tab_favorites),
85+
ContextCompat.getDrawable(this, R.drawable.tab_favorites)!!,
86+
R.id.main_tabhost_2
87+
)
88+
} else {
89+
binding.mainTabhost2.visibility = View.GONE
90+
}
91+
92+
if (pages != null && pages.isNotEmpty()) {
93+
updateMoreTab(pages, page2Config)
94+
tabIconHelper.newTabSpec(
95+
getString(R.string.tab_pages),
96+
ContextCompat.getDrawable(this, R.drawable.tab_pages)!!,
97+
R.id.main_tabhost_3
98+
)
99+
} else {
100+
binding.mainTabhost3.visibility = View.GONE
101+
}
102+
}
103+
}.start()
104+
105+
if (hasRoot && krScriptConfig.allowHomePage) {
106+
val home = FragmentHome()
107+
val fragmentManager = supportFragmentManager
108+
val transaction = fragmentManager.beginTransaction()
109+
transaction.replace(R.id.main_tabhost_cpu, home)
110+
transaction.commitAllowingStateLoss()
111+
}
112+
113+
val themeConfig = ThemeConfig(applicationContext)
114+
if (themeConfig.getAllowNotificationUI()) {
115+
WakeLockService.startService(applicationContext)
116+
}
117+
118+
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
119+
override fun handleOnBackPressed() {
120+
startService(Intent(this@MainActivity, WakeLockService::class.java).apply { action = WakeLockService.ACTION_END_WAKELOCK })
121+
isEnabled = false
122+
onBackPressedDispatcher.onBackPressed()
123+
}
124+
})
125+
}
126+
127+
private fun getItems(pageNode: PageNode): ArrayList<NodeInfoBase>? {
128+
var items: ArrayList<NodeInfoBase>? = null
129+
130+
if (pageNode.pageConfigSh.isNotEmpty()) {
131+
items = PageConfigSh(this, pageNode.pageConfigSh, null).execute()
132+
}
133+
if (items == null && pageNode.pageConfigPath.isNotEmpty()) {
134+
items = PageConfigReader(this.applicationContext, pageNode.pageConfigPath, null).readConfigXml()
135+
}
136+
137+
return items
138+
}
139+
140+
private fun updateFavoritesTab(items: ArrayList<NodeInfoBase>, pageNode: PageNode) {
141+
val favoritesFragment = ActionListFragment.create(items, getKrScriptActionHandler(pageNode, true), null, ThemeModeState.getThemeMode())
142+
supportFragmentManager.beginTransaction().replace(R.id.list_favorites, favoritesFragment).commitAllowingStateLoss()
143+
}
144+
145+
private fun updateMoreTab(items: ArrayList<NodeInfoBase>, pageNode: PageNode) {
146+
val allItemFragment = ActionListFragment.create(items, getKrScriptActionHandler(pageNode, false), null, ThemeModeState.getThemeMode())
147+
supportFragmentManager.beginTransaction().replace(R.id.list_pages, allItemFragment).commitAllowingStateLoss()
148+
}
149+
150+
private fun reloadFavoritesTab() {
151+
Thread {
152+
val favoritesConfig = krScriptConfig.favoriteConfig
153+
val favorites = getItems(favoritesConfig)
154+
favorites?.run {
155+
handler.post {
156+
updateFavoritesTab(this, favoritesConfig)
157+
}
158+
}
159+
}.start()
160+
}
161+
162+
private fun reloadMoreTab() {
163+
Thread {
164+
val page2Config = krScriptConfig.pageListConfig
165+
val pages = getItems(page2Config)
166+
167+
pages?.run {
168+
handler.post {
169+
updateMoreTab(this, page2Config)
170+
}
171+
}
172+
}.start()
173+
}
174+
175+
private fun getKrScriptActionHandler(pageNode: PageNode, isFavoritesTab: Boolean): KrScriptActionHandler {
176+
return object : KrScriptActionHandler {
177+
override fun onActionCompleted(runnableNode: RunnableNode) {
178+
if (runnableNode.autoFinish) {
179+
finishAndRemoveTask()
180+
} else if (runnableNode.reloadPage) {
181+
if (isFavoritesTab) {
182+
reloadFavoritesTab()
183+
} else {
184+
reloadMoreTab()
185+
}
186+
} else if (runnableNode.autoKill) {
187+
startService(Intent(this@MainActivity, WakeLockService::class.java).apply { action = WakeLockService.ACTION_END_WAKELOCK })
188+
finishAffinity()
189+
System.exit(0)
190+
}
191+
}
192+
193+
override fun addToFavorites(clickableNode: ClickableNode, addToFavoritesHandler: KrScriptActionHandler.AddToFavoritesHandler) {
194+
val page = clickableNode as? PageNode
195+
?: if (clickableNode is RunnableNode) {
196+
pageNode
197+
} else {
198+
return
199+
}
200+
201+
val intent = Intent()
202+
203+
intent.component = ComponentName(this@MainActivity.applicationContext, ActionPage::class.java)
204+
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
205+
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
206+
207+
if (clickableNode is RunnableNode) {
208+
intent.putExtra("autoRunItemId", clickableNode.key)
209+
}
210+
intent.putExtra("page", page)
211+
212+
addToFavoritesHandler.onAddToFavorites(clickableNode, intent)
213+
}
214+
215+
override fun onSubPageClick(pageNode: PageNode) {
216+
_openPage(pageNode)
217+
}
218+
219+
override fun openFileChooser(fileSelectedInterface: ParamsFileChooserRender.FileSelectedInterface): Boolean {
220+
return chooseFilePath(fileSelectedInterface)
221+
}
222+
}
223+
}
224+
225+
private var fileSelectedInterface: ParamsFileChooserRender.FileSelectedInterface? = null
226+
private val ACTION_FILE_PATH_CHOOSER = 65400
227+
private val ACTION_FILE_PATH_CHOOSER_INNER = 65300
228+
229+
private fun chooseFilePath(extension: String) {
230+
try {
231+
val intent = Intent(this, ActivityFileSelector::class.java)
232+
intent.putExtra("extension", extension)
233+
startActivityForResult(intent, ACTION_FILE_PATH_CHOOSER_INNER)
234+
} catch (ex: java.lang.Exception) {
235+
Toast.makeText(this, "Failed to launch the built-in file selector!", Toast.LENGTH_SHORT).show()
236+
}
237+
}
238+
239+
private fun chooseFilePath(fileSelectedInterface: ParamsFileChooserRender.FileSelectedInterface): Boolean {
240+
return try {
241+
val suffix = fileSelectedInterface.suffix()
242+
if (suffix != null && suffix.isNotEmpty()) {
243+
chooseFilePath(suffix)
244+
} else {
245+
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
246+
addCategory(Intent.CATEGORY_OPENABLE)
247+
val mimeType = fileSelectedInterface.mimeType() ?: "*/*"
248+
type = mimeType
249+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
250+
putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(mimeType))
251+
}
252+
}
253+
startActivityForResult(intent, ACTION_FILE_PATH_CHOOSER)
254+
}
255+
this.fileSelectedInterface = fileSelectedInterface
256+
true
257+
} catch (e: Exception) {
258+
Toast.makeText(this, "Unable to open picker file: ${e.message}", Toast.LENGTH_SHORT).show()
259+
false
260+
}
261+
}
262+
263+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
264+
if (requestCode == ACTION_FILE_PATH_CHOOSER) {
265+
val result = if (data == null || resultCode != RESULT_OK) null else data.data
266+
if (fileSelectedInterface != null) {
267+
if (result != null) {
268+
val absPath = getPath(result)
269+
fileSelectedInterface?.onFileSelected(absPath)
270+
} else {
271+
fileSelectedInterface?.onFileSelected(null)
272+
}
273+
}
274+
this.fileSelectedInterface = null
275+
} else if (requestCode == ACTION_FILE_PATH_CHOOSER_INNER) {
276+
val absPath = if (data == null || resultCode != RESULT_OK) null else data.getStringExtra("file")
277+
fileSelectedInterface?.onFileSelected(absPath)
278+
this.fileSelectedInterface = null
279+
}
280+
super.onActivityResult(requestCode, resultCode, data)
281+
}
282+
283+
private fun getPath(uri: Uri): String? {
284+
return try {
285+
FilePathResolver().getPath(this, uri)
286+
} catch (ex: Exception) {
287+
null
288+
}
289+
}
290+
291+
fun _openPage(pageNode: PageNode) {
292+
OpenPageHelper(this).openPage(pageNode)
293+
}
294+
295+
private fun getDensity(): Int {
296+
val dm = DisplayMetrics()
297+
windowManager.defaultDisplay.getMetrics(dm)
298+
return dm.densityDpi
299+
}
300+
301+
override fun onCreateOptionsMenu(menu: Menu): Boolean {
302+
menuInflater.inflate(R.menu.main, menu)
303+
menu.findItem(R.id.action_graph).isVisible = (binding.mainTabhostCpu.isVisible)
304+
return true
305+
}
306+
307+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
308+
when (item.itemId) {
309+
R.id.option_menu_info -> {
310+
val layoutInflater = LayoutInflater.from(this)
311+
val layout = layoutInflater.inflate(R.layout.dialog_about, null)
312+
val themeConfig = ThemeConfig(this)
313+
314+
val transparentUi = layout.findViewById<CompoundButton>(R.id.transparent_ui)
315+
transparentUi.setOnClickListener {
316+
val isChecked = (it as CompoundButton).isChecked
317+
themeConfig.setAllowTransparentUI(isChecked)
318+
}
319+
transparentUi.isChecked = themeConfig.getAllowTransparentUI()
320+
321+
val notificationUi = layout.findViewById<CompoundButton>(R.id.notification_ui)
322+
notificationUi.setOnClickListener {
323+
val isChecked = (it as CompoundButton).isChecked
324+
themeConfig.setAllowNotificationUI(isChecked)
325+
}
326+
notificationUi.isChecked = themeConfig.getAllowNotificationUI()
327+
328+
DialogHelper.customDialog(this, layout)
329+
}
330+
R.id.option_menu_reboot -> {
331+
DialogPower(this).showPowerMenu()
332+
}
333+
R.id.action_graph -> {
334+
if (FloatMonitor.isShown == true) {
335+
FloatMonitor(this).hidePopupWindow()
336+
return false
337+
}
338+
if (Settings.canDrawOverlays(this)) {
339+
FloatMonitor(this).showPopupWindow()
340+
Toast.makeText(this, getString(R.string.float_monitor_tips), Toast.LENGTH_LONG).show()
341+
} else {
342+
val intent = Intent()
343+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
344+
intent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"
345+
intent.data = Uri.fromParts("package", this.packageName, null)
346+
347+
Toast.makeText(applicationContext, getString(R.string.permission_float), Toast.LENGTH_LONG).show()
348+
349+
try {
350+
startActivity(intent)
351+
} catch (_: Exception) {
352+
}
353+
}
354+
}
355+
}
356+
return super.onOptionsItemSelected(item)
357+
}
358+
}

0 commit comments

Comments
 (0)