what approach should i follow to make Timer service in android - java

I am working on an interval timer which make an alarm every interval (E.g. 30mins).
I want to make the timer work in background or when device is in sleep and show a notification,
I was told to use Intent Service but its deprecated. what should i use?
-I want to support until API 21

You need to create a BroadcastReceiver. For example, using AlarmManager:
int repeatTime = 30; //Repeat alarm time in seconds
AlarmManager processTimer = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, processTimerReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
//Repeat alarm every second
processTimer.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(),repeatTime*1000, pendingIntent);
And create your processTimerReciever class:
//This is called every second (depends on repeatTime)
public class processTimerReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//Do something every 30 seconds
}
}
Remember to register into Manifest:
<receiver android:name="processTimer" >
<intent-filter>
<action android:name="processTimerReceiver" >
</action>
</intent-filter>
</receiver>
EDIT:
If your app use an internet connection, you can send every 30 mins a notification using Firebase

Related

AlarmManager gets canceled after a while

I am writing my first app and I'm trying to fire a notification at a specific time every day that reports some information.
For starter, I created the following class that I use to restart the alarms after a reboot and to start the alarms from the main app (this to have just one piece of code to reuse).
public class SetAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
startReminderService(context);
}
public void checkServiceRunning(Context context) {
Intent reminderIntent = new Intent(context, AlarmReceiver.class);
reminderIntent.setAction("MyReminder");
// I check if a reminder is already active
boolean reminderActive = (PendingIntent.getBroadcast(context, REMINDER_SERVICE,
reminderIntent,
PendingIntent.FLAG_NO_CREATE) != null);
Log.d("test", "The reminder is active?" + reminderActive);
if (!reminderActive) {
startReminderService(context);
}
}
public void startReminderService(Context context) {
Calendar serviceNotificationTime = Calendar.getInstance();
serviceNotificationTime.set(Calendar.HOUR_OF_DAY, 9);
serviceNotificationTime.set(Calendar.MINUTE, 0);
serviceNotificationTime.set(Calendar.SECOND, 0);
Intent reminderIntent = new Intent(context, AlarmReceiver.class);
reminderIntent.setAction("MyReminder");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
REMINDER_SERVICE,
reminderIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager serviceAlarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
serviceAlarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
serviceNotificationTime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
pendingIntent);
if (pendingIntent != null) {
Log.d("test", "Background service set up and running.");
} else {
Log.d("test", "Failed to set up background service!");
}
}
}
After that I updated the manifest with the following lines:
<receiver
android:name="com.mycompany.myapp.services.SetAlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="com.mycompany.myapp.services.AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="MyReminder" />
</intent-filter>
</receiver>
So far, everything goes right. When the phone reboots, the reminder is correctly restarted and (if the reminder time is in the past) it fires immediately.
The AlarmReceiver class is the following:
public class AlarmReceiver extends BroadcastReceiver {
private Context ctx;
#Override
public void onReceive(Context context, Intent intent) {
this.ctx = context;
remindStuff();
}
private void remindStuff() {
....
some code
....
// I check if the alarm is still on (probably awful, since it just fired)
SetAlarmReceiver setAlarmReceiver = new SetAlarmReceiver();
setAlarmReceiver.checkServiceRunning(ctx);
}
}
I use the same approach to check if the alarm is on from the main activity:
private void checkServicesRunning() {
SetAlarmReceiver setAlarmReceiver = new SetAlarmReceiver();
setAlarmReceiver.checkServiceRunning(getApplicationContext());
}
Everything looks correct to me, I've tried any solution I found, reading tons of questions like mine on StackOverflow but I still can't understand what I'm doing wrong.
The alarm fires correctly right after BOOT_COMPLETED is triggered by the system and it fires correctly when I just enabled the alarm (only if the notification time is in the past - f.e. when it's 10pm and the alarm must fire at 9am).
When the checkServiceRunning method runs, it tells me that the alarm is already enabled (returning true in the Logcat) but when I close the app and I re-run it after a while, the alarm looks like it's been canceled and it's being recreated by the app.
Any hint?
Thanks.
EDIT: I tried the command 'adb shell dumpsys alarm' and it actually shows my alarm running correctly so, at this point, I think the issue is something else but I cannot understand what...

Alarm Manager not starting after 60 seconds

I'm trying to set my alarm manager working, just simple schedule, firing toast every minute, but it's not working, what's wrong with the code?
Main Activity :
public void klik(View view) {
startalarm();
}
public void startalarm(){
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent;
PendingIntent pendingIntent;
intent = new Intent(this, AlarmToastReciever.class);
pendingIntent = PendingIntent.getBroadcast(this,0,intent,0);
manager.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime()+3000,+60000,pendingIntent);
}
}
AlarmToastReciever class :
public class AlarmToastReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent){
Toast.makeText(context,"GOWNO", Toast.LENGTH_SHORT).show();
}
}
As stated in documentation
As of Android 4.4 (API Level 19), all repeating alarms are inexact. Note that while setInexactRepeating() is an improvement over setRepeating(), it can still overwhelm a server if every instance of an app hits the server around the same time. Therefore, for network requests, add some randomness to your alarms, as discussed above.
You can use "setInexactRepeating()" or set an exact one time alarm then set next alarm in On Receive method
Also make sure you added your receiver to the manifest file, between application tag, like
<receiver android:name=".AlarmToastReciever"
android:enabled="true">
<intent-filter>
</intent-filter>
</receiver>
Use this code to initialize alarm manager.
public void setupAlarm() {
final Calendar calNow = Calendar.getInstance();
final Calendar calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, calNow.get(Calendar.HOUR_OF_DAY));
calSet.set(Calendar.MINUTE, calNow.get(Calendar.MINUTE) + 1);
calSet.set(Calendar.SECOND, calNow.get(Calendar.SECOND));
final Intent intent = new Intent(this, UploadStarterReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1,
intent, 0);
final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
60 * 1000, pendingIntent);
}

