I have build a simple app that show a notification when i click on a button. How can show a programmed notify?
The code that i call is:
Notification.Builder builder = new Notification.Builder(this)
.setTicker("Notifica")
.setSmallIcon(android.R.drawable.stat_notify_chat)
.setContentTitle("Notifica")
.setContentText("Hai una notifica!")
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0));
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify("interstitial_tag", 1, builder.build());
You can use AlarmManager in bundle with BroadcastReceiver.
At first you must create pending intent and register it with AlarmManager.set somewhere.
And then create your broadcast receiver and receive that intent.
Update: here is the code I have promised.
At first you need to create broadcast receiver.
public class NotifyHandlerReceiver extends BroadcastReceiver {
public static final String ACTION = "me.pepyakin.defferednotify.action.NOTIFY";
public void onReceive(Context context, Intent intent) {
if (ACTION.equals(intent.getAction())) {
Notification.Builder builder = new Notification.Builder(context)
.setTicker("Notifica")
.setSmallIcon(android.R.drawable.stat_notify_chat)
.setContentTitle("Notifica")
.setContentText("Hai una notifica!")
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0));
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
nm.notify("interstitial_tag", 1, builder.build());
}
}
}
This is your broadcast receiver that can handle notification requests. For it can work, you must register it in your AndroidManifest.xml. If you don't do it, Android won't be able to handle your notification request.
Just add <receiver/> declaration into your <application/> tag.
<receiver android:name=".NotifyHandlerReceiver">
<intent-filter>
<action android:name="me.pepyakin.defferednotify.action.NOTIFY" />
</intent-filter>
</receiver>
Take a note, that action name be exactly as defined in NotifyHandlerReceiver.ACTION.
Then you can use this code
public static final int REQUEST_CODE_NOTIFY = 1;
public void scheduleNotification(long delayTimeMs) {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
long currentTimeMs = SystemClock.elapsedRealtime();
PendingIntent pendingNotifyIntent = PendingIntent.getBroadcast(
this,
REQUEST_CODE_NOTIFY,
new Intent(NotifyHandlerReceiver.ACTION),
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, currentTimeMs + delayTimeMs, pendingNotifyIntent);
}
from your activity to start a notification delayed on delayTimeMs amount of milliseconds.
Related
I want to send notification everyday on a particular time. The code is working when the app is opened. But when it closed and remove, the notifications are not showing. I have used broadcast receiver and service to this. The code is given below. Can anyone help to clear this issue.
Manifest File
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true" />
<service
android:name=".MyService"
android:enabled="true"
android:exported="true" />
MyReceiver.java
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
intent = new Intent(context, MyService.class);
context.startService(intent);
}}
MyService.java
public class MyService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
createNotification();
return Service.START_STICKY;
}
private static final String NOTIFICATION_CHANNEL_ID = "Channel01";
private void createNotification() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String name = preferences.getString("name", "User");
name = name.split(" ")[0];
String namee = "Remainder";
String description = "Remainder to update Wallet";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, namee, importance);
notificationChannel.setDescription(description);
Intent notifyIntent = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 1, notifyIntent, 0);
Notification notification = new Notification.Builder(getApplicationContext())
.setContentTitle("Remainder")
.setContentText("Hey " + name + ", Let's update your wallet")
.setSmallIcon(R.drawable.wallet)
.setChannelId(NOTIFICATION_CHANNEL_ID)
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.wallet_new))
.setContentIntent(pendingIntent)
.build();
NotificationManager notificationManager = (NotificationManager)getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(notificationChannel);
// Issue the notification.
notificationManager.notify(1 , notification);
}
}}
Activity.java
Intent notifyIntent = new Intent(getApplicationContext(), MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1, notifyIntent, 0);
alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, timeMilli, timeInterval, pendingIntent);
You shouldn't use any part of application to do that. Services, JobScheduler, or Work Manager sooner or later will be killed by the system to prevent battery drain.
In my opinion the best way to send repeated notifications is to use firebase cloud messaging triggered with external cron job (e.g. php on firebase functions).
Also make sure to deliver the notification to the system tray not to the application. To do that use FCM DataMessages. Data messages are delivered to system tray and are always display - even if service is not running.
i am currently devoloping small app and i struggle about sending notifications.
My Goal: I have different tasks and they need to send unique notifications at unique time to user even
while app is closed.
What I did?: I did create different broadCastReceiver's to make them work in harmony with
alarmManager' s but even i changed the request code , flag or channel code, i do get notifications at
same time if user enables notifications for more than one task, but alarmManagers for notifications
are not supposed to work after same time.
'receiver' part of AndroidManifest.xml
<receiver
android:name=".BroadcastReceiver"
android:exported="true">
<intent-filter>
<action
android:name="pendingIntent">
</action>
</intent-filter>
</receiver>
<receiver
android:name=".BroadcastReceiver2"
android:exported="true">
<intent-filter>
<action
android:name="pendingIntent2">
</action>
</intent-filter>
</receiver>
first and second broadCastReceiver
public class BroadcastReceiver extends android.content.BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "100")
.setSmallIcon(R.drawable.logologo)
.setContentTitle("Title")
.setContentText("Text")
.setPriority(NotificationCompat.PRIORITY_HIGH);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(100, builder.build());
}
}
}
public class BroadcastReceiver2 extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,"102")
.setSmallIcon(R.drawable.logologo)
.setContentTitle("Title")
.setContentText("Text")
.setPriority(NotificationCompat.PRIORITY_HIGH);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(102, builder.build());
}
}
First and second Channel
public void createChannel1()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
CharSequence name = "channel1";
String description = "channel1 description";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel1 = new NotificationChannel("100", name, importance);
channel1.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel1);
}
}
public void createChannel2()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
CharSequence name = "channel2";
String description = "channel2 description";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel2 = new NotificationChannel("102", name,importance);
channel2.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel2);
}
}
Activity that needed to send Notification from first broadCastReceiver on Channel1 and
Activity that needed to send Notification from second broadCastReceiver on Channel2
button30.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent(SmokeActivity.this, BroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(SmokeActivity.this, 100, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60, pendingIntent);
}
});
button29.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Toast.makeText(WaterActivity.this, "Notifications Set", Toast.LENGTH_SHORT).show();
Intent intent2 = new Intent(WaterActivity.this, BroadcastReceiver2.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(WaterActivity.this,0,intent2,0);
AlarmManager alarmManager2 = (AlarmManager)getSystemService(ALARM_SERVICE);
// Set the alarm to start at 8:30 a.m.
Calendar calendar2 = Calendar.getInstance();
calendar2.setTimeInMillis(System.currentTimeMillis());
calendar2.set(Calendar.HOUR_OF_DAY, 8);
calendar2.set(Calendar.MINUTE, 30);
alarmManager2.setRepeating(AlarmManager.RTC_WAKEUP, calendar2.getTimeInMillis(),
1000*45, pendingIntent2);
}
});
For anyone suffering from same problem, the thing is android system does not allow us to send notification after first 10 minute when you create notification.
This question already has answers here:
Android notification is not showing
(14 answers)
Closed 4 years ago.
//I had given intent in oncreate
Intent alarmIntent = new Intent(getContext(), ServiceReceiver.class);
pendingIntent = PendingIntent.getBroadcast(getContext(),
0, alarmIntent, 0);
// here i am setting alarm
public void setALARM(String time, String strDate){
AlarmManager manager = (AlarmManager) getContext()
.getSystemService(Context.ALARM_SERVICE);
String strHour=formateDateFromstring("HH:mm","HH",time);
String strMin=formateDateFromstring("HH:mm","mm",time);
String strdate=formateDateFromstring("yyyy-MM-dd","dd",strDate);
String strMonth=formateDateFromstring("yyyy-MM-dd","MM",strDate);
String strYear=formateDateFromstring("yyyy-MM-dd","yyyy",strDate);
int hour=Integer.parseInt(strHour);
int min=Integer.parseInt(strMin);
int date=Integer.parseInt(strdate);
int month=Integer.parseInt(strMonth)-1;
int year=Integer.parseInt(strYear);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH,date); //1-31
cal.set(Calendar.MONTH,month); //first month is 0!!! January is zero!!!
cal.set(Calendar.YEAR,year);//year...
cal.set(Calendar.HOUR_OF_DAY,hour); //HOUR
cal.set(Calendar.MINUTE,min);//MIN
cal.set(Calendar.SECOND,0);
manager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
pendingIntent);
}
//Here is my receiver class
public class ServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.logob_icon_prestigesalon)
.setContentTitle("ABC")
.setContentText("time to go")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
Toast.makeText(context,"service",Toast.LENGTH_LONG).show();
NotificationManager notificationmanager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationmanager.notify(0, builder.build());
}
}
//I mentioned receiver class in manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".ServiceReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<!-- Will not be called unless the application explicitly enables it -->
<receiver android:name=".DeviceBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
I want to set an alarm for the exact time.I checked the code in debug mode whether the debug is coming inside the onReceive if the given time comes.The debug is coming whe the given time is reached.The issue is notification is not visible.
Not sure if it is your specific problem, but NotificationCompat.Builder(Context context) is deprecated in API level 26.1.0. You should use NotificationCompat.Builder(Context, String) instead. All posted Notifications must specify a NotificationChannel Id for 26+ devices as you can check in Notification and Notification.Builder documentation
Try something like this,Have not tested.
String channelID = "Notification_Channel_ID";
String channelDesr = "Notification_channel_description";
buildNotificationChannel(channelID,channelDesr);
public void buildNotificationChannel(String channelID, String description) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager manager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
if (manager.getNotificationChannel(channelID) == null) {
NotificationChannel channel = new NotificationChannel(channelID, description,
NotificationManager.IMPORTANCE_LOW);
channel.setDescription(description);
manager.createNotificationChannel(channel);
}
}
}
NotificationCompat.Builder builder = new
NotificationCompat.Builder(context,channelID)
.setSmallIcon(R.drawable.logob_icon_prestigesalon)
.setContentTitle("ABC")
.setContentText("time to go")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
Toast.makeText(context,"service",Toast.LENGTH_LONG).show();
NotificationManager notificationmanager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationmanager.notify(0, builder.build());
I create an android wear app and I want to this app create notification some times (In this code I want to call my service every 15 minutes for creating notification)
When I register my service with AlramManager, I can see that task Created in OS (adb shell dumpsys alarm > dump.txt) but I can't see the notification or log to prove the service run. I test my service with startService and both notification and log worked correctly, So I don't know where is the problem. Here are the codes I use:
MyAlarmService.java
public class MyAlarmService extends Service {
#Override
public void onCreate() {
super.onCreate();
Log.d("From serivce","Service run once");
// Create notification
Context context = this;
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentTitle(context.getString(R.string.NotificationTitle))
.setSmallIcon(R.mipmap.ic_launcher_hafez)
.setContentText("Some text");
Notification secondPage =
new NotificationCompat.Builder(context)
.setContentTitle(context.getString(R.string.NotificationTitle))
.setContentText("Some text")
.build();
NotificationCompat.WearableExtender extender = new NotificationCompat.WearableExtender();
extender.addPage(secondPage);
builder.extend(extender);
NotificationManagerCompat mgr = NotificationManagerCompat.from(context);
int NotificationId = new Random().nextInt(5200);
mgr.notify(NotificationId, builder.build());
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
AndroidManifest.xml
...
<service android:name=".MyAlarmService" />
...
The code that register service in AlarmManager:
Context context = getActivity().getApplicationContext();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
Intent intent = new Intent(context, MyAlarmService.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_FIFTEEN_MINUTES, alarmIntent);
The content of dump.txt
Current Alarm Manager state:
...
Batch{91609e num=3 start=7228838 end=7233540 flgs=0x8}:
...
RTC_WAKEUP #0: Alarm{18a777f type 0 when 1467992333472 org.rashno.mypackagename}
tag=*walarm*:org.rashno.mypackagename/.MyAlarmService
type=0 whenElapsed=-6s582ms when=2016-07-08 20:08:53
window=+11m15s0ms repeatInterval=900000 count=0 flags=0x0
operation=PendingIntent{397c34c: PendingIntentRecord{de77f95 org.rashno.mypackagename broadcastIntent}}
...
Alarm Stats:
...
u0a57:org.rashno.mypackagename +9ms running, 1 wakeups:
+9ms 1 wakes 1 alarms, last -1m33s417ms:
*walarm*:org.rashno.mypackagename/.MyAlarmService
...
...
A PendingIntent for a service should be created using getService.
PendingIntent alarmIntent = PendingIntent.getService(context, 0, intent, 0);
I have a Timer and I send a notification to the user when the timer finishes, I've added a "Stop" button to my notification and when the user clicks it I want the sound of the timer to stop.
What I tried is registering the action to my BroadcastReceiver in my TimerActivity like this:
filter = new IntentFilter();
filter.addAction(TimerService.BROADCAST_ACTION);
registerReceiver(broadcastReceiver, filter);
this is the BroadcastReceiver inside the TimerActivity:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ScheduledService.STOP_TIMER))
{
if(timerAudio.isPlaying())
{
timerAudio.stop();
timerAudio.release();
timerAudio = null;
}
}
};
And this is my how I create the notification inside the ScheduledService class:
Intent notificationIntent = new Intent(getBaseContext(), CookingTimer.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Intent nextIntent = new Intent(STOP_TIMER);
PendingIntent stopTimer = PendingIntent.getBroadcast(this, 0, nextIntent, 0);
Notification noti = new Notification.Builder(this)
.setContentTitle("This is a sample notification")
.setContentText("Subject")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.addAction(R.drawable.ic_launcher, "Stop", stopTimer).build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Hide the notification after its selected
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);
I've registered the Service and the action inside my Manifest and I receive the notification correctly, but the button action doesn't work.. Can someone explain me how to fix this?
Post the Activity that has the MediaPlayer controlling the sound.
If you are not receiving Null Pointer Exceptions, I suppose that timerAudio is correct.
However specify if the current view is defined and in context.