Notyfikacja raz dziennie o określonej godzinie

0

Cześć. Mam pytanie, ze względu na fakt, że Android wprowadził ostatnio sporo zmian jeśli chodzi o notyfikacje, większość tutoriali rozwiązujących mój problem nie działa. Chodzi o notyfikację, którą użytkownik otrzymywałby raz dziennie o określonej godzinie, np codziennie o 20:00.

Znalazłem kod programistów Google, jednak oni włączają notyfikację poprzez naciśnięcie przycisku, nigdzie nie tłumaczą jak to zrobić, by notyfikacja odpalała się o określonej godzinie

MainActivity

package com.android.fundamentals.standup;

import android.app.AlarmManager;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.widget.CompoundButton;
import android.widget.Toast;
import android.widget.ToggleButton;


/**
 * MainActivity for the Stand up! app. Contains a toggle button that
 * sets an alarm which delivers a Stand up notification every 15 minutes.
 */
public class MainActivity extends AppCompatActivity {

    // Notification ID.
    private static final int NOTIFICATION_ID = 0;
    // Notification channel ID.
    private static final String PRIMARY_CHANNEL_ID =
            "primary_notification_channel";
    private NotificationManager mNotificationManager;

    /**
     * Initializes the activity.
     *
     * @param savedInstanceState The current state data.
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNotificationManager = (NotificationManager)
                getSystemService(NOTIFICATION_SERVICE);

        ToggleButton alarmToggle = findViewById(R.id.alarmToggle);

        // Set up the Notification Broadcast Intent.
        Intent notifyIntent = new Intent(this, AlarmReceiver.class);

        boolean alarmUp = (PendingIntent.getBroadcast(this, NOTIFICATION_ID,
                notifyIntent, PendingIntent.FLAG_NO_CREATE) != null);
        alarmToggle.setChecked(alarmUp);

        final PendingIntent notifyPendingIntent = PendingIntent.getBroadcast
                (this, NOTIFICATION_ID, notifyIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT);

        final AlarmManager alarmManager = (AlarmManager) getSystemService
                (ALARM_SERVICE);

        // Set the click listener for the toggle button.
        alarmToggle.setOnCheckedChangeListener
                (new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged
                            (CompoundButton buttonView, boolean isChecked) {
                        String toastMessage;
                        if (isChecked) {

                            long repeatInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;

                            long triggerTime = SystemClock.elapsedRealtime()
                                    + repeatInterval;

                            // If the Toggle is turned on, set the repeating alarm with
                            // a 15 minute interval.
                            if (alarmManager != null) {
                                alarmManager.setInexactRepeating
                                        (AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                                triggerTime, repeatInterval,
                                                notifyPendingIntent);
                            }
                            // Set the toast message for the "on" case.
                            toastMessage = getString(R.string.alarm_on_toast);

                        } else {
                            // Cancel notification if the alarm is turned off.
                            mNotificationManager.cancelAll();

                            if (alarmManager != null) {
                                alarmManager.cancel(notifyPendingIntent);
                            }
                            // Set the toast message for the "off" case.
                            toastMessage = getString(R.string.alarm_off_toast);

                        }

                        // Show a toast to say the alarm is turned on or off.
                        Toast.makeText(MainActivity.this, toastMessage,
                                Toast.LENGTH_SHORT).show();
                    }
                });

        // Create the notification channel.
        createNotificationChannel();
    }


    /**
     * Creates a Notification channel, for OREO and higher.
     */
    public void createNotificationChannel() {

        // Create a notification manager object.
        mNotificationManager =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        // Notification channels are only available in OREO and higher.
        // So, add a check on SDK version.
        if (android.os.Build.VERSION.SDK_INT >=
                android.os.Build.VERSION_CODES.O) {

            // Create the NotificationChannel with all the parameters.
            NotificationChannel notificationChannel = new NotificationChannel
                    (PRIMARY_CHANNEL_ID,
                            "Stand up notification",
                            NotificationManager.IMPORTANCE_HIGH);

            notificationChannel.enableLights(true);
            notificationChannel.setLightColor(Color.RED);
            notificationChannel.enableVibration(true);
            notificationChannel.setDescription("Notifies every 15 minutes to " +
                    "stand up and walk");
            mNotificationManager.createNotificationChannel(notificationChannel);
        }
    }
}

AlarmReceiver

package com.android.fundamentals.standup;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;

/**
 * Broadcast receiver for the alarm, which delivers the notification.
 */
public class AlarmReceiver extends BroadcastReceiver {

