java - 如何在给定的时间段内显示通知中的字符串列表?

标签 java android android-notifications alarmmanager

我想在指定时间显示通知。就像我有一个开始时间,从我想查看通知和结束时间到我想查看通知,即应该在给定时间段中显示的字符串列表。

该列表也可以是用户指定的任何数量。

如何决定动态显示通知的时间?或者如何统一划分时隙和字符串?

此处的更多说明是显示开始时间、结束时间和通知中显示的字符串计数的屏幕:

enter image description here

请帮忙。谢谢...

编辑 :

我正在尝试给定的解决方案。

 List<String> times = new ArrayList<>();
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
            Date start = dateFormat.parse(startTime);
            Date end = dateFormat.parse(endTime);
            long minutes = ((end.getTime() - start.getTime()) / 1000 / 60) /
                    howMany;
            for (int i = 0; i < howMany; i++) {

                Calendar calobj = Calendar.getInstance();
                calobj.setTime(start);
                calobj.add(Calendar.MINUTE, (int) (i * minutes));
                String time = dateFormat.format(calobj.getTime());
                times.add(time);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.d("timesList", times.toString());
        return times;
    }

    public static void showNotification(
            List<String> timeList, Context context,
            String quote
    ) {

        Intent notifyIntent = new Intent(context, MyNewIntentReceiver.class);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
                notifyIntent, PendingIntent.FLAG_ONE_SHOT
        );

        notifyIntent.putExtra("title", context.getString(R.string.app_name));

        AlarmManager alarmManager = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);

        for (String time : timeList) {
            final int random = new Random().nextInt();
            notifyIntent.putExtra("notify_id", random);

            notifyIntent.putExtra(
                    "quote",
                    quote
            );
            Date date;
            SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
            try {
              date = dateFormat.parse(time);
                System.out.println(date);

            alarmManager
                    .setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                            date.getTime(),
                            date.getTime(),
                            pendingIntent
                    );

            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        Log.d("notificationIntentSet", "Utils, pending intent set");
    }

在我的接收器中构建通知。
  public class MyNewIntentReceiver extends BroadcastReceiver {

    public MyNewIntentReceiver() {
    }


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

        PowerManager powerManager = (PowerManager) context.getSystemService(
                Context.POWER_SERVICE);
        PowerManager.WakeLock wakeLock =
                powerManager.newWakeLock(
                        PowerManager.PARTIAL_WAKE_LOCK,
                        "dailyfaith:wakelog"
                );
        wakeLock.acquire();

        // get id, titleText and bigText from intent
        int NOTIFY_ID = intent.getIntExtra("notify_id", 0);
        String titleText = intent.getStringExtra("title");
        String bigText = intent.getStringExtra("quote");

        // Create intent.
        Intent notificationIntent = new Intent(context, MainActivity.class);

        // use NOTIFY_ID as requestCode
        PendingIntent contentIntent = PendingIntent.getActivity(context,
                NOTIFY_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT
        );

        // get res.
        Resources res = context.getResources();

        // build notification.
        Notification.Builder builder = new Notification.Builder(context)
                .setContentIntent(contentIntent)
                .setSmallIcon(R.drawable.ic_daily_faith_icon)
                .setAutoCancel(true)
                .setContentTitle(titleText)
                .setSound(RingtoneManager
                        .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                .setContentText(bigText);

        Log.d("notificationBuild", "Notification Builder set");

    /*    // check vibration.
        if (mPrefs.getBoolean("vibration", true)) {
            builder.setVibrate(new long[]{0, 50});
        }*/

   /*     // create default title if empty.
        if (titleText.equals("")) {
            builder.setContentTitle(
                    context.getString(R.string.app_name));
        }*/

        // show notification. check for delay.
        builder.setWhen(System.currentTimeMillis());
        Log.d("notificationSetWhen", "Notification set when triggered");

        Notification notification = new Notification.BigTextStyle(builder)
                .bigText(bigText).build();

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

        wakeLock.release();
    }
}

