mirror of
https://github.com/gkd-kit/gkd.git
synced 2024-11-16 11:42:22 +08:00
u
This commit is contained in:
parent
a458ca2fdf
commit
64e6169321
11
.github/workflows/Apk-Build.yml
vendored
11
.github/workflows/Apk-Build.yml
vendored
|
@ -15,8 +15,9 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- run: chmod 777 ./gradlew
|
||||
- run: ./gradlew build
|
||||
# - name: Archive production artifacts
|
||||
# uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# name: dist
|
||||
# path: test.js
|
||||
- run: ./gradlew assembleDebug
|
||||
- name: Archive artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: build-outputs-apk
|
||||
path: app/build/outputs/apk
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# AdCloser
|
||||
|
||||
基于无障碍和自定义匹配规则的广告关闭app
|
||||
|
||||
记录递归调用的次数, 根据统计次数考虑是否添加规则长度, 可减少匹配时间
|
||||
|
|
|
@ -28,10 +28,10 @@ class MainActivity : ComponentActivity() {
|
|||
LogUtils.d(this)
|
||||
packageName
|
||||
}
|
||||
checkPermission(0)
|
||||
Shizuku.addRequestPermissionResultListener { requestCode, grantResult ->
|
||||
LogUtils.d(requestCode, grantResult)
|
||||
}
|
||||
// Shizuku.addRequestPermissionResultListener { requestCode, grantResult ->
|
||||
// LogUtils.d(requestCode, grantResult)
|
||||
// }
|
||||
// checkPermission(0)
|
||||
// Shizuku.bindUserService()
|
||||
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@ data class Rule(
|
|||
) {
|
||||
companion object {
|
||||
val defaultRuleList = listOf<Rule>(
|
||||
Rule(
|
||||
"com.zhihu.android",
|
||||
"com.zhihu.android.mix.activity.ContentMixProfileActivity",
|
||||
"View[text=查看详情] + View[text=×]"
|
||||
),
|
||||
// Rule(
|
||||
// "com.zhihu.android",
|
||||
// "com.zhihu.android.mix.activity.ContentMixProfileActivity",
|
||||
// "View[text=查看详情] + View[text=×]"
|
||||
// ),
|
||||
Rule(
|
||||
"com.zhihu.android",
|
||||
"com.zhihu.android.mix.activity.ContentMixProfileActivity",
|
||||
|
@ -101,14 +101,57 @@ data class Rule(
|
|||
"tv.danmaku.bili",
|
||||
"tv.danmaku.bili.ui.video.VideoDetailsActivity",
|
||||
"ImageView[id=tv.danmaku.bili:id/close]"
|
||||
)
|
||||
// TODO NAF node 的父亲节点属性无法查询
|
||||
,
|
||||
|
||||
),
|
||||
Rule(
|
||||
"com.duokan.phone.remotecontroller",
|
||||
"com.xiaomi.mitv.phone.remotecontroller.HoriWidgetMainActivityV2",
|
||||
"ImageView[id=com.duokan.phone.remotecontroller:id/image_close_banner]"
|
||||
),
|
||||
Rule(
|
||||
"com.tencent.mm",
|
||||
"com.tencent.mm.plugin.sns.ui.SnsTimeLineUI",
|
||||
"TextView[id=com.tencent.mm:id/hus][text=选择后将减少该类推荐] + TextView[id=com.tencent.mm:id/hui][text=确认]"
|
||||
),
|
||||
Rule(
|
||||
"com.tencent.mm",
|
||||
"com.tencent.mm.plugin.sns.ui.SnsTimeLineUI",
|
||||
"TextView[id=com.tencent.mm:id/hus][text=选择后将减少该类推荐] + FrameLayout[id=com.tencent.mm:id/huj] > ViewGroup[id=com.tencent.mm:id/hul] > TextView[text=直接关闭]"
|
||||
),
|
||||
Rule(
|
||||
"com.tencent.mm",
|
||||
"com.tencent.mm.plugin.sns.ui.SnsTimeLineUI",
|
||||
"TextView[id=com.tencent.mm:id/hus][text*=广告] + FrameLayout[id=com.tencent.mm:id/huj] > LinearLayout[id=com.tencent.mm:id/hum] > LinearLayout[id=com.tencent.mm:id/hue] + LinearLayout[id=com.tencent.mm:id/hup]"
|
||||
),
|
||||
Rule(
|
||||
"com.tencent.mm",
|
||||
"com.tencent.mm.plugin.sns.ui.SnsTimeLineUI",
|
||||
"LinearLayout[childCount=2] > LinearLayout[id=com.tencent.mm:id/fzb] > TextView[id=com.tencent.mm:id/fzg] + LinearLayout[id=com.tencent.mm:id/fj][childCount=0]"
|
||||
),
|
||||
Rule(
|
||||
"com.baidu.tieba",
|
||||
"com.baidu.tieba.pb.pb.main.PbActivity",
|
||||
"TextView[id=com.baidu.tieba:id/head_text] + View[id=com.baidu.tieba:id/uninterested_btn]"
|
||||
),
|
||||
Rule(
|
||||
"com.baidu.tieba",
|
||||
"com.baidu.tieba.pb.pb.main.PbActivity",
|
||||
"ImageView[id=com.baidu.tieba:id/coverView] + TextView[id=com.baidu.tieba:id/alaStateView] + TextView[id=com.baidu.tieba:id/descView] + RelativeLayout + ImageView"
|
||||
),
|
||||
Rule(
|
||||
"com.zhihu.android",
|
||||
"com.zhihu.android.app.ui.activity.MainActivity",
|
||||
"LinearLayout[id=com.zhihu.android:id/content] > RelativeLayout > TextView[id=com.zhihu.android:id/title][text=不感兴趣]"
|
||||
),
|
||||
Rule(
|
||||
"com.zhihu.android",
|
||||
"com.zhihu.android.app.ui.activity.MainActivity",
|
||||
"FrameLayout[id=com.zhihu.android:id/ad_float] >> RecyclerView > FrameLayout > ViewGroup > ViewGroup > FrameLayout > ViewGroup[childCount=1] + ViewGroup[childCount=1] > ImageView"
|
||||
),
|
||||
// new rule
|
||||
Rule(
|
||||
"com.zhihu.android",
|
||||
"com.zhihu.android.mix.activity.ContentMixProfileActivity",
|
||||
"TextView[text*=赞同][text$=评论][text*=·] + TextView[text$=专题精选] + View[text=×]"
|
||||
)
|
||||
// Rule(
|
||||
// "com.coolapk.market",
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package li.songe.ad_closer.service
|
||||
|
||||
import android.accessibilityservice.AccessibilityService
|
||||
import android.content.ComponentName
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.pm.PackageManager.NameNotFoundException
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
import com.blankj.utilcode.util.LogUtils
|
||||
|
@ -18,24 +15,23 @@ import li.songe.ad_closer.util.findNodeInfo
|
|||
*/
|
||||
class AdCloserService : AccessibilityService() {
|
||||
|
||||
private fun getActivityInfo(componentName: ComponentName): ActivityInfo? {
|
||||
return try {
|
||||
packageManager.getActivityInfo(componentName, 0)
|
||||
} catch (e: NameNotFoundException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
// private fun getActivityInfo(componentName: ComponentName): ActivityInfo? {
|
||||
// return try {
|
||||
// packageManager.getActivityInfo(componentName, 0)
|
||||
// } catch (e: NameNotFoundException) {
|
||||
// null
|
||||
// }
|
||||
// }
|
||||
|
||||
private val scope = CoroutineScope(Dispatchers.Default + Job())
|
||||
// override fun onDestroy() {
|
||||
// super.onDestroy()
|
||||
// }
|
||||
|
||||
private var currentPackageName: String? = null
|
||||
// 考虑n种模式
|
||||
// 默认情况 正常获取 activity class name
|
||||
// 不使用 activity class name, 直接用 package class name, 会导致 匹配规则 变多
|
||||
// 借助 shizuku 使用 adb 获取 activity class name
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
LogUtils.d("onCreate")
|
||||
}
|
||||
|
||||
override fun onServiceConnected() {
|
||||
super.onServiceConnected()
|
||||
|
@ -54,14 +50,22 @@ class AdCloserService : AccessibilityService() {
|
|||
if (window != null && ruleListMap.containsKey(currentActivityClassName)) {
|
||||
run loop@{
|
||||
ruleListMap[currentActivityClassName]!!.forEachIndexed { _, rule ->
|
||||
val nodeInfo =
|
||||
findNodeInfo(window, rule.matchUnit, listOf(0))
|
||||
if (nodeInfo != null) {
|
||||
LogUtils.dTag("click", rule.rawText)
|
||||
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)
|
||||
nodeInfo.recycle()
|
||||
return@loop
|
||||
var nodeInfo = findNodeInfo(window, rule.matchUnit, listOf(0))
|
||||
var level = 0
|
||||
while (nodeInfo != null && !nodeInfo.isClickable) {
|
||||
nodeInfo = nodeInfo.parent
|
||||
level += 1
|
||||
}
|
||||
if (nodeInfo != null) {
|
||||
nodeInfo.apply {
|
||||
LogUtils.dTag("click", level, rule.rawText)
|
||||
performAction(AccessibilityNodeInfo.ACTION_CLICK)
|
||||
}
|
||||
} else {
|
||||
LogUtils.dTag("click", "not isClickable", rule.rawText)
|
||||
}
|
||||
return@loop
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +109,12 @@ class AdCloserService : AccessibilityService() {
|
|||
// 在桌面和应用之间来回切换, 大概率导致识别失败
|
||||
if (!className.startsWith("android.") && !className.startsWith("androidx.")) {
|
||||
// className.startsWith(packageName)
|
||||
currentActivityClassName = className
|
||||
val rootPackageName = rootInActiveWindow?.packageName?.toString() ?: ""
|
||||
if ((className == "com.miui.home.launcher.Launcher" && rootPackageName != "com.miui.home")) {
|
||||
// 上滑手势, 导致 活动名 不属于包名
|
||||
} else {
|
||||
currentActivityClassName = className
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
@ -141,7 +150,12 @@ class AdCloserService : AccessibilityService() {
|
|||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
LogUtils.dTag("updateClassName", field, rootInActiveWindow?.packageName)
|
||||
val packageName = rootInActiveWindow?.packageName
|
||||
LogUtils.dTag(
|
||||
"updateClassName",
|
||||
field,
|
||||
packageName,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ private fun match(
|
|||
return false
|
||||
}
|
||||
val childCount = nodeInfo.childCount
|
||||
val text:CharSequence? = nodeInfo.text
|
||||
val id:String? = nodeInfo.viewIdResourceName
|
||||
val text: CharSequence? = nodeInfo.text
|
||||
val id: String? = nodeInfo.viewIdResourceName
|
||||
|
||||
// 在属性匹配列表不空的情况下, 列表所有项都匹配
|
||||
if (matchUnit.attributeSelectorList.isNotEmpty()) {
|
||||
|
@ -49,7 +49,7 @@ private fun match(
|
|||
AttributeSelector.Operator.Less -> childCount < it.value.toInt()
|
||||
AttributeSelector.Operator.More -> childCount > it.value.toInt()
|
||||
AttributeSelector.Operator.Start -> false
|
||||
else-> TODO()
|
||||
else -> TODO()
|
||||
}
|
||||
AttributeSelector.Attribute.Id -> {
|
||||
when (it.operator) {
|
||||
|
@ -59,19 +59,19 @@ private fun match(
|
|||
AttributeSelector.Operator.Less -> false
|
||||
AttributeSelector.Operator.More -> false
|
||||
AttributeSelector.Operator.Start -> false
|
||||
else-> TODO()
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
AttributeSelector.Attribute.Text -> text!=null &&when (it.operator) {
|
||||
AttributeSelector.Attribute.Text -> text != null && when (it.operator) {
|
||||
AttributeSelector.Operator.End -> text.endsWith(it.value)
|
||||
AttributeSelector.Operator.Equal -> text == it.value
|
||||
AttributeSelector.Operator.Include -> text.contains(it.value)
|
||||
AttributeSelector.Operator.Less -> false
|
||||
AttributeSelector.Operator.More -> false
|
||||
AttributeSelector.Operator.Start -> text.startsWith(it.value)
|
||||
else-> TODO()
|
||||
else -> TODO()
|
||||
}
|
||||
else-> TODO()
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
if (!condition2) {
|
||||
|
@ -123,7 +123,7 @@ private fun match(
|
|||
return false
|
||||
}
|
||||
|
||||
fun findNodeInfo(
|
||||
fun findNodeInfo(
|
||||
nodeInfo: AccessibilityNodeInfo?,
|
||||
matchUnit: MatchUnit,
|
||||
pathIndexList: List<Int>,
|
||||
|
|
Loading…
Reference in New Issue
Block a user