首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在android Oreo中对传入的SMS运行服务

在android Oreo中对传入的SMS运行服务
EN

Stack Overflow用户
提问于 2017-10-01 19:10:49
回答 2查看 4.7K关注 0票数 6

我正在开发一个应用程序,需要运行一些代码(网络),无论何时收到短信。

在API25及更低版本中,我在清单文件中注册了一个隐式receiver,并在扩展了BroadcastReceiver的指定类中启动了我的服务。然而,在API26中,你不能在receiver中注册android.provider.Telephony.SMS_RECEIVED,因为它不能工作。

来自Android文档:

注意:如果您的应用程序针对API26级或更高级别,您不能使用清单来声明隐式广播(不是专门针对您的应用程序的广播)的接收器,除了少数不受该限制的隐式广播。在大多数情况下,您可以改用计划的作业。

我读过几篇像this one on medium这样的文章。有像JobSchedulerExplicit Receiver这样的解决方案,但是第一个用于网络状态的改变,我找不到在SMS_RECEIVED事件上触发作业的方法,第二个是有效的,直到您的activity启动并运行。

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

编辑

也许code in JobInfoBuilder doc on android website能帮上忙。它监视设备上照片的变化,并在变化时启动作业。然而,我找不到合适的Uri来对短信做同样的事情(甚至不确定是否可以通过ContentObserver监控短信)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-20 23:16:55

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

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

MainActivity.java

代码语言:javascript
复制
String action = "START"
final Intent intent = new Intent(this, CallMonitorService.class);
intent.setAction(action);
startService(intent);

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

代码语言:javascript
复制
    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()

代码语言:javascript
复制
    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);
    }

最后:

代码语言:javascript
复制
@Override
public void onDestroy() {
    super.onDestroy();
    unregisterReceiver(callExplicitReceiver);
}

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

票数 4
EN

Stack Overflow用户

发布于 2017-10-20 18:34:19

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46511807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档