如何在设备启动时实现广播接收器?

问题描述 投票:0回答:1

我有一个简单的应用,可以在按下按钮5分钟后安排通知。这对我来说可以。但是,如果我在5分钟内重新启动手机,则不会收到通知。我已经对设备重新启动时的警报管理器和计划通知进行了研究。我的应用程序中有5个课程。

它们是:

  • MainActivity.class
  • NotificationUtil.class
  • NotificationPublisher.class
  • NotificationView.class
  • DeviceBootReceiver.class

我有2个类可以扩展BroadCast接收器。它们是:

  • NotificationPublisher.class
  • DeviceBootReceiver.class

通过研究和其他堆栈溢出问题,我了解到,为了在设备重启后接收通知,我应该创建一个扩展BroadCast Receiver的类。每当电话启动时,它将运行onReceive()方法中的任何代码。

这是我的MainActivity.class

public class MainActivity extends AppCompatActivity {
    private Button button;
    private Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = findViewById(R.id.notification);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NotificationUtil.createNotification(MainActivity.this,NotificationView.class,"Notification","You have a new Task");
            }
        });
    }
}

这是我的NotificationUtil.class。这是处理所有通知的类,这是我在MainActivity中的Button Click上调用的类。

public class NotificationUtil
{
    public static void createNotification(Context context,Class<?> cls, String title, String content)
    {
        Intent intent = new Intent(context,cls);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

        sendNotification(getNotification(pendingIntent,context,title,content),context);
    }

    private static void sendNotification(Notification notification,Context context)
    {
        Intent notificationIntent = new Intent(context, NotificationPublisher.class);
        Intent deviceBootIntent = new Intent(context,DeviceBootReceiver.class);

        notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID,1);
        notificationIntent.putExtra(NotificationPublisher.NOTIFICATION,notification);

        deviceBootIntent.putExtra(DeviceBootReceiver.NOTIFICATION_ID, 1);
        deviceBootIntent.putExtra(DeviceBootReceiver.NOTIFICATION, notification);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000,pendingIntent);
    }

    private static Notification getNotification(PendingIntent pendingIntent, Context context, String title, String content)
    {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context,"ChannelID");
        builder.setSmallIcon(R.drawable.notification_bell);
        builder.setContentTitle(title);
        builder.setContentText("You have a Notification");
        builder.setSubText("Tap To View");
        builder.setStyle(new NotificationCompat.BigTextStyle().bigText(content));
        builder.setContentIntent(pendingIntent);
        return builder.build();
    }
}

这是我的NotificationPublisher.class。这是负责发送通知的类。

public class NotificationPublisher extends BroadcastReceiver {

    public static String NOTIFICATION_ID = "notification_id";
    public static String NOTIFICATION = "notification";

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

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

        Notification notification = intent.getParcelableExtra(NOTIFICATION);
        int notificationId = intent.getIntExtra(NOTIFICATION_ID, 1);
        notificationManager.notify(notificationId, notification);
    }
}

这是我的DeviceBootReceiver.class。我正在尝试在此处实现我的代码,以便在设备重启后接收通知。

public class DeviceBootReceiver extends BroadcastReceiver {

    public static String NOTIFICATION_ID = "notification_id";
    public static String NOTIFICATION = "notification";

    public void onReceive(Context context, Intent intent)
    {
        if(Objects.requireNonNull(intent.getAction()).equalsIgnoreCase("android.intent.action.BOOT_COMPLETED"))
        {
            Notification notification = intent.getParcelableExtra(NOTIFICATION);
            int notificationID = intent.getIntExtra(NOTIFICATION_ID,1);

            NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(notificationID, notification);
        }
    }
}

重新启动手机后,我收到消息“应用程序已停止工作”。我不确定我要去哪里哪里。

这是我的清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.notificationtest">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".NotificationView"
            android:parentActivityName=".MainActivity"/>

        <receiver android:name=".NotificationPublisher"/>


        <receiver android:name=".DeviceBootReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.ACTION_BOOT_COMPLETED" />
                <action android:name="android.intent.action.REBOOT" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
                <action android:name="android.intent.action.ACTION_SHUTDOWN" />
            </intent-filter>
        </receiver>


    </application>

</manifest>

据我了解,扩展BroadCast Receivers的类在设备重新启动时被调用。所以我尝试使用notification

将我的notificationIDIntent.putExtra从NotificationUtil.class传递到DeviceBootReceiver.class这样
Intent deviceBootIntent = new Intent(context,DeviceBootReceiver.class);
deviceBootIntent.putExtra(DeviceBootReceiver.NOTIFICATION_ID, 1);
deviceBootIntent.putExtra(DeviceBootReceiver.NOTIFICATION, notification);

然后在onReceive方法下的DeviceBootReceiver.class中,我使用getExtra获取值。我进一步将获得的2个值传递给NotificationPublisher.class。

此“ WAS”是我对DeviceBootReceiver.class的较早实现。由于此操作无效,因此我尝试了如上所述的新实现。

public class DeviceBootReceiver extends BroadcastReceiver {

    public static String NOTIFICATION_ID = "notification_id";
    public static String NOTIFICATION = "notification";

    public void onReceive(Context context, Intent intent)
    {
        if(Objects.requireNonNull(intent.getAction()).equals("android.intent.action.BOOT_COMPLETED"))
        {
            Intent pushIntent = new Intent(context, NotificationPublisher.class);

            Notification notification = intent.getParcelableExtra(NOTIFICATION);
            int notificationID = intent.getIntExtra(NOTIFICATION_ID,1);

            pushIntent.putExtra(NotificationPublisher.NOTIFICATION_ID,notificationID);
            pushIntent.putExtra(NotificationPublisher.NOTIFICATION,notification);

            PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,pushIntent,PendingIntent.FLAG_UPDATE_CURRENT);

            AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
            alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000,pendingIntent);
        }

    }
}

我所期望的是,由于DeviceBootReceiver.class在启动时被调用,因此这2个值将被发送到我的NotificationPublisher.class,我将在启动时得到通知。取而代之的是,应用程序由于onReceive方法中的新旧实现而崩溃。

具有在设备重启时接收通知的经验的人可以帮助我吗?请仔细阅读我的代码,并尝试在您的项目中实现它,以了解我的工作。我已经在此问题中上传了所有代码。

android notifications broadcastreceiver alarmmanager
1个回答
0
投票

Implicit Broadcast Exceptions

作为Android 8.0(API级别26)后台执行限制的一部分,面向API级别26或更高级别的应用程序无法再在其清单中为隐式广播注册广播接收器。但是,一些广播目前不受这些限制。无论应用程序所针对的API级别如何,应用程序都可以继续为以下广播注册侦听器。

即使这些隐式广播仍在后台运行,您应该避免为他们注册监听器。

© www.soinside.com 2019 - 2024. All rights reserved.