    private NotificationManager mNotificationManager;
    // Notification ID.
    private static final int NOTIFICATION_ID = 0;
    // Notification channel ID.
    private static final String PRIMARY_CHANNEL_ID =
            "primary_notification_channel";

    /**
     * Called when the BroadcastReceiver receives an Intent broadcast.
     *
     * @param context The Context in which the receiver is running.
     * @param intent The Intent being received.
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        mNotificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);

        // Deliver the notification.
        deliverNotification(context);
    }

    /**
     * Builds and delivers the notification.
     *
     * @param context, activity context.
     */
    private void deliverNotification(Context context) {
        // Create the content intent for the notification, which launches
        // this activity
        Intent contentIntent = new Intent(context, MainActivity.class);

        PendingIntent contentPendingIntent = PendingIntent.getActivity
                (context, NOTIFICATION_ID, contentIntent, PendingIntent
                        .FLAG_UPDATE_CURRENT);
        // Build the notification
        NotificationCompat.Builder builder = new NotificationCompat.Builder
                (context, PRIMARY_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_stand_up)
                .setContentTitle(context.getString(R.string.notification_title))
                .setContentText(context.getString(R.string.notification_text))
                .setContentIntent(contentPendingIntent)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setAutoCancel(true)
                .setDefaults(NotificationCompat.DEFAULT_ALL);

        // Deliver the notification
        mNotificationManager.notify(NOTIFICATION_ID, builder.build());
    }
}

Czy macie może pomysł, jakie zmiany trzeba tu wprowadzić, by notyfikacja odpalała się automatycznie po włączeniu aplikacji po raz pierwszy i ustawiała się na odpalenie po raz pierwszy o 20:00, a następnie co 24 godziny ?

2

Wszystko masz tu: https://developer.android.com/training/scheduling/alarms

W tym kodzie, który wkleiłeś jest ustawienie wyświetlania powiadomienia co 15 minut. Czytałeś ten kod, który wklejasz? Może lepiej złóż ofertę tu? https://4programmers.net/Forum/Og%C5%82oszenia_drobne

Bo wygląda, że nie chcesz zrozumieć jak to działa, tylko żeby ktoś to zrobił za ciebie.

0

Oczywiście, że czytałem ten kod. Nawet odpaliłem go na swoim emulatorze. Robi połowe roboty, bo wystarczy podmienić 15 minut na 24 godziny i już część zadania wykonana, czytaj powtarzalność co jakiś czas. Kwestia jeszcze jak ustawić tą pierwszą notyfikację na godzinę 20:00, a nie na naciśnięcie przycisku

Przepraszam kolego, ale o czym Ty tu mówisz ? Doskonale wiedziałem, że notyfikacja odpala się co 15 minut, ale co to ma do rzeczy ? Pytanie jest jak uruchomić notyfikację o określonej godzinie, a nie po naciśnięciu przycisku. Czy odpowiedź na to pytanie jest gdzieś zaszyfrowana w kodzie, bo nie rozumiem ?

2

Jak przeczytasz dokumentację, to się dowiesz jak ustawić na określoną godzinę. Czytałeś dokumentację? Bo wiesz, takie lenistwo jest źle widziane chyba że płacisz za zrobienie tego za ciebie. Ale to nie ten dział forum.

Czemu nie zajrzałeś dokumentacji zanim w ogóle naskrobałeś to pytanie, a jak już dostałeś link do dokumentacji, dalej pytasz o to samo?

1

Ale czemu w ogóle szukasz informacji o okresowym wyzwalaniu czegoś w dokumentacji o notyfikacjach? Znalazłeś klasę AlarmManager, więc mogłoby się wydawać, że rozumiesz do czego ona służy. Rada "przeczytaj dokumentację" z linkiem do dokumentacji, to dobra rada. Wystarczy tylko na spokojnie ze zrozumieniem przeczytać. Zwłaszcza jak jeden z odnośników w tej dokumentacji przekierowuje wprost do tej metody - https://developer.android.com/reference/android/app/AlarmManager#setRepeating(int,%20long,%20long,%20android.app.PendingIntent).

1

Zajrzałem do dokumentacji zanim założyłem temat, przeszukałem też internet. Najwidoczniej zajrzałem w złe miejsce dokumentacji. Sam temat notyfikacji w dokumentacji nie daje odpowiedzi na mój problem, a jednak tam go szukałem, bo jednak chodzi o notyfikacje, więc gdzie szukać odpowiedzi, jak nie w dokumentacji o notyfikacjach. Zajrzałem do dokumentacji, nie znalazłem, szukałem w złym miejscu. Wybacz, że nie przeczytałem jeszcze dokumentacji od deski do deski i że jeszcze nie orientuję sie dobrze, gdzie czego szukać

