One of the most annoying things in Android development is setting a daily notification. It always seem to stop working after several days. Here I am giving a solution for such cases. Follow this tutorial and your notification will be triggered every day at appointed time, as long as the user has the application installed.
Lets go.
First, create an Alarm notification receiver:
package pdf.tutorials.virtuoza.virtuozatutorials; import android.app.Notification; 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; import static android.app.PendingIntent.FLAG_ONE_SHOT; /** * Created by azem on 10/29/17. */ public class AlarmNotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { NotificationCompat.Builder builder = new NotificationCompat.Builder(context); Intent myIntent = new Intent(context, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity( context, 0, myIntent, FLAG_ONE_SHOT ); builder.setAutoCancel(true) .setDefaults(Notification.DEFAULT_ALL) .setWhen(System.currentTimeMillis()) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("Zodiac") .setContentIntent(pendingIntent) .setContentText("Check out your horoscope") .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND) .setContentInfo("Info"); NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(1,builder.build()); } }
In your Main Activity, create a method for scheduling the notification. This is where you set the time it:
package pdf.tutorials.virtuoza.virtuozatutorials; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.SystemClock; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import java.util.Calendar; public class MainActivity extends AppCompatActivity { Button show; public static String MY_PREFS_NAME= "nameOfSharedPreferences"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); show = (Button)findViewById(R.id.btn_show); show.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startAlarm(true,true); } }); } private void startAlarm(boolean isNotification, boolean isRepeat) { AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); Intent myIntent; PendingIntent pendingIntent; // SET TIME HERE Calendar calendar= Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY,15); calendar.set(Calendar.MINUTE,20); myIntent = new Intent(MainActivity.this,AlarmNotificationReceiver.class); pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,0); if(!isRepeat) manager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime()+3000,pendingIntent); else manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,pendingIntent); } }
Here is Main Activity’s layout:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="pdf.tutorials.virtuoza.virtuozatutorials.MainActivity"> <Button android:id="@+id/btn_show" android:text="SCHEDULE DAILY NOTIFICATION" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout>
Now we want to take care about scenarios where users turn off their phones. We want to reschedule our notifications after they turn their phones on again. For that, we need a BroadcastReceiver for letting the application know when the phone is turned on, and we need a service for app rescheduling the notification by itself.
Let’s first create BootReceiver class, so the app can know when the phone is restarted:
package pdf.tutorials.virtuoza.virtuozatutorials; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; /** * Created by azem on 11/3/17. */ public class BootReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { // Your code to execute when Boot Completd Intent i = new Intent(context,MyService.class); context.startService(i); Toast.makeText(context, "Booting Completed", Toast.LENGTH_LONG).show(); } }
And now lets create the service for rescheduling the notification. Service gets the information about phone being turned on and triggers the startService() method:
package pdf.tutorials.virtuoza.virtuozatutorials; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.os.SystemClock; import java.util.Calendar; public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); startAlarm(true,true); } @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_NOT_STICKY; } private void startAlarm(boolean isNotification, boolean isRepeat) { AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); Intent myIntent; PendingIntent pendingIntent; //THIS IS WHERE YOU SET NOTIFICATION TIME FOR CASES WHEN THE NOTIFICATION NEEDS TO BE RESCHEDULED Calendar calendar= Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY,18); calendar.set(Calendar.MINUTE,45); myIntent = new Intent(this,AlarmNotificationReceiver.class); pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,0); if(!isRepeat) manager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime()+3000,pendingIntent); else manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,pendingIntent); } }
Now, this is very important. In your manifest file, inside <application> tag, copy and paste this code:
<receiver android:name=".BootReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <category android:name="android.intent.category.HOME" /> </intent-filter> </receiver> <receiver android:name=".AlarmNotificationReceiver"/> <service android:name=".MyService" android:enabled="true" android:exported="true"></service>
And that is it. This is how to always get the notification without it stopping to work.
Share with your friends