android - 如何创建即使在手机重启后也始终运行的通知?

标签 android firebase-realtime-database notifications broadcastreceiver bootcompleted

我在方法 中设置了警报管理器MainActivity 的 setAlarm() 包含来自 firebase 数据库的日期并根据该日期设置警报。当我尝试运行它时,这非常好。但是当我尝试在闹钟响起之前重启手机时,什么都没有发生。

我还尝试创建一个引用服务的接收器。从这项服务 onHandleIntent( Intent Intent ) , 我调用 MainActivity.setAlarm() .我还在 android manifest 添加了一个权限启动完成。之后,我尝试重新启动我的手机,当我的手机 启动完成,应用强制关闭 .我认为它停止了,因为我在 Activity 类中调用了一个方法。

这是我的报警接收器

public class AlarmReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
    Intent notificationIntent = new Intent(context, BabyListActivity.class);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addParentStack(BabyListActivity.class);
    stackBuilder.addNextIntent(notificationIntent);

    PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(context);

    Notification notification1 = builder.setContentTitle("1")
            .setContentText("New Notification From Demo App..")
            .setTicker("New Message Alert!")
            .setSmallIcon(R.mipmap.ic_launcher_round)
            .setContentIntent(pendingIntent).build();

    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(0, notification1);
}

这是我的 startAlarm() 方法
public static void startAlarm(Context context){
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    Intent notificationIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
    notificationIntent.addCategory("android.intent.category.DEFAULT");

    PendingIntent broadcast = PendingIntent.getBroadcast(context, 100, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, 2017);
    cal.set(Calendar.MONTH, 8-1);
    cal.set(Calendar.DAY_OF_MONTH, 10);
    cal.set(Calendar.HOUR_OF_DAY, 10);
    cal.set(Calendar.MINUTE, 15);
    cal.set(Calendar.SECOND, 4);

    alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), broadcast);
}

这是我的 BootAlarmReceiver
public class BootAlarmReceiver extends BroadcastReceiver {

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

    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {

        // It is better to reset alarms using Background IntentService
        Intent i = new Intent(context, BootService.class);
        ComponentName service = context.startService(i);

        if (null == service) {
            // something really wrong here
            Log.e(TAG, "Could not start service ");
        }
        else {
            Log.e(TAG, "Successfully started service ");
        }

    } else {
        Log.e(TAG, "Received unexpected intent " + intent.toString());
    }
}

这是我的开机服务
public class BootService extends Service {


public BootService() {
    super("BootService");
}

@Override
public void onCreate() {
    MainActivity.startAlarm(this);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_NOT_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

}

这是我的安卓 list
<receiver android:name=".AlarmReceiver">
        <intent-filter>
            <action android:name="android.media.action.DISPLAY_NOTIFICATION"></action>
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

    <service android:name=".BootService"/>

    <receiver android:name=".BootAlarmReceiver" android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

有人可以告诉我如何解决这个问题吗?谢谢...

最佳答案

我认为至少有两个错误。首先,你永远不会新建一个 Activity 类,它应该由 android 框架管理,如果你只是想调用其中的一些方法,你最好将方法提取到一个实用程序类中,或者只是将方法更改为静态,这不是推荐的。其次,onHandleIntent方法将在后台线程中运行,您不能调用应该在主线程中运行的方法。

所以在我看来,为了测试,你可以把 startAlarm() MainActivity 静态和 BootService 中的方法扩展 Service 而不是 IntentService ,进行这些更改,然后重试。

像这样更改 setAlarm() 方法:

public static void startAlarm(Context context){
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    Intent notificationIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
    notificationIntent.addCategory("android.intent.category.DEFAULT");

    PendingIntent broadcast = PendingIntent.getBroadcast(context, 100, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, 2017);
    cal.set(Calendar.MONTH, 8-1);
    cal.set(Calendar.DAY_OF_MONTH, 10);
    cal.set(Calendar.HOUR_OF_DAY, 11);
    cal.set(Calendar.MINUTE, 40);
    cal.set(Calendar.SECOND, 00);

    alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), broadcast);
}

像这样更改您的 BootAlarmReceiver:
public class BootService extends Service {


    @Override
    public void onCreate() {
        MainActivity.startAlarm(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

再试一次!

关于android - 如何创建即使在手机重启后也始终运行的通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45604752/

相关文章:

c# - 在许多 Activity 中使用静态类?

java - 如何在android studio中使用MVVM+Databinding设计登录?

java - 为什么字符串不能转换为对象类

ios - 如何在我的 IN 应用程序在后台运行时发出提醒

android - 如何创建支持旧 API 级别(例如 23 级)的 Android 通知

android - Android CoordinatorLayout下FloatingActionButton不跳起来

android - 为什么我的应用程序在启动时崩溃 (Android Studio)

swift - Firebase - Swift - 从快照中删除子 UID

java - 这是否可能只显示实时 Firebase 数据库的某些特定子值的 ListView

android - 如何从服务中获取值(value)到android中的 Activity ?