My alarm code is working fine as default ringtone is playing well on time. But not able to stop the alarm tone. In receiver class I inserted the following code.
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
Ringtone r = RingtoneManager.getRingtone(context, notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
I also inserted the code for cancel the alarm in main class, which is also working well with the code
alarmMgr.cancel(pendingIntent);
But once the default ringtone start playing and user want to stop this by stop button then it is not working.
In main class with stopbutton.setOnClickListener I inserted the following code
Intent intent = new Intent(getBaseContext(), Reciver.class);
stopService(intent);
I think it can be stop by r.stop();
but how should I use it in stop button.
Make a Global instance of Ringtone and on button click use r.stop() use this link to perform the operation in service. Let me know if I understood the question correctly.
A broadcast intent registered while you schedule the alarm but to ensure a cancel you have to registered another intent that would boradcast cancel event to system.
Look at piece of code working fine during a cancel event.
Intent intent = new Intent(this, YourReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 123, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Related
I am currently developing an app on android studio using java where I want the user to be able to receive notifications from calendar events that they create. However, my notifications are not coming on time as they are either lagging or just not showing.
Here is my coding for the alarm receiver which sets up the notification:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String event = intent.getStringExtra("event");
String time = intent.getStringExtra("time");
int notId = intent.getIntExtra("id", 0);
Intent activityIntent = new Intent(context, CalendarActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, activityIntent, PendingIntent.FLAG_ONE_SHOT);
String channelId = "channel_id";
CharSequence name = "channel_name";
String description = "description";
NotificationChannel channel = new NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_HIGH);
channel.setDescription(description);
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentTitle(event)
.setContentText(time)
.setDeleteIntent(pendingIntent)
.setGroup("Group_calendar_view")
.build();
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
notificationManagerCompat.notify(notId,notification);
}
}
Here is my CustomCalendarView Activity that sets up the alarm:
private void setAlarm(Calendar calendar, String event, String time, int RequestCode){
Intent intent = new Intent(context.getApplicationContext(), AlarmReceiver.class);
intent.putExtra("event",event);
intent.putExtra("time",time);
intent.putExtra("id",RequestCode);
#SuppressLint("UnspecifiedImmutableFlag") PendingIntent pendingIntent = PendingIntent.getBroadcast(context,RequestCode,intent,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager)context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() ,pendingIntent);
}
For example: When I set an alarm for 10:20 am, the notification either doesn't pop up or pops up really late like at 10:22 am. Please help! Let me know if I need to provide any more information.
You should use exact alarms for firing alarm on time,
use alarmManager.setExact() instead of alarmManager.set().
setExact() method is like set(), but does not permit the OS to adjust the delivery time. The alarm will be delivered as nearly as possible to the requested trigger time.
Put setExact() instead of set
alarmManager.setExact(...);
But with different devices and interface updates, the performance of the application work differed from one device to another, in this case you must put some settings in your application such as Disable Software Battery Optimizations, make the application run in the background even after closing, give Permissions Autostart, turn on all notifications and display them etc. Finally, call the functions in the onStop() event of the Activity.
Yes, correct. You should ask user to allow Battery Optimization and in Android 12 or higher you should ask user to enable Alarms & Reminders permission as well.
But, when your app wants to fire alarms exactly on time you have to use exact alarms.
During development of a small android app, I am having problem in running an alarm manager, after the app is terminated by the user. While the app is running in the foreground or background, everything works fine.
I did the following steps:
AndroidManifest.xml
<receiver android:name="MyBroadcastReceiver" ></receiver>
MainActivity.java
Within the OnClick method of a button, I call
startAlert( x*60*1000);
x is a class-wide visible variable
public void startAlert(long timeInMillis){
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+(timeInMillis),pendingIntent);
}
Toast.makeText(this, "Alarm in " + x + " Minuten",Toast.LENGTH_LONG).show();
}
MyBroacastReciever.java
public void onReceive(Context context, Intent intent) {
MediaPlayer player = MediaPlayer.create(context,MainActivity.link);
player.start();
Toast.makeText(context, "Alarm....", Toast.LENGTH_LONG).show();}
What should I do to get the alarmManager successfully running, after the app is closed?
You could put the alarm manager in the service. The foreground service is used to keep our application alive even though the main application has been quit by the user. And then the alarm manager could trigger the code in the broadcast receiver class
I am very new to Android so this maybe a really basic question:
I have a Service which starts when a user press a button
The service will start a new task and Loop it every N Seconds.
The seconds are set over the Settings Tab in my Android App.
In the OnStart() Method in the service get the preferences:
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
And set the Settings, for example:
final Long pollInterval = Long.parseLong(settings.getString("pollInterval", "1000"));
The Task is Polling on a Database for new entrys.
My Goal is to restart the Service after going back to the main frame so the onCreate method get the new Preferences or to refresh the preferences in the running task to change the Poll interval.
I tried to restart the Service with:
startService(serviceIntent);
stopService(serviceIntent);
But for any reason this doesn't work.
Thanks in advance for the answers.
Use this one to repeat service
try {
//Create a new PendingIntent and add it to the AlarmManager
Intent intent = new Intent(this, Service.class);
PendingIntent pendingIntent = PendingIntent.getService(this,
12345, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
(AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(),
2*60*60,pendingIntent);
} catch (Exception e) {}
Also stop service when your task is completed
I am trying to make a simple stopwatch app that will display the time in a notification and give you a couple buttons that will allow you to start and stop the stopwatch.
How do I add a button to a notification? And how do I 'point' that button to a certain function?
Heres a picture of what I was thinking:
actionIntent = new Intent(this, MainActivity.class);
actionPendingIntent = PendingIntent.getService(this, 0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
timerNotification.addAction(android.R.drawable.ic_media_pause, "Start", actionPendingIntent);
This is what I currently have. Where in the intent would I put the function I want to execute?
Add Action to the notification and assign a pendingintent
If you want to custom your notification layout,you can use setContent() function with a RemoteViews of your custom layout.
Remote View mRemoteView = new RemoteViews(getPackageName(), R.layout.notification_general);
Notification.Builder mBuilder = new Notification.Builder(context);
mBuilder.setSmallIcon(R.mipmap.ic_battery)
.setContent(mRemoteView)
.setContentIntent(notificationPendingIntent);
mNotificationManager.notify(1, mBuilder.build());
To handle an notification button onClick event, you need to use separate PendingIntents(made from Intents with differecnt actions) for every button. Later in onReceive() you just check action of incoming Intent & execute different code depending on that. Remember to assign your Listener on manifest.
Intent generalIntent = new Intent(context, GeneralReceiver.class);
generalIntent.putExtra(REQUEST_CODE, ACTION_GENERAL);
PendingIntent generalPendingIntent =
PendingIntent.getBroadcast(context, 1, generalIntent, 0);
mRemoteView.setOnClickPendingIntent(R.id.btnNotificationGeneral, generalPendingIntent);
public static class GeneralReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Your code here
}
}
My app is running a service that collects feeds. When it find these feeds it create notations (unsuccessfully). I use a method call like this:
doNotification(date,"New Article",title,link,content,description,false);
for articles and this:
doNotification(date,"New Video",title,link,"","",true);
for videos. The method is this:
public void doNotification(Date date,String title,String subtext,String url,String body,String dateString,boolean video){
long time = date.getTime();
if(time > feedGetter.lastFeed){
//New feed, do notification
NotificationManager mNotificationManager = (NotificationManager) feedGetter.service.getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.notification_icon;
Notification notification = new Notification(icon, title + ": " + subtext, time);
Intent notificationIntent = new Intent(feedGetter.service, NotificationActivity.class);
notificationIntent.putExtra("url",url);
notificationIntent.putExtra("video",video);
if(!video){
notificationIntent.putExtra("body",body);
notificationIntent.putExtra("date",dateString);
notificationIntent.putExtra("title",subtext);
}
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(feedGetter.service, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);
notification.setLatestEventInfo(feedGetter.service.getApplicationContext(), title, subtext, contentIntent);
mNotificationManager.cancel(video? 1 : 0);
mNotificationManager.notify(video? 1 : 0, notification);
//Update new time if necessary.
if(time > feedGetter.newTime){
feedGetter.newTime = time; //New time will be the time for this feed as it is the latest so far
}
}
}
As you see I add some data to the intent so I can handle the notifications correctly. The notifications are assigned to an ID for videos or an ID for articles and should replace the previous notifications. Here is the NotificationActivity that handles the notifications:
public class NotificationActivity extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Debug.out("Notification Activity");
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if(getIntent().getBooleanExtra("video", true)){
//Handle video notification
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(getIntent().getStringExtra("url")));
startActivity(browserIntent);
mNotificationManager.cancel(1);
}else{
//Start application UI and move to article
Intent intent = new Intent(this,TheLibertyPortalActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("url", getIntent().getStringExtra("url"));
intent.putExtra("body", getIntent().getStringExtra("body"));
intent.putExtra("date", getIntent().getStringExtra("date"));
intent.putExtra("title", getIntent().getStringExtra("title"));
startActivity(intent);
mNotificationManager.cancel(0);
}
finish();
}
}
So it's supposed to activate a URL for the videos and restart the application for articles with some data for handling the articles so the article is displayed to the user.
Seems simple enough but it doesn't work. The notifications display and they replace each other on the notification menu, showing the latest notifications for videos and articles but when I click on them they go wrong. I try to click on the article notification and it thinks it is a video and loads one of the videos. I go back onto the notification menu and the video notification has disappeared even when I clicked on the article notification. I try clicking on the article notification and nothing happens. It literally closes the menu and doesn't nothing and the notification remains in the menu doing nothing.
Thank you for any help with this. I am targeting the Google APIs level 14 API, with a min SDK version of level 8, trying with a 2.2.1 Android tablet.
The problem is with the Pending intent. Even though the docs say the requestCode is not used, it is. You must pass a unique integer for each PendingIntent. That worked!