Android新手如何检测LINE应用通话状态并实现通话后返回自身应用?
嘿,作为Android新手能搞定唤起LINE已经超棒啦!针对你提到的「通话挂断后自动返回应用」和「检测LINE通话状态」这两个需求,我整理了实用的实现思路和代码示例,你可以参考下:
这里主要可以通过Activity Result API结合系统特性来实现,核心思路是监听LINE通话页面的生命周期结束事件,然后主动拉回你的应用:
第一步:用Activity Result API启动LINE通话
替代传统的startActivityForResult,AndroidX推荐用registerForActivityResult来启动LINE,这样能在LINE的页面销毁时收到回调:// 在你的Activity里注册回调 private val lineCallLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> // 不管LINE返回什么结果,只要通话页面关闭,就拉回你的主界面 val backToAppIntent = Intent(this, MainActivity::class.java).apply { // 清除栈顶,确保回到的是最新的主界面 addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) } startActivity(backToAppIntent) } // 唤起LINE通话的代码 fun startLineCall() { val lineCallIntent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("line://call/你的目标用户LINE ID或号码") addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } // 启动LINE lineCallLauncher.launch(lineCallIntent) }补充:如果上述方法不生效(比如LINE通话是独立进程,不会触发回调),可以结合前台服务+应用前台状态监听:
启动一个前台服务,定时检测LINE是否还在前台,当LINE退出前台时,就主动启动你的应用主界面。
遗憾的是LINE并没有公开官方API来直接获取通话状态,我们只能通过系统提供的特性间接实现,下面是两种可行的方案:
方案1:监听应用前台状态(简单易实现)
通过UsageStatsManager获取当前前台应用,判断是否是LINE,再结合界面特征判断是否在通话中:
- 首先添加权限到Manifest:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" /> - 然后编写检测方法:
private fun isLineInCall(): Boolean { val usageStatsManager = getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager val currentTime = System.currentTimeMillis() // 查询最近10秒的应用使用记录 val stats = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_BEST, currentTime - 10000, currentTime ) stats?.sortedByDescending { it.lastTimeUsed }?.firstOrNull()?.let { topApp -> if (topApp.packageName == "jp.naver.line.android") { // 这里可以进一步通过ActivityManager获取当前LINE的顶层Activity类名 // 判断是否是通话界面(比如类名包含"Call"关键词) val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager activityManager.getRunningTasks(1).firstOrNull()?.topActivity?.className?.let { className -> return className.contains("Call") } } } return false } - 注意:这个方法需要用户在系统设置中给你的应用开启「使用情况访问权限」,所以要在应用里引导用户跳转设置页。
方案2:使用AccessibilityService(更精准)
通过辅助功能监听LINE的界面变化,直接捕捉通话界面的出现和消失:
第一步:创建AccessibilityService子类
class LineCallMonitorService : AccessibilityService() { override fun onAccessibilityEvent(event: AccessibilityEvent?) { event?.takeIf { it.packageName == "jp.naver.line.android" }?.let { if (it.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { val className = it.className.toString() when { className.contains("Call") -> { // 通话开始,可以在这里记录状态 Log.d("LineCall", "LINE通话已开始") } else -> { // 通话结束,自动返回你的应用 val backIntent = Intent(this, MainActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } startActivity(backIntent) } } } } } override fun onInterrupt() {} }第二步:在Manifest中注册服务
<service android:name=".LineCallMonitorService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_config" /> </service>第三步:创建accessibility_config.xml(放在res/xml目录下)
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeWindowStateChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="true" android:packageNames="jp.naver.line.android" />注意:这个方法需要用户给你的应用开启辅助功能,同样需要在应用里引导用户完成设置。
最后提醒下:因为这些都是非官方的实现方式,可能会随着LINE的版本更新而失效,建议你在不同版本的LINE上测试验证稳定性哦!
内容的提问来源于stack exchange,提问作者Jasmine Antony

