Getting Android Alarms Info - java

Iv'e created several Alarms using an Intent and BroadcastReciever and placed them in an Array of Intents.
For each Intent Iv'e placed a String as in Intent.PutExtra("info", string); to be shown later as a Toast when Alarm is activated,
and gave each a different requestCode.
But when adding multiple Alarms, the Toast shows EVERY other Alarms' info as well.
MainActivity:
Intent newAlarmIntent = new Intent(this,AlarmReceiver.class);
newAlarmIntent.putExtra("info",editText.getText().toString());
alarmsArray[alarmCounter]=newAlarmIntent;
alarm.AlarmListSortAndSetNext(gameArrayList, alarmArray, this,alarmCounter,alarmsArray[alarmCounter]);
Alarm Class:
public void CreateNew (Context context, Long alarmTimeAsLong, int counter, Intent intent)
{
PendingIntent pendingIntent;
pendingIntent = PendingIntent.getBroadcast(context, counter, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager manager;
manager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
manager.set(AlarmManager.RTC_WAKEUP, (alarmTimeAsLong),pendingIntent);
Toast.makeText(context, "Alarm Set", Toast.LENGTH_SHORT).show();
}
public void AlarmListSortAndSetNext (ArrayList<Game> gameArrayList,Long[] alarmArray,Context context,int alarmCounter, Intent intent)
{
Long SystemTimeAsLong = System.currentTimeMillis();
//Sorting Long Array for NEXT ALARM
for (int i=0;i<10;i++)
{if(i<gameArrayList.size()){
alarmArray[i] = gameArrayList.get(i).getDateAndTimeAsLong();
}
else alarmArray[i]= 0L;
}
Arrays.sort(alarmArray);
//Setting next ALARM by Long Size
for(int i=0;i<10;i++)
{
if (alarmArray[i]>SystemTimeAsLong){
CreateNew(context,alarmArray[i],alarmCounter,intent);
alarmCounter++;}
}}
AlarmReceiver:
public class AlarmReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager) context.getApplicationContext().getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
wakeLock.acquire();
String gameInfo= intent.getStringExtra("info");
Toast.makeText(context, gameInfo, Toast.LENGTH_SHORT).show();
MediaPlayer mp = MediaPlayer.create(context, R.raw.bipbip);
mp.start();
wakeLock.release();}}
QUESTION: How can I make each Intent to have it's on "info"/PutExtra, or any other way to tell which one has been activate?

* Found the issue *
I had left the AlarmListSortAndSetNext method which initially was supposed to manage the Next Alarm. I no longer have to use this method since I have created multiple Intents. Something in the looping probably created multiple putExtra();
Thank you.

Related

Show alert instead of scheduled notification if the app is currently opened

I have an app that schedules a bunch of notifications (user has to answer questionnaires) locally using AlarmManager. The notification should show at certain points in the future.
I schedule the notifications like this:
private void scheduleNotification(Notification notification, int delay, int scheduleId, int notificationId) {
Intent notificationIntent = new Intent(context, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, notificationId);
notificationIntent.putExtra(NotificationPublisher.INTENT, notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, scheduleId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, delay);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
The intent is received by a BroadcastReceiver that calls notify on the notification attached to the intent.
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id";
public static String INTENT = "notification";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra(INTENT)) {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
Notification notification = intent.getParcelableExtra(INTENT);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
}
}
}
This works fine so far. The problem that I'm facing is that I only want to show the notification if the app is currently not open/shown. If it's open I want to show an AlertDialog instead.
I know that it might be a better idea to put only the plain content of the notification into the intent and only build it when it should be displayed and I want to refactor that later on.
My main problem is, how do I determine in the onReceive of my broadcast receiver if the app is currently showing to decide if a notification or an alert should be displayed?
Or is there an entirely different approach that might work better (for example using WorkManager)?
I think you can handle it on your BroadcastReceiver
public void onReceive(Context context, Intent intent) {
if (isForeground(context))
// AlertDialog
else
// Notification
}
public boolean isForeground(Context mContext) {
ActivityManager activityManager = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.AppTask> tasks = activityManager.getAppTasks();
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).getTaskInfo().topActivity;
return topActivity.getPackageName().equals(mContext.getPackageName());
}
return true;
}

BroadcastReceiver received more than once

I am getting a problem with my reminder APP.
When I add first reminder broadcast is received once for second time broadcast is received twice for third time it is received thrice.
I tried many different solutions on StackOverfolow but none of them are working
Kindly help me out with detailed answer.
Link to Project
. code is given below:
Function to set Reminder:
public void startAlarm(Calendar c) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, number, intent, PendingIntent.FLAG_ONE_SHOT);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
Class receiving Broadcast:
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, intent.getAction(), Toast.LENGTH_LONG).show();
MediaPlayer mediaPlayer = MediaPlayer.create(context, Settings.System.DEFAULT_NOTIFICATION_URI);
mediaPlayer.start();
}
}
I see that you are setting the alarm inside Adapters onBindViewHolder. This is not the right place to setting alarm. Because when you call notifyDataSetChanged it will call onBindViewHolder again and it will set same alarm over and over.

