Added module home page

This commit is contained in:
2022-05-14 18:44:24 +08:00
parent 9607eaba73
commit 775c28a7aa
30 changed files with 844 additions and 6 deletions

View File

@@ -52,7 +52,7 @@ Added more features to app's crash dialog, fixed custom rom deleted dialog, the
此项目依然在开发中,现在未解决的问题和包含的问题如下
- 排除列表和模块主界面功能正在开发
- 排除列表以及更多功能正在开发
- 后台进程可能依然会弹出崩溃对话框且开发者选项里的设置无效,还在排查

View File

@@ -61,6 +61,7 @@ dependencies {
compileOnly 'de.robv.android.xposed:api:82'
implementation 'com.highcapable.yukihookapi:api:1.0.87'
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.87'
implementation "com.github.topjohnwu.libsu:core:3.1.2"
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.0'
implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.0'
implementation 'androidx.core:core-ktx:1.7.0'

View File

@@ -28,6 +28,32 @@
android:name="xposedscope"
android:resource="@array/module_scope" />
<activity
android:name=".ui.activity.main.MainActivity"
android:exported="true"
android:screenOrientation="behind">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="de.robv.android.xposed.category.MODULE_SETTINGS" />
</intent-filter>
</activity>
<activity-alias
android:name=".Home"
android:exported="true"
android:label="@string/app_name"
android:screenOrientation="behind"
android:targetActivity=".ui.activity.main.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity
android:name=".ui.activity.errors.AppErrorsDetailActivity"
android:exported="true"

View File

@@ -19,8 +19,11 @@
*
* This file is Created by fankes on 2022/5/12.
*/
@file:Suppress("MemberVisibilityCanBePrivate")
package com.fankes.apperrorstracking.const
import com.fankes.apperrorstracking.BuildConfig
import com.fankes.apperrorstracking.bean.AppErrorsInfoBean
/**
@@ -28,6 +31,18 @@ import com.fankes.apperrorstracking.bean.AppErrorsInfoBean
*/
object Const {
/** 当前模块的包名 */
const val MODULE_PACKAGE_NAME = BuildConfig.APPLICATION_ID
/** 当前模块的版本名称 */
const val MODULE_VERSION_NAME = BuildConfig.VERSION_NAME
/** 当前模块的版本号 */
const val MODULE_VERSION_CODE = BuildConfig.VERSION_CODE
/** 当前模块的版本校验 */
const val MODULE_VERSION_VERIFY = "${MODULE_VERSION_NAME}_${MODULE_VERSION_CODE}_202205141842"
/** [AppErrorsInfoBean] 传值 */
const val EXTRA_APP_ERRORS_INFO = "app_errors_info_extra"
@@ -40,6 +55,9 @@ object Const {
/** 模块与宿主交互数据 */
const val KEY_MODULE_HOST_FETCH = "module_host_data_fetch_key"
/** 校验模块宿主版本一致性 */
const val TYPE_MODULE_VERSION_VERIFY = "module_version_verify_type"
/** 获取 [AppErrorsInfoBean] 数据 */
const val TYPE_APP_ERRORS_DATA_GET = "app_errors_data_get_type"
@@ -49,6 +67,9 @@ object Const {
/** 删除指定 [AppErrorsInfoBean] 数据 */
const val TYPE_APP_ERRORS_DATA_REMOVE = "app_errors_data_remove_type"
/** 当前模块的版本校验标签 */
const val TAG_MODULE_VERSION_VERIFY = "module_version_verify_tag"
/** 获取到的 [AppErrorsInfoBean] 数据内容 */
const val TAG_APP_ERRORS_DATA_GET_CONTENT = "app_errors_data_get_content_tag"

View File

@@ -0,0 +1,29 @@
/*
* AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/KitsunePie/AppErrorsTracking
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/5/14.
*/
package com.fankes.apperrorstracking.data
import com.highcapable.yukihookapi.hook.xposed.prefs.data.PrefsData
object DataConst {
val ENABLE_HIDE_ICON = PrefsData("_hide_icon", false)
}

View File

@@ -119,6 +119,10 @@ object FrameworkHooker : YukiBaseHooker() {
if (it.isNotBlank()) context?.sendBroadcast(Intent().apply {
action = Const.ACTION_MODULE_HANDLER_RECEIVER
when (it) {
Const.TYPE_MODULE_VERSION_VERIFY -> {
putExtra(Const.TAG_MODULE_VERSION_VERIFY, Const.MODULE_VERSION_VERIFY)
putExtra(Const.KEY_MODULE_HOST_FETCH, Const.TYPE_MODULE_VERSION_VERIFY)
}
Const.TYPE_APP_ERRORS_DATA_GET -> {
putExtra(Const.TAG_APP_ERRORS_DATA_GET_CONTENT, appErrorsRecords)
putExtra(Const.KEY_MODULE_HOST_FETCH, Const.TYPE_APP_ERRORS_DATA_GET)

View File

@@ -250,4 +250,52 @@ object LocaleString {
/** @string Automatic generated */
fun dontScreenshotTip(vararg objArrs: Any) = R.string.dont_screenshot_tip.bind(*objArrs)
/** @string Automatic generated */
val moduleVersion get() = moduleVersion()
/** @string Automatic generated */
fun moduleVersion(vararg objArrs: Any) = R.string.module_version.bind(*objArrs)
/** @string Automatic generated */
val systemVersion get() = systemVersion()
/** @string Automatic generated */
fun systemVersion(vararg objArrs: Any) = R.string.system_version.bind(*objArrs)
/** @string Automatic generated */
val areYouSureRestartSystem get() = areYouSureRestartSystem()
/** @string Automatic generated */
fun areYouSureRestartSystem(vararg objArrs: Any) = R.string.are_your_sure_restart_system.bind(*objArrs)
/** @string Automatic generated */
val fastRestart get() = fastRestart()
/** @string Automatic generated */
fun fastRestart(vararg objArrs: Any) = R.string.fast_restart.bind(*objArrs)
/** @string Automatic generated */
val accessRootFail get() = accessRootFail()
/** @string Automatic generated */
fun accessRootFail(vararg objArrs: Any) = R.string.access_root_fail.bind(*objArrs)
/** @string Automatic generated */
val moduleNotActivated get() = moduleNotActivated()
/** @string Automatic generated */
fun moduleNotActivated(vararg objArrs: Any) = R.string.module_not_activated.bind(*objArrs)
/** @string Automatic generated */
val moduleIsActivated get() = moduleIsActivated()
/** @string Automatic generated */
fun moduleIsActivated(vararg objArrs: Any) = R.string.module_is_activated.bind(*objArrs)
/** @string Automatic generated */
val moduleNotFullyActivated get() = moduleNotFullyActivated()
/** @string Automatic generated */
fun moduleNotFullyActivated(vararg objArrs: Any) = R.string.module_not_fully_activated.bind(*objArrs)
}

View File

@@ -0,0 +1,102 @@
/*
* AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/KitsunePie/AppErrorsTracking
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/5/14.
*/
@file:Suppress("SetTextI18n")
package com.fankes.apperrorstracking.ui.activity.main
import android.content.ComponentName
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.view.isVisible
import com.fankes.apperrorstracking.R
import com.fankes.apperrorstracking.const.Const
import com.fankes.apperrorstracking.data.DataConst
import com.fankes.apperrorstracking.databinding.ActivityMainBinding
import com.fankes.apperrorstracking.locale.LocaleString
import com.fankes.apperrorstracking.ui.activity.base.BaseActivity
import com.fankes.apperrorstracking.utils.factory.openBrowser
import com.fankes.apperrorstracking.utils.tool.FrameworkTool
import com.highcapable.yukihookapi.hook.factory.isXposedModuleActive
import com.highcapable.yukihookapi.hook.factory.modulePrefs
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
class MainActivity : BaseActivity<ActivityMainBinding>() {
/** 模块是否有效 */
private var isModuleValied = false
override fun onCreate() {
binding.mainTextVersion.text = LocaleString.moduleVersion(Const.MODULE_VERSION_NAME)
binding.mainTextSystemVersion.text =
LocaleString.systemVersion("${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT}) ${Build.DISPLAY}")
binding.hideIconInLauncherSwitch.isChecked = modulePrefs.get(DataConst.ENABLE_HIDE_ICON)
binding.hideIconInLauncherSwitch.setOnCheckedChangeListener { btn, b ->
if (btn.isPressed.not()) return@setOnCheckedChangeListener
modulePrefs.put(DataConst.ENABLE_HIDE_ICON, b)
packageManager.setComponentEnabledSetting(
ComponentName(packageName, "${Const.MODULE_PACKAGE_NAME}.Home"),
if (b) PackageManager.COMPONENT_ENABLED_STATE_DISABLED else PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP
)
}
/** 重启按钮点击事件 */
binding.titleRestartIcon.setOnClickListener { FrameworkTool.restartSystem(context = this) }
/** 项目地址按钮点击事件 */
binding.titleGithubIcon.setOnClickListener { openBrowser(url = "https://github.com/KitsunePie/AppErrorsTracking") }
}
/** 刷新模块状态 */
private fun refreshModuleStatus() {
binding.mainLinStatus.setBackgroundResource(
when {
isXposedModuleActive && isModuleValied.not() -> R.drawable.bg_yellow_round
isXposedModuleActive -> R.drawable.bg_green_round
else -> R.drawable.bg_dark_round
}
)
binding.mainImgStatus.setImageResource(
when {
isXposedModuleActive -> R.mipmap.ic_success
else -> R.mipmap.ic_warn
}
)
binding.mainTextStatus.text =
when {
isXposedModuleActive && isModuleValied.not() -> LocaleString.moduleNotFullyActivated
isXposedModuleActive -> LocaleString.moduleIsActivated
else -> LocaleString.moduleNotActivated
}
binding.mainTextApiWay.isVisible = isXposedModuleActive
binding.mainTextApiWay.text = "Activated by ${YukiHookModuleStatus.executorName} API ${YukiHookModuleStatus.executorVersion}"
}
override fun onResume() {
super.onResume()
/** 刷新模块状态 */
refreshModuleStatus()
/** 发送广播检查模块激活状态 */
FrameworkTool.checkingActivated(context = this) { isValied ->
isModuleValied = isValied
refreshModuleStatus()
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer.
* Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com)
* https://github.com/KitsunePie/AppErrorsTracking
*
* This software is non-free but opensource software: you can redistribute it
* and/or modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* and eula along with this software. If not, see
* <https://www.gnu.org/licenses/>
*
* This file is Created by fankes on 2022/5/14.
*/
@file:Suppress("SameParameterValue")
package com.fankes.apperrorstracking.ui.view
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
import android.text.TextUtils
import android.util.AttributeSet
import androidx.appcompat.widget.SwitchCompat
import com.fankes.apperrorstracking.utils.drawable.drawabletoolbox.DrawableBuilder
import com.fankes.apperrorstracking.utils.factory.dp
import com.fankes.apperrorstracking.utils.factory.isSystemInDarkMode
class MaterialSwitch(context: Context, attrs: AttributeSet?) : SwitchCompat(context, attrs) {
private fun toColors(selected: Int, pressed: Int, normal: Int): ColorStateList {
val colors = intArrayOf(selected, pressed, normal)
val states = arrayOfNulls<IntArray>(3)
states[0] = intArrayOf(android.R.attr.state_checked)
states[1] = intArrayOf(android.R.attr.state_pressed)
states[2] = intArrayOf()
return ColorStateList(states, colors)
}
private val thumbColor get() = if (context.isSystemInDarkMode) 0xFF7C7C7C else 0xFFCCCCCC
init {
trackDrawable = DrawableBuilder()
.rectangle()
.rounded()
.solidColor(0xFF656565.toInt())
.height(20.dp(context))
.cornerRadius(15.dp(context))
.build()
thumbDrawable = DrawableBuilder()
.rectangle()
.rounded()
.solidColor(Color.WHITE)
.size(20.dp(context), 20.dp(context))
.cornerRadius(20.dp(context))
.strokeWidth(8.dp(context))
.strokeColor(Color.TRANSPARENT)
.build()
trackTintList = toColors(
0xFF656565.toInt(),
thumbColor.toInt(),
thumbColor.toInt()
)
isSingleLine = true
ellipsize = TextUtils.TruncateAt.END
}
}

View File

@@ -28,16 +28,19 @@ import android.app.Service
import android.content.*
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.provider.Settings
import android.widget.Toast
import androidx.core.content.res.ResourcesCompat
import com.fankes.apperrorstracking.BuildConfig
import com.fankes.apperrorstracking.R
import com.fankes.apperrorstracking.const.Const
import com.fankes.apperrorstracking.locale.LocaleString
import com.google.android.material.snackbar.Snackbar
import com.highcapable.yukihookapi.hook.factory.field
import com.highcapable.yukihookapi.hook.type.android.ApplicationInfoClass
import com.topjohnwu.superuser.Shell
/**
* 系统深色模式是否开启
@@ -114,6 +117,19 @@ fun Context.appIcon(packageName: String) =
*/
fun Context.toast(msg: String) = Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
/**
* 弹出 [Snackbar]
* @param msg 提示内容
* @param actionText 按钮文本 - 不写默认取消按钮
* @param it 按钮事件回调
*/
fun Context.snake(msg: String, actionText: String = "", it: () -> Unit = {}) =
Snackbar.make((this as Activity).findViewById(android.R.id.content), msg, Snackbar.LENGTH_LONG).apply {
if (actionText.isBlank()) return@apply
setActionTextColor(if (isSystemInDarkMode) Color.BLACK else Color.WHITE)
setAction(actionText) { it() }
}.show()
/**
* 跳转到指定页面
*
@@ -125,7 +141,7 @@ inline fun <reified T : Activity> Context.navigate(isOutSide: Boolean = false, c
startActivity((if (isOutSide) Intent() else Intent(if (this is Service) applicationContext else this, T::class.java)).apply {
flags = if (this@navigate !is Activity) Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
else Intent.FLAG_ACTIVITY_NEW_TASK
if (isOutSide) component = ComponentName(BuildConfig.APPLICATION_ID, T::class.java.name)
if (isOutSide) component = ComponentName(Const.MODULE_PACKAGE_NAME, T::class.java.name)
callback(this)
})
}.onFailure { toast(msg = "Start ${T::class.java.name} failed") }
@@ -155,6 +171,24 @@ fun Context.openSelfSetting(packageName: String = this.packageName) = runCatchin
})
}.onFailure { toast(msg = "Cannot open '$packageName'") }
/**
* 启动系统浏览器
* @param url 网址
* @param packageName 指定包名 - 可不填
*/
fun Context.openBrowser(url: String, packageName: String = "") = runCatching {
startActivity(Intent().apply {
if (packageName.isNotBlank()) setPackage(packageName)
action = Intent.ACTION_VIEW
data = Uri.parse(url)
/** 防止顶栈一样重叠在自己的 APP 中 */
flags = Intent.FLAG_ACTIVITY_NEW_TASK
})
}.onFailure {
if (packageName.isNotBlank()) snake(msg = "Cannot start '$packageName'")
else snake(msg = "Start system browser failed")
}
/**
* 当前 APP 是否可被启动
* @param packageName 包名
@@ -170,4 +204,22 @@ fun Context.openApp(packageName: String = this.packageName) = runCatching {
startActivity(packageManager.getLaunchIntentForPackage(packageName)?.apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
})
}.onFailure { toast(msg = "Cannot start '$packageName'") }
}.onFailure { toast(msg = "Cannot start '$packageName'") }
/**
* 是否有 Root 权限
* @return [Boolean]
*/
val isRootAccess get() = runCatching { Shell.rootAccess() }.getOrNull() ?: false
/**
* 执行命令
* @param cmd 命令
* @param isSu 是否使用 Root 权限执行 - 默认:是
* @return [String] 执行结果
*/
fun execShell(cmd: String, isSu: Boolean = true) = runCatching {
(if (isSu) Shell.su(cmd) else Shell.sh(cmd)).exec().out.let {
if (it.isNotEmpty()) it[0].trim() else ""
}
}.getOrNull() ?: ""

View File

@@ -29,6 +29,11 @@ import android.content.Intent
import android.content.IntentFilter
import com.fankes.apperrorstracking.bean.AppErrorsInfoBean
import com.fankes.apperrorstracking.const.Const
import com.fankes.apperrorstracking.locale.LocaleString
import com.fankes.apperrorstracking.utils.factory.execShell
import com.fankes.apperrorstracking.utils.factory.isRootAccess
import com.fankes.apperrorstracking.utils.factory.showDialog
import com.fankes.apperrorstracking.utils.factory.snake
import com.highcapable.yukihookapi.hook.log.loggerE
import java.io.Serializable
@@ -37,6 +42,9 @@ import java.io.Serializable
*/
object FrameworkTool {
/** 回调模块激活状态 */
private var onModuleActiveStatusCallback: ((Boolean) -> Unit)? = null
/** 回调获取的 APP 异常信息 */
private var onAppErrorsInfoDataCallback: ((ArrayList<AppErrorsInfoBean>) -> Unit)? = null
@@ -54,6 +62,8 @@ object FrameworkTool {
runCatching {
intent.getStringExtra(Const.KEY_MODULE_HOST_FETCH)?.also {
if (it.isNotBlank()) when (it) {
Const.TYPE_MODULE_VERSION_VERIFY ->
onModuleActiveStatusCallback?.invoke(intent.getStringExtra(Const.TAG_MODULE_VERSION_VERIFY) == Const.MODULE_VERSION_VERIFY)
Const.TYPE_APP_ERRORS_DATA_GET -> runCatching {
onAppErrorsInfoDataCallback?.invoke(
intent.getSerializableExtra(Const.TAG_APP_ERRORS_DATA_GET_CONTENT) as ArrayList<AppErrorsInfoBean>
@@ -69,6 +79,27 @@ object FrameworkTool {
}
}
/**
* 重启系统
* @param context 实例
*/
fun restartSystem(context: Context) =
context.showDialog {
title = LocaleString.notice
msg = LocaleString.areYouSureRestartSystem
confirmButton {
if (isRootAccess)
execShell(cmd = "reboot")
else context.snake(LocaleString.accessRootFail)
}
neutralButton(LocaleString.fastRestart) {
if (isRootAccess)
execShell(cmd = "killall zygote")
else context.snake(LocaleString.accessRootFail)
}
cancelButton()
}
/**
* 发送广播
* @param context 实例
@@ -92,6 +123,16 @@ object FrameworkTool {
})
}
/**
* 检查模块是否激活
* @param context 实例
* @param it 成功后回调 - ([Boolean] 是否激活)
*/
fun checkingActivated(context: Context, it: (Boolean) -> Unit) {
onModuleActiveStatusCallback = it
pushReceiver(context, Const.TYPE_MODULE_VERSION_VERIFY)
}
/**
* 获取 APP 异常信息数组
* @param context 实例

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#66A6A6A6" />
<corners android:radius="15dp" />
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#661B1B1B" />
<corners android:radius="15dp" />
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#26A69A" />
<corners android:radius="15dp" />
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF7043" />
<corners android:radius="15dp" />
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF9800" />
<corners android:radius="15dp" />
</shape>

View File

@@ -0,0 +1,308 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorThemeBackground"
android:orientation="vertical"
tools:context=".ui.activity.main.MainActivity"
tools:ignore="UseCompoundDrawables,ContentDescription,SmallSp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="0dp"
android:gravity="center|start"
android:paddingLeft="15dp"
android:paddingTop="13dp"
android:paddingRight="15dp"
android:paddingBottom="5dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:text="@string/app_name"
android:textColor="@color/colorTextGray"
android:textSize="25sp"
android:textStyle="bold" />
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/title_restart_icon"
style="?android:attr/selectableItemBackgroundBorderless"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_marginEnd="15dp"
android:alpha="0.85"
android:src="@mipmap/ic_restart"
android:tint="@color/colorTextGray"
android:tooltipText="@string/restart_system" />
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/title_github_icon"
style="?android:attr/selectableItemBackgroundBorderless"
android:layout_width="27dp"
android:layout_height="27dp"
android:layout_marginEnd="5dp"
android:alpha="0.85"
android:src="@mipmap/ic_github"
android:tint="@color/colorTextGray"
android:tooltipText="@string/project_address" />
</LinearLayout>
<LinearLayout
android:id="@+id/main_lin_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="5dp"
android:background="@drawable/bg_dark_round"
android:elevation="0dp"
android:gravity="center">
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/main_img_status"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginStart="25dp"
android:layout_marginEnd="5dp"
android:src="@mipmap/ic_warn"
android:tint="@color/white" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="20dp"
android:paddingTop="10dp"
android:paddingRight="20dp"
android:paddingBottom="10dp">
<TextView
android:id="@+id/main_text_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/module_not_activated"
android:textColor="@color/white"
android:textSize="18sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:id="@+id/main_text_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.8"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/module_version"
android:textColor="@color/white"
android:textSize="13sp" />
<TextView
android:id="@+id/main_text_release_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:background="@drawable/bg_orange_round"
android:ellipsize="end"
android:paddingLeft="5dp"
android:paddingTop="2dp"
android:paddingRight="5dp"
android:paddingBottom="2dp"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="11sp"
android:visibility="gone" />
</LinearLayout>
<TextView
android:id="@+id/main_text_system_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.8"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/system_version"
android:textColor="@color/white"
android:textSize="13sp" />
<TextView
android:id="@+id/main_text_api_way"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:alpha="0.6"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="11sp"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:fadingEdgeLength="10dp"
android:fillViewport="true"
android:requiresFadingEdge="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
android:background="@drawable/bg_permotion_round"
android:elevation="0dp"
android:gravity="center"
android:orientation="horizontal"
android:padding="15dp">
<androidx.constraintlayout.utils.widget.ImageFilterView
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginEnd="10dp"
android:alpha="0.85"
android:src="@mipmap/ic_about"
android:tint="@color/colorTextDark" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.6"
android:lineSpacingExtra="5dp"
android:text="@string/after_some_settings_need_restart"
android:textColor="@color/colorTextGray"
android:textSize="11sp" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:layout_marginRight="15dp"
android:background="@drawable/bg_permotion_round"
android:gravity="center"
android:padding="50dp"
android:text="@string/todo_items"
android:textColor="@color/colorTextDark"
android:textSize="15sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:layout_marginRight="15dp"
android:background="@drawable/bg_permotion_round"
android:elevation="0dp"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingTop="15dp"
android:paddingRight="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|start">
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginEnd="10dp"
android:src="@mipmap/ic_home" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="0.85"
android:singleLine="true"
android:text="@string/display_settings"
android:textColor="@color/colorTextGray"
android:textSize="12sp" />
</LinearLayout>
<com.fankes.apperrorstracking.ui.view.MaterialSwitch
android:id="@+id/hide_icon_in_launcher_switch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hide_app_icon_on_desktop"
android:textAllCaps="false"
android:textColor="@color/colorTextGray"
android:textSize="15sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:alpha="0.6"
android:lineSpacingExtra="6dp"
android:text="@string/hide_app_icon_on_desktop_tip"
android:textColor="@color/colorTextDark"
android:textSize="12sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:alpha="0.6"
android:lineSpacingExtra="6dp"
android:text="@string/hide_app_icon_on_desktop_notice"
android:textColor="#FF5722"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="10dp"
android:background="@drawable/bg_permotion_round"
android:gravity="center|start"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginEnd="10dp"
android:src="@mipmap/ic_yukihookapi" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="web"
android:ellipsize="end"
android:lineSpacingExtra="6dp"
android:maxLines="2"
android:text="@string/about_module"
android:textColor="@color/colorTextGray"
android:textSize="11sp" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -36,9 +36,9 @@
<string name="cancel">キャンセル</string>
<string name="more">モア</string>
<string name="notice">ヒント</string>
<string name="are_you_sure_clear_errors">すべてのエラーレコードをクリアしてもよろしいですか</string>
<string name="are_you_sure_clear_errors">すべてのエラーレコードをクリアしてもよろしいですか</string>
<string name="all_errors_clear_success">すべてのアラーレコードがクリアされました</string>
<string name="are_you_sure_export_all_errors">すべてのログファイルをエクスポートしてもよろしいですか 梱包プロセスには時間がかかる場合があります。</string>
<string name="are_you_sure_export_all_errors">すべてのログファイルをエクスポートしてもよろしいですか梱包プロセスには時間がかかる場合があります。</string>
<string name="view_detail">詳細を見る</string>
<string name="export_all_errors_success">すべてのエラーレコードがエクスポートされました</string>
<string name="export_all_errors_fail">すべてのエラーレコードのエクスポートに失敗しました</string>
@@ -48,4 +48,21 @@
<string name="got_it">分かります</string>
<string name="dont_screenshot">スクリーンショットを撮らないでください</string>
<string name="dont_screenshot_tip">エラーログのスクリーンショットを撮ることはお勧めできません。このインターフェイスの右上隅にあるボタンをクリックして、ログの内容を抽出またはコピーする必要があります。</string>
<string name="restart_system">リスタートシステム</string>
<string name="project_address">プロジェクトアドレス</string>
<string name="module_not_activated">モジュールが無効化でした</string>
<string name="module_version">モジュールバージョン: %1$s</string>
<string name="system_version">システムバージョン: %1$s</string>
<string name="module_is_activated">モジュールが有効化でした</string>
<string name="after_some_settings_need_restart">一部の設定を変更した後、リスタートシステムして有効にするには、右上隅をクリックする必要がある場合があります。</string>
<string name="display_settings">表示設定</string>
<string name="hide_app_icon_on_desktop">デスクトップ上のアプリアイコンを非表示</string>
<string name="hide_app_icon_on_desktop_tip">モジュールアイコンを非表示にすると、インターフェイスが閉じてデスクトップに表示されなくなります。モジュール設定は、EdXposedまたはLSPosedで検索して開くことができます。</string>
<string name="hide_app_icon_on_desktop_notice">LSPosedの「Force apps to show launcher icons」機能を必ずオフにしてください</string>
<string name="about_module">このモジュールは、YukiHookAPIを使用して構築できます。 \n詳細 https://github.com/fankes/YukiHookAPI</string>
<string name="module_not_fully_activated">モジュールが不完全に有効化でした</string>
<string name="are_your_sure_restart_system">リスタートシステムしてもよろしいですか</string>
<string name="fast_restart">高速リスタート</string>
<string name="access_root_fail">ルート権限を取得できませんでした</string>
<string name="todo_items">より多くの機能が開発中です</string>
</resources>

View File

@@ -48,4 +48,21 @@
<string name="got_it">我知道了</string>
<string name="dont_screenshot">请不要截屏</string>
<string name="dont_screenshot_tip">在错误日志中截屏是不明智的做法,你应当点击此界面右上角的按钮提取或复制日志内容。</string>
<string name="restart_system">重启系统</string>
<string name="project_address">项目地址</string>
<string name="module_not_activated">模块未激活</string>
<string name="module_version">模块版本:%1$s</string>
<string name="system_version">系统版本:%1$s</string>
<string name="module_is_activated">模块已激活</string>
<string name="after_some_settings_need_restart">部分设置修改后可能需要点击右上角重启系统才能生效。</string>
<string name="display_settings">显示设置</string>
<string name="hide_app_icon_on_desktop">在桌面隐藏模块图标</string>
<string name="hide_app_icon_on_desktop_tip">隐藏模块图标后界面可能会被关闭,将不会再在桌面显示,你可以在 EdXposed、LSPosed 中找到模块设置并打开。</string>
<string name="hide_app_icon_on_desktop_notice">注意:请务必在 LSPosed 中关闭“强制显示桌面图标”功能</string>
<string name="about_module">此模块使用 YukiHookAPI 构建。\n了解更多 https://github.com/fankes/YukiHookAPI</string>
<string name="module_not_fully_activated">模块未完全激活,请重启系统</string>
<string name="are_your_sure_restart_system">你确定要重启系统吗?</string>
<string name="fast_restart">快速重启</string>
<string name="access_root_fail">获取 Root 权限失败</string>
<string name="todo_items">更多功能正在开发</string>
</resources>

View File

@@ -48,4 +48,21 @@
<string name="got_it">我懂了</string>
<string name="dont_screenshot">請不要捕獲熒屏</string>
<string name="dont_screenshot_tip">在錯誤日誌中捕獲熒屏是不明理的做法,你應當點擊此界面右上角的按鈕提取或複制日誌內容。</string>
<string name="restart_system">重新開機</string>
<string name="project_address">項目地址</string>
<string name="module_not_activated">模組未激活</string>
<string name="module_version">模組版本:%1$s</string>
<string name="system_version">系統版本:%1$s</string>
<string name="module_is_activated">模組已激活</string>
<string name="after_some_settings_need_restart">部分設置修改後可能需要點擊右上角重啟系統才能生效。</string>
<string name="display_settings">顯示設置</string>
<string name="hide_app_icon_on_desktop">在桌面隱藏模組圖標</string>
<string name="hide_app_icon_on_desktop_tip">隱藏模組圖標後界面可能會被關閉,將不會再在桌面顯示,你可以在 EdXposed、LSPosed 中找到模組設置並打開。</string>
<string name="hide_app_icon_on_desktop_notice">注意:請務必在 LSPosed 中關閉“強制顯示桌面圖標”功能</string>
<string name="about_module">此模組使用 YukiHookAPI 構建。 \n了解更多 https://github.com/fankes/YukiHookAPI</string>
<string name="module_not_fully_activated">模組未完全激活,請重新開機</string>
<string name="are_your_sure_restart_system">你確定要重新開機嗎?</string>
<string name="fast_restart">急速重開</string>
<string name="access_root_fail">取得 Root 权利失败</string>
<string name="todo_items">更多機能正在開發</string>
</resources>

View File

@@ -48,4 +48,21 @@
<string name="got_it">我懂了</string>
<string name="dont_screenshot">請不要捕獲熒屏</string>
<string name="dont_screenshot_tip">在錯誤日誌中捕獲熒屏是不明理的做法,你應當點擊此界面右上角的按鈕提取或複制日誌內容。</string>
<string name="restart_system">重新開機</string>
<string name="project_address">項目地址</string>
<string name="module_not_activated">模組未激活</string>
<string name="module_version">模組版本:%1$s</string>
<string name="system_version">系統版本:%1$s</string>
<string name="module_is_activated">模組已激活</string>
<string name="after_some_settings_need_restart">部分設置修改後可能需要點擊右上角重啟系統才能生效。</string>
<string name="display_settings">顯示設置</string>
<string name="hide_app_icon_on_desktop">在桌面隱藏模組圖標</string>
<string name="hide_app_icon_on_desktop_tip">隱藏模組圖標後界面可能會被關閉,將不會再在桌面顯示,你可以在 EdXposed、LSPosed 中找到模組設置並打開。</string>
<string name="hide_app_icon_on_desktop_notice">注意:請務必在 LSPosed 中關閉“強制顯示桌面圖標”功能</string>
<string name="about_module">此模組使用 YukiHookAPI 構建。 \n了解更多 https://github.com/fankes/YukiHookAPI</string>
<string name="module_not_fully_activated">模組未完全激活,請重新開機</string>
<string name="are_your_sure_restart_system">你確定要重新開機嗎?</string>
<string name="fast_restart">急速重開</string>
<string name="access_root_fail">取得 Root 权利失败</string>
<string name="todo_items">更多機能正在開發</string>
</resources>

View File

@@ -48,4 +48,21 @@
<string name="got_it">我懂了</string>
<string name="dont_screenshot">請不要捕獲熒屏</string>
<string name="dont_screenshot_tip">在錯誤日誌中捕獲熒屏是不明理的做法,你應當點擊此界面右上角的按鈕提取或複制日誌內容。</string>
<string name="restart_system">重新開機</string>
<string name="project_address">項目地址</string>
<string name="module_not_activated">模組未激活</string>
<string name="module_version">模組版本:%1$s</string>
<string name="system_version">系統版本:%1$s</string>
<string name="module_is_activated">模組已激活</string>
<string name="after_some_settings_need_restart">部分設置修改後可能需要點擊右上角重啟系統才能生效。</string>
<string name="display_settings">顯示設置</string>
<string name="hide_app_icon_on_desktop">在桌面隱藏模組圖標</string>
<string name="hide_app_icon_on_desktop_tip">隱藏模組圖標後界面可能會被關閉,將不會再在桌面顯示,你可以在 EdXposed、LSPosed 中找到模組設置並打開。</string>
<string name="hide_app_icon_on_desktop_notice">注意:請務必在 LSPosed 中關閉“強制顯示桌面圖標”功能</string>
<string name="about_module">此模組使用 YukiHookAPI 構建。 \n了解更多 https://github.com/fankes/YukiHookAPI</string>
<string name="module_not_fully_activated">模組未完全激活,請重新開機</string>
<string name="are_your_sure_restart_system">你確定要重新開機嗎?</string>
<string name="fast_restart">急速重開</string>
<string name="access_root_fail">取得 Root 权利失败</string>
<string name="todo_items">更多機能正在開發</string>
</resources>

View File

@@ -47,4 +47,21 @@
<string name="got_it">Got it</string>
<string name="dont_screenshot">Do not take screenshots</string>
<string name="dont_screenshot_tip">It is not advisable to take a screenshot of the error log, you should extract or copy the log content by clicking the button in the upper right corner of this interface.</string>
<string name="restart_system">Restart system</string>
<string name="project_address">Project address</string>
<string name="module_not_activated">Module not activated</string>
<string name="module_version">Module version: %1$s</string>
<string name="system_version">System version: %1$s</string>
<string name="module_is_activated">Module is activated</string>
<string name="after_some_settings_need_restart">After some settings are modified, you may need to click the upper right corner to restart the system to take effect.</string>
<string name="display_settings">Display settings</string>
<string name="hide_app_icon_on_desktop">Hide app icons on desktop</string>
<string name="hide_app_icon_on_desktop_tip">After hiding the app icon, the interface may be closed and will no longer be displayed on the desktop. You can find and open the module settings in EdXposed or LSPosed.</string>
<string name="hide_app_icon_on_desktop_notice">Note: Be sure to turn off the \"Force apps to show launcher icons\" feature in LSPosed</string>
<string name="about_module">This module is made by YukiHookAPI. \nLearn more https://github.com/fankes/YukiHookAPI</string>
<string name="module_not_fully_activated">Module not fully activated</string>
<string name="are_your_sure_restart_system">Are you sure you want to restart system?</string>
<string name="fast_restart">Fast restart</string>
<string name="access_root_fail">Access Root failed</string>
<string name="todo_items">More features are in development</string>
</resources>