You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android平台使用Kotlin检测用户访问的网站

可行的网站监控替代方案

一、AccessibilityService(辅助功能服务)

  • 核心逻辑:通过监听系统中浏览器应用的界面元素变化,提取地址栏中的URL。无需VPN权限,但需要用户手动开启辅助功能。
  • 实现要点:
    1. 创建继承自AccessibilityService的类,重写onAccessibilityEvent方法处理界面变化事件。
    2. 在AndroidManifest中声明服务,指定可监听的主流浏览器包名(如Chrome、Edge)。
    3. 遍历界面节点,识别地址栏控件并提取文本内容。
  • 代码示例:
class WebMonitorAccessibilityService : AccessibilityService() {
    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        if (event.eventType != AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) return

        // 过滤目标浏览器包名
        val targetPackages = listOf("com.android.chrome", "com.microsoft.emmx", "org.mozilla.firefox")
        if (!targetPackages.contains(event.packageName)) return

        rootInActiveWindow?.let { findUrlInNodes(it) }
    }

    private fun findUrlInNodes(node: AccessibilityNodeInfo) {
        // 匹配地址栏输入框(多数浏览器用EditText承载地址)
        if (node.className == "android.widget.EditText" && node.text != null) {
            val url = node.text.toString()
            if (url.startsWith("http")) {
                // 此处可将URL存入本地数据库或上传至后端
                Log.d("WebMonitor", "当前访问网址: $url")
            }
        }

        // 递归遍历子节点
        for (i in 0 until node.childCount) {
            node.getChild(i)?.let { findUrlInNodes(it) }
        }
    }

    override fun onInterrupt() {}
}
  • 注意:不同浏览器的地址栏控件结构可能不同,需要针对性适配;无法监控浏览器隐身模式下的访问。

二、监听浏览器历史ContentProvider

  • 核心逻辑:多数主流浏览器会将浏览历史存储在公开的ContentProvider中,通过ContentObserver监听数据变化,读取最新历史记录。
  • 实现要点:
    1. 在AndroidManifest中添加权限:android.permission.READ_HISTORY_BOOKMARKS(针对系统浏览器);Android 10+访问Chrome历史需额外申请QUERY_ALL_PACKAGES权限或指定Chrome包名的QUERY_PACKAGE_CONTENTS权限。
    2. 创建ContentObserver子类,监听对应浏览器的历史URI。
    3. 历史数据变化时,查询ContentProvider获取最新URL。
  • 代码示例(以Chrome为例):
class ChromeHistoryObserver(private val context: Context, handler: Handler) : ContentObserver(handler) {
    private val CHROME_HISTORY_URI = Uri.parse("content://com.android.chrome.browser/bookmarks")

    fun startObserving() {
        context.contentResolver.registerContentObserver(CHROME_HISTORY_URI, true, this)
    }

    fun stopObserving() {
        context.contentResolver.unregisterContentObserver(this)
    }

    override fun onChange(selfChange: Boolean, uri: Uri?) {
        super.onChange(selfChange, uri)
        // 查询最新1条历史记录
        val projection = arrayOf("url", "date_added")
        val sortOrder = "date_added DESC LIMIT 1"
        context.contentResolver.query(CHROME_HISTORY_URI, projection, null, null, sortOrder)?.use { cursor ->
            if (cursor.moveToFirst()) {
                val url = cursor.getString(cursor.getColumnIndexOrThrow("url"))
                val timestamp = cursor.getLong(cursor.getColumnIndexOrThrow("date_added"))
                Log.d("WebMonitor", "Chrome历史新增: $url 时间戳: $timestamp")
            }
        }
    }
}

// 使用方式
val observer = ChromeHistoryObserver(context, Handler(Looper.getMainLooper()))
observer.startObserving()
  • 注意:不同浏览器的历史URI不同,需自行查阅对应文档;部分小众浏览器可能不开放历史ContentProvider;无法实时监控正在访问的网址,只能获取已记录的历史。

三、UsageStatsManager + 辅助功能组合方案

  • 核心逻辑:通过UsageStatsManager获取当前活跃的应用包名,判断是否为浏览器,再结合辅助功能服务提取当前网址。
  • 实现要点:
    1. 申请android.permission.PACKAGE_USAGE_STATS权限,需引导用户跳转到系统设置开启。
    2. 定时查询应用使用统计,识别当前活跃的浏览器。
    3. 若检测到浏览器活跃,触发辅助功能服务提取地址栏URL。
  • 代码示例(获取当前活跃浏览器):
fun getCurrentActiveBrowser(context: Context): String? {
    val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
    val endTime = System.currentTimeMillis()
    val startTime = endTime - 60 * 1000 // 查询最近1分钟的使用记录

    val stats = usageStatsManager.queryUsageStats(
        UsageStatsManager.INTERVAL_BEST,
        startTime,
        endTime
    )

    var currentPackage: String? = null
    var lastActiveTime = 0L

    stats.forEach { stat ->
        if (stat.lastTimeUsed > lastActiveTime) {
            lastActiveTime = stat.lastTimeUsed
            currentPackage = stat.packageName
        }
    }

    val browserPackages = listOf("com.android.chrome", "com.microsoft.emmx", "org.mozilla.firefox")
    return if (browserPackages.contains(currentPackage)) currentPackage else null
}
  • 注意:仅能识别活跃浏览器,需配合辅助功能才能获取具体网址;权限开启流程较繁琐,需做好用户引导。

内容的提问来源于stack exchange,提问作者Powplowdevs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:13:11