How Do I getText().toString() a TextView Using RemoteViews?

I'm developing a widget for the first time, and remoteviews is a bit confusing compared to building an app.
I understand this part...
RemoteViews views = new Remoteviews(context.getPackageName(), R.layout.my_widget_layout);
views.setTextViewText(R.id.myTV, "Hello World");
Now the next is a bit complex for me. I want the button that I have on the widget to pass the TextView text and display it on a toast.
Here's what I started...
Intent myIntent = new Intent(context, myReceiver.class);
PendingIntent myPendingIntent = PendingIntent.getBroadcast(context, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.myButton, myPendingIntent);
My Class (This is where I need help!)
public static class myReceiver extends BroadcastReceiver{
Override
public void onReceive(Context context, Intent intent){
Toast.makeText(context, (HELP! I need to getText().toString() from the R.id.myTV), Toast.LENGTH_SHORT).show();
}
}
Thanks! Much appreciated!
You can add the text you want to display to the intent via putStringExtra method and then extract the extra string like this:
#Override
public void onReceive(Context context, Intent intent) {
AppWidgetManager mgr = AppWidgetManager.getInstance(context);
if (intent.getAction().equals(check-your-desired-action-here)) {
String textThatYouWantToDisplay = intent.getStringExtra("name-of-the-desired-item");
Toast.makeText(context,textThatYouWantToDisplay , Toast.LENGTH_SHORT).show();
}
super.onReceive(context, intent);
}
for more info:
this sample widget app from google
Build an app widget android document
Intent getStringExtra method

Pop up window after the alarm signal - Android

I would like to know - how to show pop up window when AlarmManager will call? I've already created AlarmManager now I need to create something what will show popup window to cancel this Alarm.
My code:
public void setAlarm(long timeInMillis){
if(Build.VERSION.SDK_INT >= 23){
mCalendar.set(
mCalendar.get(Calendar.MONTH),
mCalendar.get(Calendar.YEAR),
mCalendar.get(Calendar.DAY_OF_YEAR),
mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE)
);
}
final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarm.class);
intent.setData(currentUri);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.setExact(AlarmManager.RTC, timeInMillis, pendingIntent);
}
and
public class MyAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
MediaPlayer mediaPlayer = MediaPlayer.create(context, Settings.System.DEFAULT_RINGTONE_URI);
mediaPlayer.start();
}
}
onReceive(context, intent) {
/*show the dialog in this method. set the onclick so it can dismiss the alarm,
get the value for the alarm from the bundle. I may be wrong about this
but i think alarmManager has a cancel(PendingIntent operation) method that u can
just send in the intent and your done.
Call a stopMedia(context) method after the cancel in order to stop the media
that is playing
*/
showDialog(context, intent)
//Extract the play media code to a method for readability
playMedia(context)
}
That should solve your problem
Before the code was posted:
We can either use the pending intent and have an activity that handles the pending intent. or use the handler to execute the code.
In either case, create a dialog fragment and then use the appropriate context to show it. setOnClickListener { alarmManager.cancel } for the dialog fragment button.
A little more explanation may be required depending on how the alarm manager is setup

Simple AlarmManager example for firing an activity in 10 minutes

I've found many similar questions to this, but they're too complicated (too much code), at least I think.
Can this thing be done in a few code of lines? I want to fire an activity in 10 (let's say) minutes, that's it. Thank you.
To Set Alarm for 10 Minutes(let's say) Use this code
AlarmManager alarmMgr = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, ShortTimeEntryReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),10*60*1000, pendingIntent);
To Start Activity
public class ShortTimeEntryReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
// Your activity name
Intent newIntent = new Intent(context, ReminderPopupMessage.class);
newIntent.putExtra("alarm_message", message);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
In your Manifest File Add the following
<receiver android:name=".ShortTimeEntryReceiver"
android:enabled="true"
android:process=":remote">
</receiver>
This function I use sets or cancels an alarm depending on the "Set" parameter
public static void SetAlarm(Context c, long AlarmTime, int ItemID, String Message, Boolean Set) {
Intent intent = new Intent(c, AlarmReceiver.class);
intent.putExtra("Message", Message);
intent.putExtra("ItemID", ItemID);
PendingIntent sender = PendingIntent.getBroadcast(c, 8192 + ItemID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Clear the seconds to 0 for neatness
Calendar ca = Calendar.getInstance();
ca.setTimeInMillis(AlarmTime);
ca.set(Calendar.SECOND, 0);
AlarmTime = ca.getTimeInMillis();
// Get the AlarmManager service
AlarmManager am = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
if (Set) {
am.set(AlarmManager.RTC_WAKEUP, AlarmTime, sender);
} else {
am.cancel(sender);
}
}
You would then need a Broadcast Receiver to handle the alarm and do whatever it is you want to do.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String Message = bundle.getString("Message");
int ItemID = bundle.getInt("ItemID");
// Do what you want to do, start an activity etc
} catch (Exception e) {
e.printStackTrace();
}
}
}

Categories

Resources