从 Activity :
  @Override
    public void onTimeSet(
            TimePickerDialog view, int hourOfDay, int minute, int second
    ) {
        String hourString = hourOfDay < 10 ? "0" + hourOfDay : "" + hourOfDay;
        String minuteString = minute < 10 ? "0" + minute : ":" + minute;
        String time = hourString + minuteString;

        if (startTimeSelected) {
            startTime = time;
            textViewStartTime.setText(time);
        }
        else if (endTimeSelected) {
            endTime = time;
            textViewEndTime.setText(time);
        }

        String count = (String) textViewQuoteCount.getText();
        count.replace("X","");

        if(startTimeSelected && endTimeSelected)
        {
            Utils.setAlarmTimeList(startTime, endTime, Integer.parseInt(count));
            Utils.showNotification(timeList); // not sure how to send the list of strings - quotes
        }

        tpd = null;
    }

我将时间数组传递给待处理的 Intent ,但没有触发通知。我想为了报警,我还需要给出当前日期,所以我再次为每个通知格式化时间。

但这也没有用。有什么建议么?

编辑 :

我已经更新了欧文的答案。我现在也得到了日期,但仍然在我调试接收器时也没有被调用。

我在 list 文件中设置了接收器:
<receiver
    android:name = ".MyNewIntentReceiver"
    android:enabled = "true"
    android:exported = "false" />

时间列表的日志
  D/timesList: [Tue May 19 16:21:00 GMT+05:30 2020, Tue May 19 16:24:00 GMT+05:30 2020, Tue May 19 16:27:00 GMT+05:30 2020, Tue May 19 16:30:00 GMT+05:30 2020, Tue May 19 16:33:00 GMT+05:30 2020, Tue May 19 16:36:00 GMT+05:30 2020, Tue May 19 16:39:00 GMT+05:30 2020, Tue May 19 16:42:00 GMT+05:30 2020, Tue May 19 16:45:00 GMT+05:30 2020, Tue May 19 16:48:00 GMT+05:30 2020]

可能是什么问题:

我试图将当前时间赋予未决 Intent :
 alarmManager
                .setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                        System.currentTimeMillis(),
                        System.currentTimeMillis(),
                        pendingIntent
                );

然后我收到了通知。但是当我设置日期时没有得到。

编辑 2
   public static List<Date> setAlarmTimeList(String startTime, String endTime, int howMany) {
        List<Date> times = new ArrayList<>();
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
            Date start = dateFormat.parse(startTime);
            Date end = dateFormat.parse(endTime);
            long minutes = ((end.getTime() - start.getTime()) / 1000 / 60) /
                    (howMany - 1);
            Calendar calobj;
            for (int i = 0; i < howMany; i++) {

                calobj = Calendar.getInstance();
                calobj.set(Calendar.HOUR_OF_DAY, Integer.valueOf(dateFormat.format(start).split(":")[0]));
                calobj.set(Calendar.MINUTE, Integer.valueOf(dateFormat.format(start).split(":")[1]));
                calobj.add(Calendar.MINUTE, (int) (i * minutes));
                calobj.set(Calendar.SECOND, 0);
                times.add(calobj.getTime());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.d("timesList", times.toString());
        return times;
    }


    public static void showNotification(
            List<Date> timeList, Context context,
            String quote
    ) {

        for (Date date : timeList) {
            Intent notifyIntent = new Intent(context, MyNewIntentReceiver.class);

            notifyIntent.putExtra("title", context.getString(R.string.app_name));

            final int random = new Random().nextInt();
            notifyIntent.putExtra("notify_id", random);

            notifyIntent.putExtra(
                    "quote",
                    quote
            );
            int randomInt = new Random().nextInt(1000);

            notifyIntent.putExtra("requestCode",randomInt);

            PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                    randomInt,
                    notifyIntent, PendingIntent.FLAG_ONE_SHOT

            );

            AlarmManager alarmManager = (AlarmManager) context
                    .getSystemService(Context.ALARM_SERVICE);


            Log.d("date",String.valueOf(date.getTime()));

         /*   long afterTwoMinutes = SystemClock.elapsedRealtime() + 60 * 1000;*/
            long afterTwoMinutes = System.currentTimeMillis();

            Log.d("aftertwoMinutes",String.valueOf(afterTwoMinutes));

            long datetimer = date.getTime();

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                alarmManager.setExactAndAllowWhileIdle
                        (AlarmManager.ELAPSED_REALTIME_WAKEUP,
                               date.getTime(), pendingIntent);
            else
                alarmManager.setExact
                        (AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                date.getTime(), pendingIntent);
        }

        Log.d("notificationIntentSet", "Utils, pending intent set");
    }


public class MyNewIntentReceiver extends BroadcastReceiver {

