当前位置: 首页 > 知识库问答 >
问题:

通知在错误的时间发出(Java、Android Studio)

钮承恩
2023-03-14

在我的应用程序中,用户可以选择一个时间和日期,当通知将被发送。然而,通知没有在正确的时间发出。如果我选择一个通知在同一天发出,它将在第二天的随机时间发出。如果我选择一个通知在未来的某一天发出,它将在一个那天的随机时间。因此,总的来说,它似乎忽略了时间,并根据日期发送通知,但当我选择当前日期的通知时,它甚至无法正确确定日期。

当用户只能选择时间时,代码运行良好。在我添加了选择通知日期的功能后,它崩溃了。

MeelDetuletusActivity.java

public class MeeldetuletusActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener, DatePickerDialog.OnDateSetListener {
    String timeText;
    TextView textTime;
    Button nupp_vali, nupp_katkesta, nupp_kuupaev, nupp_alarm;
    Calendar c;



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

        nupp_vali = findViewById(R.id.button2);
        nupp_katkesta = findViewById(R.id.nupp_katkesta);
        nupp_kuupaev = findViewById(R.id.button);
        nupp_alarm = findViewById(R.id.button3);

        nupp_alarm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startAlarm(c);


            }
        });

        nupp_vali.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment timePicker = new TimePickerFragment();
                timePicker.show(getSupportFragmentManager(), "time picker");

            }
        });

        nupp_kuupaev.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment kuupaevaValija = new KuupaevaFragment();
                kuupaevaValija.show(getSupportFragmentManager(), "date picker");
            }
        });

        nupp_katkesta.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                katkestaAlarm();
                Toast.makeText(MeeldetuletusActivity.this, "Meeldetuletus unustatud", Toast.LENGTH_SHORT).show();

            }
        });




    }


    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, hourOfDay);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, 0);
    }


    public void onDateSet (DatePicker view, int aasta, int kuu, int paev) {
        c = Calendar.getInstance();
        c.set(Calendar.YEAR, aasta);
        c.set(Calendar.MONTH, kuu);
        c.set(Calendar.DAY_OF_MONTH, paev);
    }



    private void startAlarm(Calendar c) {
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(this, NotificationPublisher.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
        if (c.before(Calendar.getInstance())) {
            c.add(Calendar.DATE, 1);
        }
        Objects.requireNonNull(alarmManager).setExact(AlarmManager.RTC_WAKEUP,
                c.getTimeInMillis(), pendingIntent);
    }

    private void katkestaAlarm() {
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent myIntent = new Intent(getApplicationContext(), NotificationPublisher.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                getApplicationContext(), 1, myIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        alarmManager.cancel(pendingIntent);
    }
}

KuupaevaFragment.java

public class KuupaevaFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar c = Calendar.getInstance();
        int aasta = c.get(Calendar.YEAR);
        int kuu = c.get(Calendar.MONTH);
        int paev = c.get(Calendar.DAY_OF_MONTH);
        return new DatePickerDialog(getActivity(), (DatePickerDialog.OnDateSetListener) getActivity(),
                aasta, kuu, paev);


    }


}

TimePickerFragment.java

public class TimePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);
        return new TimePickerDialog(getActivity(), (TimePickerDialog.OnTimeSetListener) getActivity(),
                hour, minute, DateFormat.is24HourFormat(getActivity()));


    }


}

NotificationPublisher。java

public class NotificationPublisher extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationHelper notificationHelper = new NotificationHelper(context);
        NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
        notificationHelper.getManager().notify(1, nb.build());
        Notification notification = nb.build();
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        notification.defaults |= Notification.DEFAULT_SOUND;
    }
}

NotificationHelper.java

class NotificationHelper extends ContextWrapper {
    public static final String channelID = "channelID";
    public static final String channelName = "Channel Name";
    private NotificationManager notificationManager;
    public NotificationHelper(Context base) {
        super(base);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createChannel();
        }
    }
    @TargetApi(Build.VERSION_CODES.O)
    private void createChannel() {
        NotificationChannel channel = new NotificationChannel(channelID, channelName,
                NotificationManager.IMPORTANCE_HIGH);
        getManager().createNotificationChannel(channel);
    }
    public NotificationManager getManager() {
        if (notificationManager == null) {
            notificationManager = (NotificationManager)
                    getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return notificationManager;
    }
    public NotificationCompat.Builder getChannelNotification() {
        return new NotificationCompat.Builder(getApplicationContext(), channelID)
                .setContentTitle("Meeldetuletus")
                .setContentText("Teie valitud aeg on käes")
                .setSmallIcon(R.drawable.ic_baseline_notifications_active_24);
    }
}

共有1个答案

松刚豪
2023-03-14

这种情况很可能发生,因为在onTimeSetontateset回调方法中,您正在初始化c变量,该变量应该表示应该触发警报的日期,因此每当您设置新的日期或时间时,c变量就会丢失以前的值设置数据:

java prettyprint-override">@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
    c = Calendar.getInstance(); // This code is causing the trouble
    c.set(Calendar.HOUR_OF_DAY, hourOfDay);
    c.set(Calendar.MINUTE, minute);
    c.set(Calendar.SECOND, 0);
}

public void onDateSet (DatePicker view, int aasta, int kuu, int paev) {
    c = Calendar.getInstance(); // This code is also causing the trouble
    c.set(Calendar.YEAR, aasta);
    c.set(Calendar.MONTH, kuu);
    c.set(Calendar.DAY_OF_MONTH, paev);
}

现在,简单的解决方案是在onCreate生命周期方法中初始化c

Calendar c;

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

        c = Calendar.getInstance() // Initialize 'c' here!

        ...
}

并删除回调方法中的冗余初始化:

@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
    c.set(Calendar.HOUR_OF_DAY, hourOfDay);
    c.set(Calendar.MINUTE, minute);
    c.set(Calendar.SECOND, 0);
}

public void onDateSet (DatePicker view, int aasta, int kuu, int paev) {
    c.set(Calendar.YEAR, aasta);
    c.set(Calendar.MONTH, kuu);
    c.set(Calendar.DAY_OF_MONTH, paev);
}

现在,无论何时调用startAlarm(c)方法,它都将使用从onDateSetonTimeSet或仅从其中一个方法设置的数据——基本上,这些方法中所做的更改不会被这些方法本身的c变量的冗余重新初始化所覆盖。

 类似资料: