安卓通知不触发广播接收器的onReceive方法

12

如何通过通知启动广播接收器?

我尝试了以下代码但是它并没有起作用。

通知被创建出来了,但是当我点击它时什么也没有发生。

注意:当我将notificationIntent从MyBroadcastReceiver.class指向一个活动(比如MainActivity.class)时,它可以正常工作。

通知创建:

    NotificationManager notificationManager = (NotificationManager) context.getSystemService(
        Context.NOTIFICATION_SERVICE);

    int notificationIconId = XXXXXX
    Notification notification = new Notification(
        notificationIconId,
        XXXXXX,
        System.currentTimeMillis()
    );

    CharSequence contentTitle = XXXXXXX
    CharSequence contentText = XXXXXX

    Intent notificationIntent = new Intent(context,MyBroadcastReceiver.class);
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

    notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
    notificationManager.notify(1,notification);

这里是BroadcastReceiver。

public static class MyBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
   /*
          */

 }
}

在 AndroidManifest.xml 文件中

<receiver android:name=".MyBroadcastReceiver" />
1个回答

36

从你的代码看,你正在尝试在Python中使用os.system()来运行命令。但是,这种方法已经被认为是不安全和易受攻击的,因为它容易受到命令注入的攻击。相反,建议您使用subprocess模块来代替os.system()。例如,如果您想运行ls -l命令,您可以使用以下代码:

import subprocess
subprocess.call(["ls", "-l"])
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
创建一个针对 BroadcastReceiverPendingIntent 时,必须使用 getBroadcast(...) 而不是 getActivity(...)
请参阅:PendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int flags) 此外,不要像这样创建您的 Intent ...
Intent notificationIntent = new Intent(context,MyBroadcastReceiver.class);

这是一个明确的Intent,它针对特定的类(通常用于启动特定的Activity类)。

相反,创建一个带有“操作”(action)的“广播”Intent,如...

Intent notificationIntent = new Intent(MyApp.ACTION_DO_SOMETHING);

您还需要在清单文件中为 <receiver android:name=".MyBroadcastReceiver" /> 部分指定一个 <intent-filter> 部分。


1
@Abhishek:没问题。第一次使用通知时,我也犯了同样的错误,使用getActivity来获取一个PendingIntent,而实际上我想要启动一个Service(使用getService)。这是一个很好的教训。 :) - Squonk
3
@Abhishek,你忘记提到为notificationIntent设置类的setClass方法 notificationIntent.setClass(context, MyBroadcastReceiver.class); - AbdullahDiaa
5
请注意,这个答案的第二部分并不完全正确。对于在清单中注册的接收器而言,显式的Intent是完全可行且更受推荐的。实际上,从 API 级别 26 开始,针对该版本及以上版本应用程序,隐式Intent对于在清单中注册的接收器不再起作用,除了一些特定的系统广播。你仍然可以在Intent上设置一个动作来区分接收器内的不同广播,但你将不需要在<receiver>上使用<intent-filter> - Mike M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接