【问题标题】:Launch activity by dialing a number通过拨号启动活动
【发布时间】:2015-11-18 21:56:10
【问题描述】:

我创建了一个合适的BoradcastReceiver,在Manifest.xml 中注册了它,这是我的问题:如果我的应用程序已经启动并挂在后台,那么拨打一个号码会将它带到前面。如果尚未启动,则拨打号码将无效。
我怎样才能解决这个问题?如果这很重要,我会在带有 MIUI6 的小米 Mi4 上进行测试。

这是代码(我使用 Scala):

manifest.xml:

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
...
<receiver android:name="DialerGate" android:enabled="true" android:exported="true">
            <intent-filter android:priority="1">
                <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
            </intent-filter>
        </receiver>

广播接收者:

class DialerGate extends BroadcastReceiver {
  def onReceive(context: Context, intent: Intent) =
    if (intent.getAction equals Intent.ACTION_NEW_OUTGOING_CALL) {
      val phoneno = intent.getExtras getString Intent.EXTRA_PHONE_NUMBER
      val prefs = context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
      val number = prefs.getString(AbstractKit.LAUNCH_NUMBER, null)

      Log.d("WALLET-PHONE", s"Dialed number: $phoneno, saved number: $number")
      Log.d("WALLET-PHONE-OK", (number == phoneno).toString)

      val i = new Intent
      i.setClassName("com.app.wallet", "com.app.wallet.MainActivity")
      i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP)

      val appContext = context.getApplicationContext
      appContext.startActivity(i)


      //if (number == phoneno) context startActivity new Intent(context, target)
      //context stopService intent
    }
}

【问题讨论】:

  • 你不能让你的应用在启动时运行吗? stackoverflow.com/questions/10428510/…
  • @JesterXiii,不,这根本不是我想要的。我的目标是启动一个拨打特定号码的应用程序。
  • @Anton 广播在 Manifest 中注册时的工作方式是,如果进程未运行,它们将被调用以唤醒进程。
  • 这可能会有所帮助 - stackoverflow.com/questions/17122085/…
  • 你的意思是,如果应用程序在后台它可以工作,如果不是它就不行?

标签: android broadcastreceiver


【解决方案1】:

从简单的用户角度来看,这是无法做到的(它是一项安全功能)。

从 HONEYCOMB 开始,Android 不允许调用任何广播接收器,直到应用程序至少运行一次。

让程序至少运行一次(在引导期间是最常见的一次)基本上更简单,然后如果不是时候使用它,就让意图关闭应用程序。

Check this for further details 了解如何实现额外的接收器,这些接收器可以做你需要做的事情。

【讨论】:

  • 嗯,这不是我遇到的问题,因为我在拨号前多次启动应用程序。
  • @Anton 只是一些细节......我没有使用def,而是更喜欢使用完整的@Override public void onReceive(Context c, Intent i){stuffs()} 版本,因为这样更容易跟踪程序更新......另外,你你的代码中充满了“错别字”......因为几乎没有;,并且没有对函数的函数调用val i = new Intent不是java......int i = new Intent();可能是
  • 很抱歉,我忘了提及我使用的是 Scala。我刚刚更新了帖子。
  • 推荐使用java。我对Scala一无所知。由于包括我在内的很多开发人员都使用 java,所以如果您使用 java,我们会更容易为您提供帮助。
  • @Anton 提供的帮助不仅仅是批评,所以我将您的代码修改为 java。 (有一些变化)它位于pastebin.com/f3ma6zQ7
【解决方案2】:

在您的广播接收器中创建一个侦听器并收听ON_BOOT_COMPLETED,然后以安静的心情启动您的应用程序,您将解决您的正常工作。

旁注如果以这种方式唤醒活动,那么创建键盘记录应用程序和黑客应用程序将非常非常非常便宜 - 因此会使 android 易受攻击。

【讨论】:

  • 换句话说,如果应用程序尚未挂在后台,则不启动应用程序的这种行为是设计使然?
【解决方案3】:

http://android-developers.blogspot.in/2013/05/handling-phone-call-requests-right-way.html

监听拨出电话请求

提供电话呼叫服务(例如 VOIP 或号码管理)的应用可以设置 Intent 过滤器来处理拨出呼叫请求,例如从拨号器或其他已安装应用发出的呼叫请求。这为用户提供了无缝集成,用户可以直接转换到呼叫服务,而无需重拨或启动另一个应用程序。

当用户发起呼叫时,系统会通过发送 NEW_OUTGOING_CALL Intent 的有序广播通知感兴趣的应用,并附加原始电话号码、URI 和其他信息作为附加信息。这使 Google Voice 等应用和其他应用有机会在呼叫传递到系统的默认电话应用之前修改、重新路由或取消呼叫。

如果您希望您的电话呼叫应用能够处理拨出呼叫请求,请实现接收 NEW_OUTGOING_CALL Intent、处理号码并根据需要发起呼叫的广播接收器。确保在接收器中为 NEW_OUTGOING_CALL 声明一个意图过滤器,以让系统知道您的应用程序对广播感兴趣。您还需要请求 PROCESS_OUTGOING_CALLS 权限才能接收 Intent。

请注意,系统仅为与核心拨号功能(例如紧急号码)无关的号码广播 NEW_OUTGOING_CALL。这意味着 NEW_OUTGOING_CALL 不会像您使用 CALL_PRIVILEGED 那样干扰对紧急服务的访问。

这是在应用清单文件中声明的示例广播接收器:

<manifest>
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />  
    <application>
        ...
        <receiver android:name=MyOutgoingCallHandler">
            <intent-filter>
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        ...
    </application>
</manifest>

我相信&lt;category android:name="android.intent.category.DEFAULT" /&gt; 会为您解决问题。也检查这个问题以获取有关类别标签的更多详细信息。here

【讨论】:

  • 遗憾的是添加类别标签根本没有效果。
  • 将优先级提高到2147483647
【解决方案4】:

你可以尝试一些东西。

尝试使用java,如果没有尝试以下。

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
...
<receiver android:name="DialerGate">
        <intent-filter android:priority="2147483648">
            <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
        </intent-filter>
    </receiver>

更改了优先级并删除了不必要的内容。

虽然我擅长广播接收器,但我没有使用 Scala 的经验,所以我只能提出一些想法。删除if 语句。它不是必需的,因为您已经有一个&lt;intent-filter&gt;。还要像粘贴 bin 代码一样更改意图。

【讨论】:

    【解决方案5】:

    看看here。 您可能会使用服务,但只关心一件事:当应用程序关闭时,服务也会关闭,因为它们在一个线程中,所以服务应该在另一个线程上以使其不被关闭 您可以使用 AlarmManager 使其保持活力。 在链接中也有一些示例:)

    希望对你有帮助!

    【讨论】:

    • 这是不正确的先生,服务不依赖于 Activity 生命周期,这意味着除非你明确地杀死它。
    【解决方案6】:

    应用程序可能没有“电话”的权限,要么在运行时请求权限,要么转到应用程序设置并启用应用程序请求的所有权限。
    这对我有用..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-05
      相关资源
      最近更新 更多