that's my code for scheduled notification for my android app, but it does nothing for some reason. Please tell me where is the problem.
Another question: I also made a button which send a notification - just for learning, and for some reason it works only on my samsung s6. When I run the app on the android studio emulator it gives me an error about notification package. Why is that?
Thank a lot!
public void setAlarm(View view) {
Long alertTime = new GregorianCalendar().getTimeInMillis()+5*1000;
Intent alertIntent = new Intent(this, AlertReceiver.class);
AlarmManager alarmManager = (AlarmManager)
getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime,
PendingIntent.getBroadcast(this, 1, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
}
}
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
createNotification(context, "Time Up", "5 Seconds Has Passed", "Alert");
}
public void createNotification(Context context, String msg, String msgText, String msgAlert) {
PendingIntent noficitIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(msg)
.setTicker(msgAlert)
.setContentText(msgText);
mBuilder.setContentIntent(noficitIntent);
mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
Based on your comments, it seems you just forgot to register your BroadcastReceiver. Per Android docs you will only be able to receive intents on your receiver if you register it first:
You can either dynamically register an instance of this class with Context.registerReceiver() or statically declare an implementation with the tag in your AndroidManifest.xml.
Since you are sending a broadcast directly to your receiver like that:
Intent alertIntent = new Intent(this, AlertReceiver.class);
There is no point in declaring any intent-filter for it, so you just need to add the following line to your AndroidManifest.xml (inside <application> tag):
<receiver android:name="com.your.package.AlertReceiver" />
Hope it helps.
Related
I am creating a research app that should prompt the user 4 times a day to enter their mood - by sending a notification, which when clicked launches the correct Activity. I am able to schedule these notifications using AlarmManager, however only the last scheduled notification ever shows. So although I schedule them for 9AM, 2PM, 5PM, and 8PM, it only ever sends a notification at 8PM.
How can I get all of the scheduled notifications to show?
Here is my code for setting (one of) the alarms (from a notification manager class). Note that al alarms are set using the same instance of AlarmManager:
cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.HOUR_OF_DAY, 9);
cal.set(Calendar.MINUTE, 0);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), createPendingIntent(9, this));
Here is the createPendingIntent method (in the same notification manager class):
public static PendingIntent createPendingIntent(int hour, Context c){
Intent notificationIntent = new Intent(c, AlarmBroadcastReceiver.class);
notificationIntent.putExtra("time", hour);
PendingIntent pendingIntent = PendingIntent.getBroadcast(c, 0 , notificationIntent , PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
Here is the BroadcastReceiver for the alarm:
public class AlarmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationSender.createNotification(context);
}
}
And finally the createNotification method:
public static void createNotification(Context c){
Log.e("notif?", "creating");
Intent intent = new Intent(c, UpdateMoodActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
int notificationId = new Random().nextInt();
PendingIntent pendingIntent = PendingIntent.getActivity(c, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(c, "com.lizfltn.phdapp.notifChannelID")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("SoftMood")
.setContentText("Please record your mood")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(c);
notificationManager.notify(notificationId, builder.build());
}
Yes I know this isn't the best-practice way of doing things, or even the neatest, but unfortunately I need to get code working ahead of writing good code :P
I've tried various configurations of setting the alarm, e.g. using elapsed realtime instead of RTC, only setting the alarm, setting the exact alarm, etc, but there might be something fundamental I'm not understanding about how those work.
Any help appreciated!
Can you try with same id in pending intent and notify.?
Notification id in createNotification() method is random id.
int notificationId = new Random().nextInt();
and id used in createPendingIntent method is 0.
PendingIntent pendingIntent = PendingIntent.getBroadcast(c, 0 , notificationIntent , PendingIntent.FLAG_UPDATE_CURRENT);
Can you try with using same value for second parameter of getBroadcast?
Not sending notification at selected time, when I ran my code, directly showed notification
and showed error as well
Here is the error message: E/NotificationManager: notifyAsUser: tag=null, id=12345, user=UserHandle{0}
I thought the error message was due to Build.VERSION.SDK_INT, but after adding that, the error message is still there.
Place all of these under onCreate:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 13);
calendar.set(Calendar.MINUTE,9)
;
Intent intent = new Intent ();
intent.setAction("com.example.Broadcast");
PendingIntent contentIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// PendingIntent alarmIntent = PendingIntent.getBroadcast(this,0, intent,0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, contentIntent);
and here is the extend.
public class wakeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
setNotification(context);
}
protected void setNotification(Context context){
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
String ChannelId = "12345";
int uniID = 12345;
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,ChannelId )
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle("Hi")
.setAutoCancel(true)
.setWhen(System.currentTimeMillis())
.setContentText("Please Rate.");
builder.setContentIntent(contentIntent);
//
// Send notification to your device
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId("com.myApp");
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"com.myApp",
"My App",
NotificationManager.IMPORTANCE_DEFAULT
);
if (manager != null) {
manager.createNotificationChannel(channel);
}
}
manager.notify(uniID, builder.build());
}
}
Can someone please help me with this?
You are very confused.
In your code you call NotificationManager.notify(). This will show the Notification immediately.
You do:
Intent intent = new Intent(this, MainActivity.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this,0, intent,0);
This won't work. You have created a PendingIntent which will be sent via broadcast using an Intent that is for an Activity! What do you want to happen? Do you want an Activity to be launched or do you want a BroadcastReceiver to be triggered?
I think what you want to do is as follows:
Create an Intent for a BroadcastReceiver, wrap that in a PendingIntent using getBroadcast() and pass that to the AlarmManager so that the broadcast Intent will be set at some future time.
Create a class that extends BroadcastReceiver. In onReceive() create the Notification and call NotificationManager.notify() to post the Notification. In the Notification you can set a PendingIntent that opens your Activity so that if the user clicks on the Notification your Activity will be launched. To do this, call PendingIntent.getActivity() and pass an Intent that contains MainActivity.class.
I made a service for receiving notification, every time data is updated at the back end. Here's the code for the service:
public class FeedbackService extends IntentService {
public FeedbackService() {
super("FeedbackService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d("MyService", "About to execute feedback call");
feedbackCheckCall(this);
}
private void feedbackCheckCall(final Context context){
//Call for getting checking data from backend.
}
private void sendNotification(Context context) {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher_icon)
.setContentTitle("Feedback Reply")
.setContentText("You've a reply waiting for your feedback!")
.setVibrate(new long[]{500,500,500});
Intent notificationIntent = new Intent(context, navHomeActivity.class );
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);
// Add as notification
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0, builder.build());
}
}
Here's the code for the reciever :
public class FeedbackRecieiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent dailyUpdater = new Intent(context, FeedbackService.class);
context.startService(dailyUpdater);
Log.d("AlarmReceiver", "Called context.startService from AlarmReceiver.onReceive");
}
}
Here's the code from where I call it:
Calendar updateTime = Calendar.getInstance();
updateTime.setTimeZone(TimeZone.getDefault());
updateTime.set(Calendar.HOUR_OF_DAY,0);
updateTime.set(Calendar.MINUTE, 0);
updateTime.set(Calendar.SECOND, 0);
long intervalTime = 2*60*60*1000; //in milliseconds format is : h*m*s*1000
Intent intent = new Intent(context, FeedbackRecieiver.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,intent,PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,updateTime.getTimeInMillis(),intervalTime,pendingIntent);
My manifest declarations are :
<service android:name=".navFragments.feedbackSuppport.FeedbackService"/>
<receiver android:name=".navFragments.feedbackSuppport.FeedbackRecieiver"/>
The app is crashing when I use a signed copy with this error on startup:
Sending non-protected broadcast com.motorola.motocare.INTENT_TRIGGER from system 6836:com.motorola.process.system/1000 pkg com.motorola.motgeofencesvc
java.lang.Throwable
at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:18179)
at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:18779)
at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:512)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2905)
at android.os.Binder.execTransact(Binder.java:565)
Can someone please help me out with this? I'm really stuck here. Thanks in advance.
So, there was no issue with broadcast receiver or the service. The issue was while using proguard. I was not using it correctly. I had disabled it in the debug variant and enabled it in the release variant. The app was crashing due to that.
I am building a simple android app for java tutorial in which i want to keep one read later option using which the user can schedule a time for reading and at the specified time my app should give a notification to the user. Even if my app is not opened at that time he should get the notification in notifications bar.I am a newbie in android and have no idea about how to do this.Can someone please help me out?As a i am a newbie a detailed explanation can be more helpful.Thanks in advance :-)
To schedule a delayed notification, you
1) Create a BroadcastReceiver that will receive the event:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//you might want to check what's inside the Intent
if(intent.getStringExtra("myAction") != null &&
intent.getStringExtra("myAction").equals("notify")){
NotificationManager manager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.yourIcon)
//example for large icon
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setContentTitle("my title")
.setContentText("my message")
.setOngoing(false)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true);
Intent i = new Intent(context, YourTargetActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(
context,
0,
i,
PendingIntent.FLAG_ONE_SHOT
);
// example for blinking LED
builder.setLights(0xFFb71c1c, 1000, 2000);
builder.setSound(yourSoundUri);
builder.setContentIntent(pendingIntent);
manager.notify(12345, builder.build());
}
}
}
Don't forget to declare it in the Manifest:
<receiver
android:name="your.package.name.MyReceiver"
android:exported="false" />
2) Schedule the action (assumed you do it from an Activity):
//will fire in 60 seconds
long when = System.currentTimeMillis() + 60000L;
AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyReceiver.class);
intent.putExtra("myAction", "mDoNotify");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
am.set(AlarmManager.RTC_WAKEUP, when, pendingIntent);
3) You're done
//Disclaimer: haven't compiled the code, typos possible. The rest is your homework ;)
Use AlarmManager to solve your problem. And when alarm is received, you can send a notification too.
See this sample app in android's tutorial for implementing the alarms.
I have set an Alarm Manager which will show Notification 10 seconds after app will be destroyed.
But it's not working.
Here's my onDestroy() code:
#Override
public void onDestroy() {
super.onDestroy();
Intent myIntent = new Intent(this, alarmManager.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
//alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 10*1000, 10*1000, pendingIntent);
alarmManager.cancel(pendingIntent);
}
and here is alarmManager.class:
public class alarmManager extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service1 = new Intent(context, Notification.class);
context.startService(service1);
}
}
and here is Notification.class:
public class Notification extends Service {
#Override
public void onCreate() {
super.onCreate();
Intent mainIntent = new Intent(this, Main.class);
NotificationManager notificationManager
= (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
android.app.Notification noti = new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(this, 0, mainIntent,
PendingIntent.FLAG_UPDATE_CURRENT))
.setContentTitle("Title")
.setContentText("It's been so Long!!!")
.setSubText("Please return back to App")
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setVibrate(new long[] {1000,1000,1000,1000})
.setSmallIcon(R.drawable.ic_launcher)
.setTicker("Important Notification")
.setWhen(System.currentTimeMillis())
.build();
notificationManager.notify(0, noti);
}
*I've been working on this since many days, but I am unable to get through it.
Any Help would be highly* appreciated.
Thanks in advance.
There are some relatively minor changes to make, but overall you've got the necessary code.
You don't need a Service for this. Move the code to create the Notification to the BroadcastReceiver, and replace this with context everywhere.
Make sure your BroadcastReceiver is listed in the manifest.
Don't use setRepeating() for the alarm; use set(). You only need it to fire once.
Remove the following line: alarmManager.cancel(pendingIntent);
Those are the changes necessary to get it working. However, you might also consider removing the sound and vibration from the Notification, and treat it more like a status message. It would also be preferable to rename your BroadcastReceiver class. Perhaps something like AlarmReceiver, to be in keeping with Java class naming conventions, and to avoid confusion with the AlarmManager class.