【问题标题】:Run service on incoming SMS in android Oreo在 android Oreo 中对传入的 SMS 运行服务
【发布时间】:2018-03-12 17:10:24
【问题描述】:

我正在开发一个应用程序,它需要在收到短信时运行一些代码(网络)。
在 API 25 及更低版本中很好,我在 Manifest 文件中注册了一个隐式 receiver 并在扩展 BroadcastReceiver 的指定类中启动我的服务。但是,在 API 26 中,您不能在 receiver 中注册 android.provider.Telephony.SMS_RECEIVED,因为它不起作用。

来自 Android 文档:

注意:如果您的应用以 API 级别 26 或更高级别为目标,则您不能使用清单为隐式广播(不专门针对您的应用的广播)声明接收器,但一些不受该限制的隐式广播除外.在大多数情况下,您可以改用计划作业。

我读过几篇文章,例如this one on medium。有JobSchedulerExplicit Receiver 之类的解决方案,但是第一个用于更改网络状态,我找不到在SMS_RECEIVED 事件上触发作业的方法,第二个在您的活动结束之前有效启动并运行。

由于我的应用程序的性质,无论应用程序是否正在运行,我都需要监听传入的 SMS。如何在 API 26+ 中做到这一点?

编辑

也许code in JobInfoBuilder doc on android website 会有所帮助。它监控设备上照片的变化并在变化时开始工作。但是我找不到合适的 Uri 对 SMS 做同样的事情(甚至不确定是否可以通过 ContentObserver 监控 SMS)

【问题讨论】:

  • 我认为具有定期检查方法的作业调度程序可能是正确的解决方案。
  • @VVB 我正在开发一个 TTS 应用程序,它应该在收到 SMS 时播放声音,但是似乎降低检测收到 SMS 的时间段对性能有不好的影响,而不是一个适当的解决方案。
  • SMS_RECEIVED 操作不受新的隐式广播限制的约束。 developer.android.com/guide/components/…
  • @MikeM。谢谢。我在这里犯了一个严重的错误,我什至在那个例外列表中搜索了“SMS”。但是,对于那些可以由setRequiredNetworkType method 直接触发的网络相关接收器以外的非例外接收器,有没有像ContentObserver(不确定)那样做与隐式接收器相同的工作?
  • 我不确定你在问什么。 setRequiredNetworkType() 方法设置必须存在哪个网络才能运行给定的作业。它本身不会触发任何工作。就ContentObservers 而言,如果您在API 级别21+ 上运行,则最好使用JobScheduler。无论哪种情况,SMS 的 URI 都是 content://sms,由于某种原因,您无法获得比 SMS Provider 更具体的信息。也就是说,您不能只观察收到的消息content://sms/inbox

标签: android broadcastreceiver receiver android-jobscheduler


【解决方案1】:

由于在 android O 中有很多方法可以完成这项工作,所以我发布了这个答案并提到了我解决问题的方法。显然,问题是指一般问题,而不是SMS_RECEIVED 接收器本身。

我启动了一个前台服务,并在其中注册了一个动态或显式接收器来监听来电(例如):

MainActivity.java:

String action = "START"
final Intent intent = new Intent(this, CallMonitorService.class);
intent.setAction(action);
startService(intent);

CallMonitorService.javas onCreate() 方法中,我将BroadcastReceiver callExplicitReceiver 作为字段:

    final IntentFilter intentFilter = new IntentFilter();
    intentFilter.setPriority(2147483647);
    intentFilter.addAction("android.intent.action.PHONE_STATE");
    this.callExplicitReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
                // do the stuff here
            }
        }
    };
    registerReceiver(callExplicitReceiver, intentFilter);

然后在onStartCommand():

    if (intent.getAction().equals("START")) {
        Intent callServiceNotificationIntent = new Intent(this, MainActivity.class);
        callServiceNotificationIntent.setFlags(
            Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent
            .getActivity(this, CALL_SERVICE_REQUEST_CODE,
                    callServiceNotificationIntent, CALL_SERVICE_FLAG);

        Notification notification = new NotificationCompat.Builder(this)
            .setContentTitle(CALL_NOTIFICATION_CONTENT_TITLE)
            .setTicker(CALL_NOTIFICATION_TICKER)
            .setContentText(CALL_NOTIFICATION_CONTENT_TEXT)
            .setSmallIcon(R.drawable.ic_info_outline_black_24dp)
            .setContentIntent(pendingIntent)
            .setOngoing(true)
            .build();
        startForeground(CALL_NOTIFICATION_ID, notification);
    }

最后:

@Override
public void onDestroy() {
    super.onDestroy();
    unregisterReceiver(callExplicitReceiver);
}

我认为这是一种很好的方法,因为由于不可关闭的通知,用户会收到正在运行的服务的通知,这就是 android Oreo 想要的,但是通过应用程序中的按钮,用户可以停止服务和监控接收器作为破坏服务的直接结果(我清除了那部分代码)。

【讨论】:

  • 我在我的应用程序中做了同样的事情 - 有些人对通知栏中的图标感到困惑(默认情况下它在 8.0 上,而不是在 8.1 上),因为它是前台服务。就个人而言,如果有 10 个这样的通知,我会很生气。所以不确定谷歌是否考虑过。我曾抱怨某些电话号码在 8.0.0 上根本没有触发广播接收器。你看到了吗?
  • 我知道该服务当时处于活动状态,因为我添加了带有日志的错误报告功能,并且没有消息表明服务已重新启动。
  • @szmani20 现在还是唯一的解决方案吗?
【解决方案2】:

我认为现在你是安全的,因为SMS_RECEIVED_ACTION 出现在当前豁免的隐式广播list 中。此外,在收到系统广播后,您可以启动前台服务或安排作业(在您的情况下执行网络操作)。此外,我也在使用相同的操作,经过测试,它似乎可以正常工作。

【讨论】:

  • 感谢您的回答。我还需要一些不在该列表中的其他接收器。我的方法是启动前台服务并以编程方式在其中注册一个动态(显式)接收器,并在启动时重新启动服务。我将发布我的方法作为答案。
猜你喜欢
  • 2019-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多