0

Dobra dzieciaczki, starczy tego rzucania piaskiem w oczy kolegów z piaskownicy. Dajcie sobie spokój, bo nie chce mi się więcej postów kasować czy edytować ;)

0

Panowie, czy jest możliwe otrzymywanie notyfikacji z apki, w momencie kiedy jest ona całkowicie wyłączona ? Czytam o background services, ale nie wiem, czy kopie w dobrym miejscu

Edit. Juz wiem, ze zle kopie... xd

2

Tak, do tego służy AlarmManager w połączeniu z BroadcastReceiver. W teorii będzie działać. W praktyce zależy od telefonu - https://dontkillmyapp.com.

0

Dzięki wielkie

0

A wiesz może jak takie apki jak messenger, czy aplikacje bankowe przeskoczyły ten problem, by wysyłać notyfikację bez względu na to, czy używasz apki, czy nie, czy jest włączona i jaki masz telefon ? Jest jakiś sposób, by wymusić na telefonie, by pozwolił apce działać w tle cały czas ?

2
RezyserKinaAkcji napisał(a):

A wiesz może jak takie apki jak messenger, czy aplikacje bankowe przeskoczyły ten problem, by wysyłać notyfikację bez względu na to, czy używasz apki, czy nie, czy jest włączona i jaki masz telefon?

Opakowałeś dwa problemy w jedno pytanie. Do powiadomień w tle w tego typu scenariuszach korzysta się z wiadomości push - https://firebase.google.com/docs/cloud-messaging/android/client. Z tym, żeby działało to na wszystkich telefonach zawsze, zazwyczaj możesz mało zrobić. Chińscy dostawcy często mają zaszyte na poziomie systemu aplikacje bardziej uprzywilejowane i np. duże aplikacje jak Messenger albo AirBnb są tam dodane ze względu na swoją popularność.

Jest jakiś sposób, by wymusić na telefonie, by pozwolił apce działać w tle cały czas?

Na szczęście nie.

0

Kurcze, to nie dobrze, cała koncepcja aplikacji mi runeła, jeśli notyfikacje nie zawsze sobie przychodzą :P

No ale nic, dzięki za pomoc

0

Jeśli mam być szczery, to nie przejmowałbym się tym. Wiadomości push zazwyczaj przychodzą niezależnie od systemu. Co prawda, Google w ogóle nie daje gwarancji, że wiadomości przyjdą, ale to raczej wyimaginowany problem, jeśli nie korzysta się z nich do sytuacji krytycznych dla aplikacji. Tak naprawdę pewnie nawet bym się nie przejmował przerywaniem działania AlarmManagera na niektórych telefonach.

2

Tam to nie aplikacja generuje powiadomienia, tylko dostaje je z serwera, za pomocą usług Google. Aplikacja wcale w tym celu nie musi działać w tle, usługi Google działają i to wystarczy.

0

Tzn moja aplikacja miała w formie notyfikacji przypominać użytkownikowi, że ma wykonać pewną rzecz, którą sobie zaplanował i wprowadził do aplikacji. Najlepiej by było, gdyby to działało zawsze, nie tylko jak aplikacja jest włączona, lub działa w tle. Wiadomo, człowiek może się zapomnieć, wyłączyć lub nie włączyć apki, a tu ona przestaje spełniać swoje główne założenie - przypominanie. Także troche się zawiodłem, że nie działa to tak jak np w messengerze, tzn niezależnie, czy jest włączony, czy nie, dostajesz powiadomienie :P

3

Najlepiej by było, gdyby to działało zawsze, nie tylko jak aplikacja jest włączona

No to w pierwszym linku podanym przez @Meini masz napisane jak byk

Alarms have these characteristics:
[...]
They operate outside of your application, so you can use 
them to trigger events or actions even when your app 
Is not running, and even if the device itself is asleep.

Chyba to jest dokładnie to, czego chcesz. Ustawisz alarm, apka może zostać zaorana, ale powiadomienie się pokaże, bo za pamiętanie o tym odpowiedzialny jest system a nie aplikacja.

0

No właśnie. I chociaż zgodnie z dokumentacją stosuję WAKEUP

"RTC_WAKEUP—Wakes up the device to fire the pending intent at the specified time."

        if (alarmManager != null) {
            alarmManager.setInexactRepeating
                    (AlarmManager.RTC_WAKEUP,
                            triggerTime, repeatInterval,
                            notifyPendingIntent);
        }

To jednak po wyłączeniu aplikacji notyfikacje nie przychodzą.

1 użytkowników online, w tym zalogowanych: 0, gości: 1