mirror of
https://github.com/fankes/ColorOSNotifyIcon.git
synced 2025-09-08 19:44:10 +08:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
ea962e1520 | |||
3e2b8247c8 | |||
e529e75bc2 | |||
cd5f9806a3 | |||
4d7891f769 | |||
cd4b9794c4 | |||
efbd919482 | |||
|
e297dc0b96 | ||
|
42c817c90e | ||
fe31b79d4d |
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -8,6 +8,8 @@
|
|||||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.335" />
|
<entry key="app/src/main/res/layout/activity_main.xml" value="0.335" />
|
||||||
<entry key="app/src/main/res/layout/adapter_config.xml" value="0.4375" />
|
<entry key="app/src/main/res/layout/adapter_config.xml" value="0.4375" />
|
||||||
<entry key="app/src/main/res/layout/dia_icon_filter.xml" value="0.4375" />
|
<entry key="app/src/main/res/layout/dia_icon_filter.xml" value="0.4375" />
|
||||||
|
<entry key="app/src/main/res/layout/dia_source_from.xml" value="0.4375" />
|
||||||
|
<entry key="app/src/main/res/layout/dia_source_from_string.xml" value="0.4375" />
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<img src="https://github.com/fankes/ColorOSNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png" width = "100" height = "100"/>
|
<img src="https://github.com/fankes/ColorOSNotifyIcon/blob/master/app/src/main/ic_launcher-playstore.png" width = "100" height = "100"/>
|
||||||
<br/>
|
<br/>
|
||||||
@@ -12,7 +12,7 @@ Optimize notification icons for ColorOS and adapt to native notification icon sp
|
|||||||
# 开始使用
|
# 开始使用
|
||||||
|
|
||||||
点击下载最新版本
|
点击下载最新版本
|
||||||
<a href='https://github.com/fankes/ColorOSNotifyIcon/releases'></a>
|
<a href='https://github.com/fankes/ColorOSNotifyIcon/releases'></a>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
⚠️ 适配说明<br/>
|
⚠️ 适配说明<br/>
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ Optimize notification icons for ColorOS and adapt to native notification icon sp
|
|||||||
|
|
||||||
此项目是 `AndroidNotifyIconAdapt` 项目的一部分,详情请参考下方。<br/>
|
此项目是 `AndroidNotifyIconAdapt` 项目的一部分,详情请参考下方。<br/>
|
||||||
|
|
||||||
- [Android 通知图标规范适配](https://github.com/fankes/AndroidNotifyIconAdapt)
|
- [Android 通知图标规范适配计划](https://github.com/fankes/AndroidNotifyIconAdapt)
|
||||||
|
|
||||||
# 历史背景
|
# 历史背景
|
||||||
|
|
||||||
|
@@ -60,13 +60,12 @@ tasks.whenTaskAdded {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
compileOnly 'de.robv.android.xposed:api:82'
|
||||||
|
implementation 'com.highcapable.yukihookapi:api:1.0.4'
|
||||||
|
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.4'
|
||||||
|
implementation 'com.github.tiann:FreeReflection:3.1.0'
|
||||||
implementation "com.github.topjohnwu.libsu:core:3.1.2"
|
implementation "com.github.topjohnwu.libsu:core:3.1.2"
|
||||||
implementation 'androidx.annotation:annotation:1.3.0'
|
implementation 'androidx.annotation:annotation:1.3.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
|
|
||||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
|
|
||||||
compileOnly 'de.robv.android.xposed:api:82'
|
|
||||||
implementation 'com.highcapable.yukihookapi:api:1.0.3'
|
|
||||||
ksp 'com.highcapable.yukihookapi:ksp-xposed:1.0.3'
|
|
||||||
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.0'
|
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.0'
|
||||||
implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.0'
|
implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.0'
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
|
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
|
||||||
|
2
app/proguard-rules.pro
vendored
2
app/proguard-rules.pro
vendored
@@ -40,6 +40,8 @@
|
|||||||
-keep class android.support**
|
-keep class android.support**
|
||||||
-keep class androidx**
|
-keep class androidx**
|
||||||
|
|
||||||
|
-keep class me.weishu**{*;}
|
||||||
|
|
||||||
-keep public class * extends android.app.Activity
|
-keep public class * extends android.app.Activity
|
||||||
-keep public class * extends android.app.Application
|
-keep public class * extends android.app.Application
|
||||||
-keep public class * extends android.app.Service
|
-keep public class * extends android.app.Service
|
||||||
|
@@ -25,7 +25,9 @@
|
|||||||
package com.fankes.coloros.notify.application
|
package com.fankes.coloros.notify.application
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import me.weishu.reflection.Reflection
|
||||||
|
|
||||||
class CNNApplication : Application() {
|
class CNNApplication : Application() {
|
||||||
|
|
||||||
@@ -38,6 +40,12 @@ class CNNApplication : Application() {
|
|||||||
val appContext get() = context ?: error("App is death")
|
val appContext get() = context ?: error("App is death")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: Context?) {
|
||||||
|
super.attachBaseContext(base)
|
||||||
|
/** 解锁隐藏 API */
|
||||||
|
Reflection.unseal(base)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
/** 设置静态实例 */
|
/** 设置静态实例 */
|
||||||
|
@@ -47,4 +47,13 @@ data class IconDataBean(
|
|||||||
) : Serializable {
|
) : Serializable {
|
||||||
fun toEnabledName() = ("$appName$packageName").base64 + "_enable"
|
fun toEnabledName() = ("$appName$packageName").base64 + "_enable"
|
||||||
fun toEnabledAllName() = ("$appName$packageName").base64 + "_enable_all"
|
fun toEnabledAllName() = ("$appName$packageName").base64 + "_enable_all"
|
||||||
|
override fun toString() = "{\n" +
|
||||||
|
" \"appName\": \"$appName\",\n" +
|
||||||
|
" \"packageName\": \"$packageName\",\n" +
|
||||||
|
" \"iconBitmap\": \"${iconBitmap.base64}\",\n" +
|
||||||
|
" \"iconColor\": \"#${Integer.toHexString(iconColor)}\",\n" +
|
||||||
|
" \"contributorName\": \"$contributorName\",\n" +
|
||||||
|
" \"isEnabled\": $isEnabled,\n" +
|
||||||
|
" \"isEnabledAll\": $isEnabledAll\n" +
|
||||||
|
" }"
|
||||||
}
|
}
|
@@ -33,5 +33,12 @@ object HookConst {
|
|||||||
const val REMOVE_CHANGECP_NOTIFY = "_remove_charge_complete_notify"
|
const val REMOVE_CHANGECP_NOTIFY = "_remove_charge_complete_notify"
|
||||||
const val NOTIFY_ICON_DATAS = "_notify_icon_datas"
|
const val NOTIFY_ICON_DATAS = "_notify_icon_datas"
|
||||||
|
|
||||||
|
const val SOURCE_SYNC_WAY = "_source_sync_way"
|
||||||
|
const val SOURCE_SYNC_WAY_CUSTOM_URL = "_source_sync_way_custom_url"
|
||||||
|
|
||||||
|
const val TYPE_SOURCE_SYNC_WAY_1 = 1000
|
||||||
|
const val TYPE_SOURCE_SYNC_WAY_2 = 2000
|
||||||
|
const val TYPE_SOURCE_SYNC_WAY_3 = 3000
|
||||||
|
|
||||||
const val SYSTEMUI_PACKAGE_NAME = "com.android.systemui"
|
const val SYSTEMUI_PACKAGE_NAME = "com.android.systemui"
|
||||||
}
|
}
|
@@ -267,11 +267,19 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onHook() = encase {
|
override fun onHook() {
|
||||||
configs {
|
runConfig()
|
||||||
debugTag = "ColorOSNotify"
|
runHook()
|
||||||
isDebug = false
|
}
|
||||||
}
|
|
||||||
|
/** 配置 Hook */
|
||||||
|
private fun runConfig() = configs {
|
||||||
|
debugTag = "ColorOSNotify"
|
||||||
|
isDebug = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 开始 Hook */
|
||||||
|
private fun runHook() = encase {
|
||||||
loadApp(SYSTEMUI_PACKAGE_NAME) {
|
loadApp(SYSTEMUI_PACKAGE_NAME) {
|
||||||
when {
|
when {
|
||||||
/** 不是 ColorOS 系统停止 Hook */
|
/** 不是 ColorOS 系统停止 Hook */
|
||||||
@@ -301,7 +309,11 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
}
|
}
|
||||||
beforeHook {
|
beforeHook {
|
||||||
/** 是否移除 */
|
/** 是否移除 */
|
||||||
if (firstArgs as Int == 7 && prefs.getBoolean(REMOVE_CHANGECP_NOTIFY, default = false)) resultNull()
|
if (firstArgs as Int == 7 && prefs.getBoolean(
|
||||||
|
REMOVE_CHANGECP_NOTIFY,
|
||||||
|
default = false
|
||||||
|
)
|
||||||
|
) resultNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,8 @@
|
|||||||
*
|
*
|
||||||
* This file is Created by fankes on 2022/1/24.
|
* This file is Created by fankes on 2022/1/24.
|
||||||
*/
|
*/
|
||||||
|
@file:Suppress("MemberVisibilityCanBePrivate")
|
||||||
|
|
||||||
package com.fankes.coloros.notify.param
|
package com.fankes.coloros.notify.param
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@@ -27,9 +29,7 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import com.fankes.coloros.notify.bean.IconDataBean
|
import com.fankes.coloros.notify.bean.IconDataBean
|
||||||
import com.fankes.coloros.notify.hook.HookConst.NOTIFY_ICON_DATAS
|
import com.fankes.coloros.notify.hook.HookConst.NOTIFY_ICON_DATAS
|
||||||
import com.fankes.coloros.notify.utils.bitmap
|
import com.fankes.coloros.notify.utils.*
|
||||||
import com.fankes.coloros.notify.utils.safeOf
|
|
||||||
import com.fankes.coloros.notify.utils.safeOfNan
|
|
||||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
@@ -101,7 +101,7 @@ class IconPackParams(private val context: Context? = null, private val param: Pa
|
|||||||
* 已存储的 JSON 数据
|
* 已存储的 JSON 数据
|
||||||
* @return [String]
|
* @return [String]
|
||||||
*/
|
*/
|
||||||
private val storageDataJson get() = (context?.modulePrefs ?: param?.prefs)?.getString(NOTIFY_ICON_DATAS)
|
internal val storageDataJson get() = (context?.modulePrefs ?: param?.prefs)?.getString(NOTIFY_ICON_DATAS)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取图标数据
|
* 获取图标数据
|
||||||
@@ -113,25 +113,32 @@ class IconPackParams(private val context: Context? = null, private val param: Pa
|
|||||||
if (it.isNotBlank()) runCatching {
|
if (it.isNotBlank()) runCatching {
|
||||||
JSONArray(it).also { array ->
|
JSONArray(it).also { array ->
|
||||||
for (i in 0 until array.length()) runCatching {
|
for (i in 0 until array.length()) runCatching {
|
||||||
(array.get(i) as JSONObject).apply {
|
add(convertToBean(array.get(i) as JSONObject)!!)
|
||||||
add(
|
}.onFailure { context?.snake(msg = "部分规则加载失败") }
|
||||||
IconDataBean(
|
|
||||||
appName = getString("appName"),
|
|
||||||
packageName = getString("packageName"),
|
|
||||||
isEnabled = getBoolean("isEnabled"),
|
|
||||||
isEnabledAll = getBoolean("isEnabledAll"),
|
|
||||||
iconBitmap = getString("iconBitmap").bitmap,
|
|
||||||
iconColor = safeOfNan { Color.parseColor(getString("iconColor")) },
|
|
||||||
contributorName = getString("contributorName")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}.onFailure { context?.snake(msg = "规则加载发生错误") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为 [IconDataBean]
|
||||||
|
* @param jsonObject Json 实例
|
||||||
|
* @return [IconDataBean] or null
|
||||||
|
*/
|
||||||
|
private fun convertToBean(jsonObject: JSONObject) = safeOfNull {
|
||||||
|
jsonObject.let {
|
||||||
|
IconDataBean(
|
||||||
|
appName = it.getString("appName"),
|
||||||
|
packageName = it.getString("packageName"),
|
||||||
|
isEnabled = it.getBoolean("isEnabled"),
|
||||||
|
isEnabledAll = it.getBoolean("isEnabledAll"),
|
||||||
|
iconBitmap = it.getString("iconBitmap").bitmap,
|
||||||
|
iconColor = safeOfNan { Color.parseColor(it.getString("iconColor")) },
|
||||||
|
contributorName = it.getString("contributorName")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拼接图标数组数据
|
* 拼接图标数组数据
|
||||||
* @param dataJson1 图标数据 JSON
|
* @param dataJson1 图标数据 JSON
|
||||||
@@ -142,6 +149,34 @@ class IconPackParams(private val context: Context? = null, private val param: Pa
|
|||||||
dataJson1.replace(oldValue = "]", newValue = "") + "," + dataJson2.replace(oldValue = "[", newValue = "")
|
dataJson1.replace(oldValue = "]", newValue = "") + "," + dataJson2.replace(oldValue = "[", newValue = "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否不为合法 JSON
|
||||||
|
* @param json 数据
|
||||||
|
* @return [Boolean]
|
||||||
|
*/
|
||||||
|
fun isNotVaildJson(json: String) = !isJsonArray(json) && !isJsonObject(json)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为 JSON 数组
|
||||||
|
* @param json 数据
|
||||||
|
* @return [Boolean]
|
||||||
|
*/
|
||||||
|
fun isJsonArray(json: String) = json.trim().let { it.startsWith("[") && it.endsWith("]") }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为 JSON 实例
|
||||||
|
* @param json 数据
|
||||||
|
* @return [Boolean]
|
||||||
|
*/
|
||||||
|
fun isJsonObject(json: String) = json.trim().let { it.startsWith("{") && it.endsWith("}") }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为异常地址
|
||||||
|
* @param json 数据
|
||||||
|
* @return [Boolean]
|
||||||
|
*/
|
||||||
|
fun isHackString(json: String) = json.contains(other = "Checking your browser before accessing")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 比较图标数据不相等
|
* 比较图标数据不相等
|
||||||
* @param dataJson 图标数据 JSON
|
* @param dataJson 图标数据 JSON
|
||||||
|
@@ -34,8 +34,14 @@ import android.widget.ListView
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.constraintlayout.utils.widget.ImageFilterView
|
import androidx.constraintlayout.utils.widget.ImageFilterView
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.core.widget.doOnTextChanged
|
||||||
import com.fankes.coloros.notify.R
|
import com.fankes.coloros.notify.R
|
||||||
import com.fankes.coloros.notify.bean.IconDataBean
|
import com.fankes.coloros.notify.bean.IconDataBean
|
||||||
|
import com.fankes.coloros.notify.hook.HookConst.SOURCE_SYNC_WAY
|
||||||
|
import com.fankes.coloros.notify.hook.HookConst.SOURCE_SYNC_WAY_CUSTOM_URL
|
||||||
|
import com.fankes.coloros.notify.hook.HookConst.TYPE_SOURCE_SYNC_WAY_1
|
||||||
|
import com.fankes.coloros.notify.hook.HookConst.TYPE_SOURCE_SYNC_WAY_2
|
||||||
|
import com.fankes.coloros.notify.hook.HookConst.TYPE_SOURCE_SYNC_WAY_3
|
||||||
import com.fankes.coloros.notify.hook.factory.isAppNotifyHookAllOf
|
import com.fankes.coloros.notify.hook.factory.isAppNotifyHookAllOf
|
||||||
import com.fankes.coloros.notify.hook.factory.isAppNotifyHookOf
|
import com.fankes.coloros.notify.hook.factory.isAppNotifyHookOf
|
||||||
import com.fankes.coloros.notify.hook.factory.putAppNotifyHookAllOf
|
import com.fankes.coloros.notify.hook.factory.putAppNotifyHookAllOf
|
||||||
@@ -44,14 +50,13 @@ import com.fankes.coloros.notify.param.IconPackParams
|
|||||||
import com.fankes.coloros.notify.ui.base.BaseActivity
|
import com.fankes.coloros.notify.ui.base.BaseActivity
|
||||||
import com.fankes.coloros.notify.utils.*
|
import com.fankes.coloros.notify.utils.*
|
||||||
import com.fankes.coloros.notify.view.MaterialSwitch
|
import com.fankes.coloros.notify.view.MaterialSwitch
|
||||||
|
import com.google.android.material.radiobutton.MaterialRadioButton
|
||||||
import com.google.android.material.textfield.TextInputEditText
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
|
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||||
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
||||||
|
|
||||||
class ConfigureActivity : BaseActivity() {
|
class ConfigureActivity : BaseActivity() {
|
||||||
|
|
||||||
/** 访问请求链接 */
|
|
||||||
private var rawGithubUrl = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main"
|
|
||||||
|
|
||||||
/** 当前筛选条件 */
|
/** 当前筛选条件 */
|
||||||
private var filterText = ""
|
private var filterText = ""
|
||||||
|
|
||||||
@@ -188,7 +193,18 @@ class ConfigureActivity : BaseActivity() {
|
|||||||
lateinit var switchOpen: MaterialSwitch
|
lateinit var switchOpen: MaterialSwitch
|
||||||
lateinit var switchAll: MaterialSwitch
|
lateinit var switchAll: MaterialSwitch
|
||||||
}
|
}
|
||||||
}.apply { onChanged = { notifyDataSetChanged() } }
|
}.apply {
|
||||||
|
setOnItemLongClickListener { _, _, p, _ ->
|
||||||
|
showDialog {
|
||||||
|
title = "复制“${iconDatas[p].appName}”的规则"
|
||||||
|
msg = "是否复制单条规则到剪贴板?"
|
||||||
|
confirmButton { copyToClipboard(iconDatas[p].toString()) }
|
||||||
|
cancelButton()
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
onChanged = { notifyDataSetChanged() }
|
||||||
|
}
|
||||||
onScrollEvent = { post { setSelection(if (it) iconDatas.lastIndex else 0) } }
|
onScrollEvent = { post { setSelection(if (it) iconDatas.lastIndex else 0) } }
|
||||||
}
|
}
|
||||||
/** 设置点击事件 */
|
/** 设置点击事件 */
|
||||||
@@ -210,16 +226,119 @@ class ConfigureActivity : BaseActivity() {
|
|||||||
/** 首次进入或更新数据 */
|
/** 首次进入或更新数据 */
|
||||||
private fun onStartRefresh() =
|
private fun onStartRefresh() =
|
||||||
showDialog {
|
showDialog {
|
||||||
title = if (iconAllDatas.isNotEmpty()) "同步列表" else "初始化"
|
title = "同步列表"
|
||||||
msg = (if (iconAllDatas.isNotEmpty()) "建议定期从云端拉取数据以获得最新的通知图标优化名单适配数据。\n\n"
|
var sourceType = modulePrefs.getInt(SOURCE_SYNC_WAY, TYPE_SOURCE_SYNC_WAY_1)
|
||||||
else "首次装载需要从云端下载最新适配数据,后续可继续前往这里检查更新。\n\n") +
|
var customUrl = modulePrefs.getString(SOURCE_SYNC_WAY_CUSTOM_URL)
|
||||||
"通过从 Github 同步最新数据,无法连接可能需要魔法上网。"
|
addView(R.layout.dia_source_from).apply {
|
||||||
confirmButton(text = "开始同步") { onRefreshing() }
|
val radio1 = findViewById<MaterialRadioButton>(R.id.dia_sf_rd1)
|
||||||
|
val radio2 = findViewById<MaterialRadioButton>(R.id.dia_sf_rd2)
|
||||||
|
val radio3 = findViewById<MaterialRadioButton>(R.id.dia_sf_rd3)
|
||||||
|
val edLin = findViewById<View>(R.id.dia_sf_text_lin)
|
||||||
|
findViewById<TextInputEditText>(R.id.dia_sf_text).apply {
|
||||||
|
if (customUrl.isNotBlank()) {
|
||||||
|
setText(customUrl)
|
||||||
|
setSelection(customUrl.length)
|
||||||
|
}
|
||||||
|
doOnTextChanged { text, _, _, _ ->
|
||||||
|
customUrl = text.toString()
|
||||||
|
modulePrefs.putString(SOURCE_SYNC_WAY_CUSTOM_URL, text.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
edLin.isVisible = sourceType == TYPE_SOURCE_SYNC_WAY_3
|
||||||
|
radio1.isChecked = sourceType == TYPE_SOURCE_SYNC_WAY_1
|
||||||
|
radio2.isChecked = sourceType == TYPE_SOURCE_SYNC_WAY_2
|
||||||
|
radio3.isChecked = sourceType == TYPE_SOURCE_SYNC_WAY_3
|
||||||
|
radio1.setOnClickListener {
|
||||||
|
radio2.isChecked = false
|
||||||
|
radio3.isChecked = false
|
||||||
|
edLin.isVisible = false
|
||||||
|
sourceType = TYPE_SOURCE_SYNC_WAY_1
|
||||||
|
modulePrefs.putInt(SOURCE_SYNC_WAY, TYPE_SOURCE_SYNC_WAY_1)
|
||||||
|
}
|
||||||
|
radio2.setOnClickListener {
|
||||||
|
radio1.isChecked = false
|
||||||
|
radio3.isChecked = false
|
||||||
|
edLin.isVisible = false
|
||||||
|
sourceType = TYPE_SOURCE_SYNC_WAY_2
|
||||||
|
modulePrefs.putInt(SOURCE_SYNC_WAY, TYPE_SOURCE_SYNC_WAY_2)
|
||||||
|
}
|
||||||
|
radio3.setOnClickListener {
|
||||||
|
radio1.isChecked = false
|
||||||
|
radio2.isChecked = false
|
||||||
|
edLin.isVisible = true
|
||||||
|
sourceType = TYPE_SOURCE_SYNC_WAY_3
|
||||||
|
modulePrefs.putInt(SOURCE_SYNC_WAY, TYPE_SOURCE_SYNC_WAY_3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
confirmButton {
|
||||||
|
when (sourceType) {
|
||||||
|
TYPE_SOURCE_SYNC_WAY_1 -> onRefreshing(url = "https://raw.fastgit.org/fankes/AndroidNotifyIconAdapt/main")
|
||||||
|
TYPE_SOURCE_SYNC_WAY_2 -> onRefreshing(url = "https://raw.githubusercontent.com/fankes/AndroidNotifyIconAdapt/main")
|
||||||
|
TYPE_SOURCE_SYNC_WAY_3 ->
|
||||||
|
if (customUrl.isNotBlank())
|
||||||
|
if (customUrl.startsWith("http://") || customUrl.startsWith("https://"))
|
||||||
|
onRefreshingCustom(customUrl)
|
||||||
|
else snake(msg = "同步地址不是一个合法的 URL")
|
||||||
|
else snake(msg = "同步地址不能为空")
|
||||||
|
else -> snake(msg = "同步类型错误")
|
||||||
|
}
|
||||||
|
}
|
||||||
cancelButton()
|
cancelButton()
|
||||||
|
neutralButton(text = "自定义规则") {
|
||||||
|
showDialog {
|
||||||
|
title = "自定义规则"
|
||||||
|
var editText: TextInputEditText
|
||||||
|
addView(R.layout.dia_source_from_string).apply {
|
||||||
|
editText = findViewById<TextInputEditText>(R.id.dia_sfs_input_edit).apply {
|
||||||
|
requestFocus()
|
||||||
|
invalidate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconPackParams(context = this@ConfigureActivity).also { params ->
|
||||||
|
confirmButton(text = "合并") {
|
||||||
|
editText.text.toString().also { jsonString ->
|
||||||
|
when {
|
||||||
|
jsonString.isNotBlank() && params.isNotVaildJson(jsonString) -> snake(msg = "不是有效的 JSON 数据")
|
||||||
|
jsonString.isNotBlank() -> {
|
||||||
|
params.save(
|
||||||
|
params.splicingJsonArray(
|
||||||
|
dataJson1 = params.storageDataJson ?: "[]",
|
||||||
|
dataJson2 = jsonString.takeIf { params.isJsonArray(it) } ?: "[$jsonString]"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
filterText = ""
|
||||||
|
mockLocalData()
|
||||||
|
SystemUITool.showNeedUpdateApplySnake(context = this@ConfigureActivity)
|
||||||
|
}
|
||||||
|
else -> snake(msg = "请输入有效内容")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cancelButton(text = "覆盖") {
|
||||||
|
editText.text.toString().also { jsonString ->
|
||||||
|
when {
|
||||||
|
jsonString.isNotBlank() && params.isNotVaildJson(jsonString) -> snake(msg = "不是有效的 JSON 数据")
|
||||||
|
jsonString.isNotBlank() -> {
|
||||||
|
params.save(dataJson = jsonString.takeIf { params.isJsonArray(it) } ?: "[$jsonString]")
|
||||||
|
filterText = ""
|
||||||
|
mockLocalData()
|
||||||
|
SystemUITool.showNeedUpdateApplySnake(context = this@ConfigureActivity)
|
||||||
|
}
|
||||||
|
else -> snake(msg = "请输入有效内容")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
neutralButton(text = "取消")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 开始更新数据 */
|
/**
|
||||||
private fun onRefreshing() = ClientRequestTool.checkingInternetConnect(context = this) {
|
* 开始更新数据
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
private fun onRefreshing(url: String) = ClientRequestTool.checkingInternetConnect(context = this) {
|
||||||
ProgressDialog(this).apply {
|
ProgressDialog(this).apply {
|
||||||
setDefaultStyle(context = this@ConfigureActivity)
|
setDefaultStyle(context = this@ConfigureActivity)
|
||||||
setCancelable(false)
|
setCancelable(false)
|
||||||
@@ -229,22 +348,27 @@ class ConfigureActivity : BaseActivity() {
|
|||||||
}.also {
|
}.also {
|
||||||
ClientRequestTool.wait(
|
ClientRequestTool.wait(
|
||||||
context = this,
|
context = this,
|
||||||
url = "$rawGithubUrl/OS/ColorOS/NotifyIconsSupportConfig.json"
|
url = "$url/OS/ColorOS/NotifyIconsSupportConfig.json"
|
||||||
) { isDone1, ctOS ->
|
) { isDone1, ctOS ->
|
||||||
it.setMessage("正在同步 APP 数据")
|
it.setMessage("正在同步 APP 数据")
|
||||||
ClientRequestTool.wait(
|
ClientRequestTool.wait(
|
||||||
context = this,
|
context = this,
|
||||||
url = "$rawGithubUrl/APP/NotifyIconsSupportConfig.json"
|
url = "$url/APP/NotifyIconsSupportConfig.json"
|
||||||
) { isDone2, ctAPP ->
|
) { isDone2, ctAPP ->
|
||||||
it.cancel()
|
it.cancel()
|
||||||
IconPackParams(context = this).also { params ->
|
IconPackParams(context = this).also { params ->
|
||||||
if (isDone1 && isDone2) params.splicingJsonArray(ctOS, ctAPP).also {
|
if (isDone1 && isDone2) params.splicingJsonArray(ctOS, ctAPP).also {
|
||||||
if (params.isCompareDifferent(it)) {
|
when {
|
||||||
params.save(it)
|
params.isHackString(it) -> snake(msg = "请求需要验证,请尝试魔法上网或关闭魔法")
|
||||||
filterText = ""
|
params.isNotVaildJson(it) -> snake(msg = "在线规则发生问题,请稍后重试")
|
||||||
mockLocalData()
|
params.isCompareDifferent(it) -> {
|
||||||
SystemUITool.showNeedUpdateApplySnake(context = this)
|
params.save(it)
|
||||||
} else snake(msg = "列表数据已是最新")
|
filterText = ""
|
||||||
|
mockLocalData()
|
||||||
|
SystemUITool.showNeedUpdateApplySnake(context = this)
|
||||||
|
}
|
||||||
|
else -> snake(msg = "列表数据已是最新")
|
||||||
|
}
|
||||||
} else showDialog {
|
} else showDialog {
|
||||||
title = "连接失败"
|
title = "连接失败"
|
||||||
msg = "连接失败,错误如下:\n${if (!isDone1) ctOS else ctAPP}"
|
msg = "连接失败,错误如下:\n${if (!isDone1) ctOS else ctAPP}"
|
||||||
@@ -259,6 +383,46 @@ class ConfigureActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始更新数据
|
||||||
|
* @param url
|
||||||
|
*/
|
||||||
|
private fun onRefreshingCustom(url: String) = ClientRequestTool.checkingInternetConnect(context = this) {
|
||||||
|
ProgressDialog(this).apply {
|
||||||
|
setDefaultStyle(context = this@ConfigureActivity)
|
||||||
|
setCancelable(false)
|
||||||
|
setTitle("同步中")
|
||||||
|
setMessage("正在通过自定义地址同步数据")
|
||||||
|
show()
|
||||||
|
}.also {
|
||||||
|
ClientRequestTool.wait(
|
||||||
|
context = this,
|
||||||
|
url = url
|
||||||
|
) { isDone, content ->
|
||||||
|
it.cancel()
|
||||||
|
IconPackParams(context = this).also { params ->
|
||||||
|
if (isDone)
|
||||||
|
when {
|
||||||
|
params.isHackString(content) -> snake(msg = "请求需要验证,请尝试魔法上网或关闭魔法")
|
||||||
|
params.isNotVaildJson(content) -> snake(msg = "目标地址不是有效的 JSON 数据")
|
||||||
|
params.isCompareDifferent(content) -> {
|
||||||
|
params.save(content)
|
||||||
|
filterText = ""
|
||||||
|
mockLocalData()
|
||||||
|
SystemUITool.showNeedUpdateApplySnake(context = this)
|
||||||
|
}
|
||||||
|
else -> snake(msg = "列表数据已是最新")
|
||||||
|
}
|
||||||
|
else showDialog {
|
||||||
|
title = "连接失败"
|
||||||
|
msg = "连接失败,错误如下:\n$content"
|
||||||
|
confirmButton(text = "我知道了")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 刷新适配器结果相关 */
|
/** 刷新适配器结果相关 */
|
||||||
private fun refreshAdapterResult() {
|
private fun refreshAdapterResult() {
|
||||||
onChanged?.invoke()
|
onChanged?.invoke()
|
||||||
@@ -280,4 +444,4 @@ class ConfigureActivity : BaseActivity() {
|
|||||||
else iconAllDatas.filter {
|
else iconAllDatas.filter {
|
||||||
it.appName.lowercase().contains(filterText.lowercase()) || it.packageName.lowercase().contains(filterText.lowercase())
|
it.appName.lowercase().contains(filterText.lowercase()) || it.packageName.lowercase().contains(filterText.lowercase())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -60,7 +60,7 @@ class MainActivity : BaseActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
/** 设置文本 */
|
/** 设置文本 */
|
||||||
findViewById<TextView>(R.id.main_text_version).text = "当前版本:$moduleVersion"
|
findViewById<TextView>(R.id.main_text_version).text = "模块版本:$moduleVersion"
|
||||||
findViewById<TextView>(R.id.main_text_coloros_version).text = "系统版本:$colorOSVersion"
|
findViewById<TextView>(R.id.main_text_coloros_version).text = "系统版本:$colorOSVersion"
|
||||||
when {
|
when {
|
||||||
/** 判断是否为 ColorOS 系统 */
|
/** 判断是否为 ColorOS 系统 */
|
||||||
|
@@ -79,7 +79,7 @@ object ClientRequestTool {
|
|||||||
* @param url 请求地址
|
* @param url 请求地址
|
||||||
* @param it 回调 - ([Boolean] 是否成功,[String] 成功的内容或失败消息)
|
* @param it 回调 - ([Boolean] 是否成功,[String] 成功的内容或失败消息)
|
||||||
*/
|
*/
|
||||||
fun wait(context: Activity, url: String, it: (Boolean, String) -> Unit) {
|
fun wait(context: Activity, url: String, it: (Boolean, String) -> Unit) = runCatching {
|
||||||
OkHttpClient().newBuilder().apply {
|
OkHttpClient().newBuilder().apply {
|
||||||
SSLSocketClient.sSLSocketFactory?.let { sslSocketFactory(it, SSLSocketClient.trustManager) }
|
SSLSocketClient.sSLSocketFactory?.let { sslSocketFactory(it, SSLSocketClient.trustManager) }
|
||||||
hostnameVerifier(SSLSocketClient.hostnameVerifier)
|
hostnameVerifier(SSLSocketClient.hostnameVerifier)
|
||||||
@@ -98,7 +98,7 @@ object ClientRequestTool {
|
|||||||
context.runOnUiThread { it(true, bodyString) }
|
context.runOnUiThread { it(true, bodyString) }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}.onFailure { it(false, "URL 无效") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动信任 SSL 证书
|
* 自动信任 SSL 证书
|
||||||
|
@@ -26,6 +26,8 @@ package com.fankes.coloros.notify.utils
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageInfo
|
import android.content.pm.PackageInfo
|
||||||
@@ -42,11 +44,13 @@ import android.widget.Toast
|
|||||||
import com.fankes.coloros.notify.application.CNNApplication.Companion.appContext
|
import com.fankes.coloros.notify.application.CNNApplication.Companion.appContext
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.highcapable.yukihookapi.hook.factory.classOf
|
import com.highcapable.yukihookapi.hook.factory.classOf
|
||||||
|
import com.highcapable.yukihookapi.hook.factory.field
|
||||||
import com.highcapable.yukihookapi.hook.factory.hasClass
|
import com.highcapable.yukihookapi.hook.factory.hasClass
|
||||||
import com.highcapable.yukihookapi.hook.factory.method
|
import com.highcapable.yukihookapi.hook.factory.method
|
||||||
import com.highcapable.yukihookapi.hook.log.loggerE
|
import com.highcapable.yukihookapi.hook.log.loggerE
|
||||||
import com.highcapable.yukihookapi.hook.type.java.StringType
|
import com.highcapable.yukihookapi.hook.type.java.StringType
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统深色模式是否开启
|
* 系统深色模式是否开启
|
||||||
@@ -103,9 +107,12 @@ inline val isNotColorOS get() = !isColorOS
|
|||||||
*/
|
*/
|
||||||
val colorOSVersion
|
val colorOSVersion
|
||||||
get() = safeOf(default = "无法获取") {
|
get() = safeOf(default = "无法获取") {
|
||||||
findPropString(key = "ro.system.build.fingerprint", default = "无法获取")
|
(classOf(name = "com.oplus.os.OplusBuild").let {
|
||||||
|
it.field { name = "VERSIONS" }.ignoredError().of<Array<String>>()
|
||||||
|
?.get((it.method { name = "getOplusOSVERSION" }.ignoredError().get().invoke<Int>() ?: 23) - 1)
|
||||||
|
} ?: findPropString(key = "ro.system.build.fingerprint", default = "无法获取")
|
||||||
.split("ssi:")[1]
|
.split("ssi:")[1]
|
||||||
.split("/")[0].trim()
|
.split("/")[0].trim()) + " ${Build.DISPLAY}"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,6 +159,17 @@ val Number.dp get() = (toFloat() * appContext.resources.displayMetrics.density).
|
|||||||
*/
|
*/
|
||||||
fun Number.dp(context: Context) = (toFloat() * context.resources.displayMetrics.density).toInt()
|
fun Number.dp(context: Context) = (toFloat() * context.resources.displayMetrics.density).toInt()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base64 加密
|
||||||
|
* @return [String]
|
||||||
|
*/
|
||||||
|
val Bitmap.base64
|
||||||
|
get() = safeOfNothing {
|
||||||
|
val baos = ByteArrayOutputStream()
|
||||||
|
compress(Bitmap.CompressFormat.PNG, 100, baos)
|
||||||
|
Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base64 加密
|
* Base64 加密
|
||||||
* @return [String]
|
* @return [String]
|
||||||
@@ -255,6 +273,19 @@ fun Context.openBrowser(url: String, packageName: String = "") =
|
|||||||
else snake(msg = "启动系统浏览器失败")
|
else snake(msg = "启动系统浏览器失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制到剪贴板
|
||||||
|
* @param content 要复制的文本
|
||||||
|
*/
|
||||||
|
fun Context.copyToClipboard(content: String) = runCatching {
|
||||||
|
(getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).apply {
|
||||||
|
setPrimaryClip(ClipData.newPlainText(null, content))
|
||||||
|
(primaryClip?.getItemAt(0)?.text ?: "").also {
|
||||||
|
if (it != content) snake(msg = "复制失败") else snake(msg = "已复制")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 忽略异常返回值
|
* 忽略异常返回值
|
||||||
* @param it 回调 - 如果异常为空
|
* @param it 回调 - 如果异常为空
|
||||||
|
@@ -149,7 +149,7 @@
|
|||||||
android:divider="@color/trans"
|
android:divider="@color/trans"
|
||||||
android:dividerHeight="15dp"
|
android:dividerHeight="15dp"
|
||||||
android:fadingEdgeLength="10dp"
|
android:fadingEdgeLength="10dp"
|
||||||
android:listSelector="@null"
|
android:listSelector="@color/trans"
|
||||||
android:padding="15dp"
|
android:padding="15dp"
|
||||||
android:requiresFadingEdge="vertical"
|
android:requiresFadingEdge="vertical"
|
||||||
android:scrollbars="none" />
|
android:scrollbars="none" />
|
||||||
|
@@ -86,7 +86,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:alpha="0.8"
|
android:alpha="0.8"
|
||||||
android:text="当前版本:%1"
|
android:text="模块版本:%1"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="13sp" />
|
android:textSize="13sp" />
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:alpha="0.8"
|
android:alpha="0.8"
|
||||||
android:text="ColorOS 版本:%1"
|
android:text="系统版本:%1"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="13sp" />
|
android:textSize="13sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -447,7 +447,7 @@
|
|||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:alpha="0.8"
|
android:alpha="0.8"
|
||||||
android:lineSpacingExtra="6dp"
|
android:lineSpacingExtra="6dp"
|
||||||
android:text="Q.哪些是已知问题?\nA.暂时只对 ColorOS 12 做了适配,其它版本情况未知,请自行进行测试。"
|
android:text="Q.哪些是已知问题?\nA.问题如下:\n1.由于机型有限,仅对 ColorOS 12~12.1 测试正常运行,根据酷友的需要云调试修复 ColorOS 11 的问题,其它版本情况未知,请自行进行测试。\n2.OxygenOS 只支持 12 版本,其它类 ColorOS 魔改的 UI 理论没有问题,请自行测试。"
|
||||||
android:textColor="@color/colorTextDark"
|
android:textColor="@color/colorTextDark"
|
||||||
android:textSize="12sp" />
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/bg_permotion_round"
|
android:background="@drawable/bg_permotion_round"
|
||||||
android:baselineAligned="false"
|
android:baselineAligned="false"
|
||||||
|
android:descendantFocusability="blocksDescendants"
|
||||||
android:gravity="center|start"
|
android:gravity="center|start"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="15dp"
|
android:padding="15dp"
|
||||||
|
54
app/src/main/res/layout/dia_source_from.xml
Normal file
54
app/src/main/res/layout/dia_source_from.xml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?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="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="15dp"
|
||||||
|
android:paddingTop="15dp"
|
||||||
|
android:paddingRight="15dp"
|
||||||
|
tools:ignore="HardcodedText">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8.5dp"
|
||||||
|
android:layout_marginRight="8.5dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:lineSpacingExtra="6dp"
|
||||||
|
android:text="在线规则将不定期更新,建议定期同步列表以适配更多 APP,若无法同步请自行寻找解决方法或魔法上网。"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||||
|
android:id="@+id/dia_sf_rd1"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="从 FastGit 获取" />
|
||||||
|
|
||||||
|
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||||
|
android:id="@+id/dia_sf_rd2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="从 Github Raw 获取" />
|
||||||
|
|
||||||
|
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||||
|
android:id="@+id/dia_sf_rd3"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="从自定义地址获取" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/dia_sf_text_lin"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/dia_sf_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:hint="请输入在线地址 URL"
|
||||||
|
android:singleLine="true" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
</LinearLayout>
|
25
app/src/main/res/layout/dia_source_from_string.xml
Normal file
25
app/src/main/res/layout/dia_source_from_string.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?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="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="15dp"
|
||||||
|
android:paddingTop="15dp"
|
||||||
|
android:paddingRight="15dp"
|
||||||
|
tools:ignore="HardcodedText">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/dia_sfs_input_edit"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="150dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center|start|top"
|
||||||
|
android:hint="请粘贴 JSON 规则到此处"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
</LinearLayout>
|
@@ -5,8 +5,8 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
appVersionName = "1.2"
|
appVersionName = "1.35"
|
||||||
appVersionCode = 3
|
appVersionCode = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
|
Reference in New Issue
Block a user