Android How to set exact repeating alarm?

I'm building an alarm application which will have an exact repeating alarm.
Seeing how for Repeating Android provides only Inexact alarm with possible delay of 75% of chosen interval, I've tried making Exact alarm which upon triggering sets itself once again. This type of alarm works perfectly as long as my screen is kept on. But as soon as it goes to sleep, the alarm works fine the first time, but second alarm which is set programmaticaly fires with delay as if I was using Inexact method.
As an alternative solution I'm thinking of making an InexactRepeating alarm which will fire up every minute to check whether it's "the time". This way my alarm will be with 2 minute imprecision interval, which is acceptable. But I'm not sure how much it will strain phone's battery.
Any ideas guys?
Here's my attemp at Exact alarm:
AlarmManager.java
public static void setAlarm(Context context){
AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
//SET BROADCAST RECEIVER WHICH WILL BE THE ONE TO LISTEN FOR THE ALARM SIGNAL
Intent intent = new Intent(context, AlarmTriggerBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 22222, intent, PendingIntent.FLAG_CANCEL_CURRENT);
//SETING THE ALARM
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 300000, pendingIntent);
} else {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 300000, pendingIntent);
}
}
AlarmTriggerBroadcastReceiver.java
public class AlarmTriggerBroadcastReceiver extends BroadcastReceiver {
private final static String TAG_ALARM_TRIGGER_BROADCAST = "ALARM_TRIGGER_BROADCAST";
#Override
public void onReceive(Context context, Intent intent) {
//WAKE UP DEVICE
WakeLocker.acquire(context);
//LAUNCH PAGE
Intent intent1 = new Intent();
intent1.setClassName(context.getPackageName(), SomeActivity.class.getName());
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
Toast.makeText(context, "TOAST ALARM", Toast.LENGTH_LONG).show();
};
//SET NEW ALARM
AlarmManagerActivity.setAlarm(context);
WakeLocker.release();
}
}
WakeLocker.java
//WAKES UP DEVICE IF PHONE'S SCREEN LOCKED
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context ctx) {
//if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, "myapp:WAKE_LOCK_TAG");
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
Manifest
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.SET_ALARM"/>
<receiver
android:name=".Alarm.AlarmTriggerBroadcastReceiver"
android:process=":remote">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
<intent-filter android:priority="1">
<action android:name="my.app.here.ALARM_RECIEVED" />
</intent-filter>
</receiver>
What do, fellow coders?
have you tried using a WorkManager instead of having to use the Broadcast Receivers? See details here. And an app demo here.

Alarm not going off when app killed

How am I supposed to implement an alarm to open the dismiss/snooze screen after the app is destroyed? My alarm works perfectly fine as long as the app stays up, here's how I schedule the alarm:
//instantiate calendar to call alarm on time match
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute());
//if time is set earlier than current (e.g set for 6:59pm, currently 7pm), do not play until next clock cycle/day
if(calendar.before(Calendar.getInstance())) {
calendar.add(Calendar.DATE, 1);
}
//cancel any currently pending intents if toggle button is toggled on
Intent myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT).cancel();
//add parameters to pass to activities that play the alarm
myIntent.putExtra("stream",stream);
myIntent.putExtra("seconds",snoozeSeconds);
myIntent.putExtra("link",ytLink);
//create pending intent to broadcast to activity that plays the alarm
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);
alarmManager.setExact(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
And I use a receiver that's fairly simple:
public class AlarmReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
//....
MainActivity.ringtone.play();
Intent alarmIntent = new Intent(context, AlarmActivity.class);
context.startActivity(alarmIntent); //start dismiss screen
As per your question, This is what i understand, Let me know if misunderstand your question
if you want to open/active your alaram after App close or device reboot
then you have add intent filter android.intent.action.BOOT_COMPLETED in your AlarmReceiver AndroidManifest.xml and you can manage the actions on your AlarmReceiver onReceive methond
Please check the following code
public void onReceive(Context context, Intent intent) {
if(intent == null){
return;
}
String action = intent.getAction();
if (action != null && action.equalsIgnoreCase("android.intent.action.BOOT_COMPLETED")) {
}
AlarmReceiver.completeWakefulIntent(intent);
}
Add intent filter actions in your AndroidManifest.xml file
<receiver android:name="com.monster.android.Services.AlarmReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
You can use stopService() method:
stopService(new Intent(MainMenu.this, AlarmActivity.class));

Starting service in android to read message after fixed interval

I am able to read message of user when the application gets installed. But what I want is that even after the application is closed, I should be able to read user message after a fixed interval of time. For example, application like Walnut that reads specific message and gives alerts automatically if any new message has come. How can I do the same.
Use Alarm manager and Pending Intent
Initiate Alarm manager here.
AlarmManager alarmMgr = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
new Intent(this, AlarmReceiver_update.class),
PendingIntent.FLAG_CANCEL_CURRENT);
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
0, yourTimeInterval, pendingIntent);
And in AlarmReceiver_update class:
public class AlarmReceiver_update extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// Do whatever you want
}
}
And in Your AndroidManifest file register your receiver:
<receiver android:name="com.x.y.AlarmReceiver_update" >
<intent-filter>
<action android:name="android.test.BROADCAST" />
</intent-filter>
</receiver>
This is not complete just sample you have any doubt just comment.
You shuold use an alarm manager to set a repeating alarm.
Then you should setup a BroadcastReceiver Service that read the user messages onRecieve.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Run the task to read the user messages
}
}
This is a good tutorial
Have a look at the below links to learn how to notify the user if you found new message.
http://javatechig.com/android/repeat-alarm-example-in-android#3-defining-alarm-broadcastreceiver
http://developer.android.com/training/notify-user/build-notification.html

Categories

Resources