    public MyNewIntentReceiver() {
    }


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

        int NOTIFY_ID = intent.getIntExtra("notify_id", 0);
        String titleText = intent.getStringExtra("title");
        String bigText = intent.getStringExtra("quote");
        int requestCode = intent.getIntExtra("requestCode",0);
        sendNotification(context,bigText,NOTIFY_ID,requestCode);
    }

    private void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library

    }

    public static void sendNotification(Context mcontext, String messageBody,
            int notify_id,int requestCode) {
        Intent intent = new Intent(mcontext, HomeScreenActivity.class);
        PendingIntent pendingIntent = PendingIntent
                .getActivity(mcontext, requestCode /* Request code */, intent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
        NotificationManager notificationManager = (NotificationManager) mcontext
                .getSystemService(Context.NOTIFICATION_SERVICE);

        Uri defaultSoundUri = RingtoneManager
                .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel
                    (
                            mcontext.getString(R.string.default_notification_channel_id),
                            "Rewards Notifications",
                            NotificationManager.IMPORTANCE_HIGH
                    );

            // Configure the notification channel.
            notificationChannel.setDescription("Channel description");
            notificationChannel.enableLights(true);
            notificationManager.createNotificationChannel(notificationChannel);
        }

        NotificationCompat.Builder notificationBuilder = new NotificationCompat
                .Builder(mcontext, mcontext.getString(R.string.default_notification_channel_id))
                .setContentTitle(mcontext.getString(R.string.app_name))
                .setSmallIcon(R.drawable.ic_daily_faith_icon)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);


        notificationManager.notify(notify_id /* ID of notification */,
                notificationBuilder.build());
    }
}

不适用于 date.getTime(),System.currentTimeInMilliseconds() 适用于 SystemClock

最佳答案

尝试这个,

    public static List<Date> setAlarmTimeList(String startTime, String endTime, int howMany) {
    List<Date> times = new ArrayList<>();
    try {
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
        Date start = dateFormat.parse(startTime);
        Date end = dateFormat.parse(endTime);
        long minutes = ((end.getTime() - start.getTime()) / 1000 / 60) /
                (howMany - 1);
        Calendar calobj;
        for (int i = 0; i < howMany; i++) {

            calobj = Calendar.getInstance();
            calobj.set(Calendar.HOUR_OF_DAY, Integer.valueOf(dateFormat.format(start).split(":")[0]));
            calobj.set(Calendar.MINUTE, Integer.valueOf(dateFormat.format(start).split(":")[1]));
            calobj.add(Calendar.MINUTE, (int) (i * minutes));
            calobj.set(Calendar.SECOND, 0);
            times.add(calobj.getTime());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    Log.d("timesList", times.toString());
    return times;
}

以毫秒为单位获取开始时间和结束时间,然后将其除以多少次。

对于警报管理器,
public static void showNotification(List<Date> timeList, Context context, String quote) {

        Intent notifyIntent = new Intent(context, MyNewIntentReceiver.class);

        notifyIntent.putExtra("title", context.getString(R.string.app_name));

        AlarmManager alarmManager = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);

        for (Date time : timeList) {
            final int random = new Random().nextInt();
            notifyIntent.putExtra("notify_id", random);

            notifyIntent.putExtra(
                    "quote",
                    quote
            );

            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, random,
                    notifyIntent, PendingIntent.FLAG_ONE_SHOT
            );

            alarmManager
                    .setInexactRepeating(AlarmManager.RTC_WAKEUP,
                            time.getTime(),
                            AlarmManager.INTERVAL_DAY,
                            pendingIntent
                    );
        }

        Log.d("notificationIntentSet", "Utils, pending intent set");
    }

关于java - 如何在给定的时间段内显示通知中的字符串列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61663018/

相关文章:

java - 如何从Windows连接远程Q管理器(在docker上)?

java - Applet(或 WebStart 应用程序)调用服务器 : best practices?

java - 将 LinkedList 保存到文件并将 List 加载回程序

android - 从非 Activity 中完成 Activity

android - 如何获取Android中所有应用程序收到的通知数

java - 从 wsdl 创建 Web 服务

java - 如何从异常跟踪堆栈中判断连接超时和套接字超时?

android - 如何重新启动 MAIN Activity

Android:在特定时间触发 Notification.Builder

android - 服务被系统自动杀死时取消Android通知