【问题标题】:Detecting outgoing call answered on Android检测在 Android 上接听的拨出电话
【发布时间】:2013-05-22 04:59:52
【问题描述】:

我知道这个问题已经被问过很多次了,没有答案,但我仍然希望有人终于解决了这个问题。

问题:我有一台运行 Android 2.3 的无根设备。我需要创建一个服务:

  1. 拨打电话;
  2. 等待呼叫被应答;
  3. 接听电话后挂断电话(超时);

像许多其他人一样,我一直坚持 #2。以下是曾经提出的解决方案的摘要:

  • 使用 PhoneStateListener(最流行):不起作用,对于拨出电话它无法检测到我需要什么。
  • 使用com.android.internal.telephony.CallManager 及其类似registerForPreciseCallStateChanged 的方法(例如this one):不起作用,其中没有注册电话,因此不会触发事件。
  • 使用com.android.internal.telephony.PhoneFactory获取com.android.internal.telephony.Phone实例(这是一切的关键):不起作用,工厂没有初始化;尝试使用 makeDefaultPhones 调用对其进行初始化会导致安全异常(如 here)。
  • 检测输出铃声 (link):作者 - Dany Poplawec - 表示检测铃声可能有助于解决问题,但没有提供任何细节,所以我无法尝试这种技术。李>

看起来一切都已经尝试过了,但可能还有一个技巧可以拯救我:)

【问题讨论】:

  • 你有解决办法吗?
  • 唉,看来除了修改安卓操作系统本身什么都做不了。

标签: android


【解决方案1】:

我也在尝试解决这个问题,但还没有找到任何解决方案。

查看 Android 源代码,我在 ~/kitchen/jellybean/frameworks/opt/telephony/src/java/com/android/internal/telephony/Call.java 中找到了这些行

public enum State {
    IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING;

    public boolean isAlive() {
        return !(this == IDLE || this == DISCONNECTED || this == DISCONNECTING);
    }

    public boolean isRinging() {
        return this == INCOMING || this == WAITING;
    }

    public boolean isDialing() {
        return this == DIALING || this == ALERTING;
    }
}

我认为通过检查 ACTIVE 状态可以知道是否接听了拨出电话,但我不知道如何从应用程序中读取此值,也许可以通过为此添加特定函数来修改框架:

    public boolean isActive() {
         return this == ACTIVE;
    }

这只是一个想法,但我不确定如何实现,因为显然必须进行其他修改才能从应用程序层访问这个新功能。

如果您发现此方法可行或知道如何操作,我们将非常感谢您提供帮助和反馈。

【讨论】:

    【解决方案2】:

    如果您按照Android INJECT_EVENTS permission 中的说明进行操作,则第三个项目符号中的解决方案应该可以在有根设备中使用

    一步一步,就是这样的:

    1. 使用平台证书对应用程序进行签名。这需要以下步骤:
      • android:sharedUserId="android.uid.phone" 添加到您的 apk 清单的清单标记中。
      • android:process="com.android.phone" 添加到清单的应用程序标签中。
      • 您可能需要向清单添加一些额外的权限,并且还需要在项目的“Android Lint Preferences”中更改 ProtectedPermission 的严重性。
      • 从 {Android Source}/build/target/product/security 获取 platform.pk8 + platform.x509.pem(我在 https://android.googlesource.com/platform/build/+/android-4.4.4_r1/target/product/security/ 中使用了 4.4.4r1 的那些)
      • https://github.com/getfatday/keytool-importkeypair下载keytool-importkeypair
      • 使用此脚本通过以下命令获取平台的密钥库:keytool-importkeypair -k google_certificate.keystore -p android -pk8 platform.pk8 -cert platform.x509.pem -alias platform。我在 cygwin 上运行它,对脚本稍作修改。
      • 使用此密钥库为 apk 签名。
    2. 使用 adb 将应用程序安装为系统应用程序:

      adb 根

      adb 重新挂载

      adb push MyApp.apk /system/app

      adb shell chmod 644 /systen/app/MyApp.apk

    3. 重启设备。

    我实际上已经尝试了第二个项目符号中的解决方案,但它对我也不起作用(在运行 Kitkat 的 Galaxy S5 上)。 第三个项目中的解决方案确实工作得很好。无论包名称如何,应用都以 com.android.phone 的形式运行,因此如果要调试应用,则需要附加到该进程。

    【讨论】:

    • 好吧,使用 root 可以做很多事情。但是,我的一个关键要求是使用没有 root 访问权限的库存设备。无论如何,谢谢分享,也许有一天会有所帮助:)
    • 在 4.1 之前的 Android 版本中,您可以从应用程序中解析 logcat 输出以获取大多数呼叫事件。这确实是一个肮脏的解决方案,但可以在无根设备上运行。不幸的是,这在较新的 android 版本中是不可能的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多