I've an alarm which opens an activity at a time chosen by the user. If the user hits the start button, the alarm goes fine but it gets cancelled after reboot. I've looked everywhere and it says that I should use a service. Is it possible to keep the alarms on after the reboot without using service? I'm new to coding so can you please breakdown what I need to do. Thank you
public class MainActivity extends AppCompatActivity {
Button disable;
Button start;
TimePicker timePicker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timePicker = (TimePicker) findViewById(R.id.timePicker);
disable = (Button) findViewById(R.id.disable_alarm);
start = (Button) findViewById(R.id.button);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, timePicker.getHour());
calendar.set(Calendar.MINUTE, timePicker.getMinute());
Intent intent = new Intent(getApplicationContext(),notification.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 120*1000, pendingIntent);
}
});
disable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),notification.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
});
and Broadcast Receiver is
public class notification extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent scheduledIntent = new Intent(context, pop_up2.class);
scheduledIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(scheduledIntent);}}
Thanks
All of the active alarms are cancelled after phone is shutdown. In order to reset the alarms you need to use a separate broadcast receiver that will receive only boot completed action. The receiver then starts service that will reset all your alarms in background. Best one for you is IntentService, because it ends itself when the work is done. Of course you need to store the information about alarms somewhere in order to remember which ones to reset. You can use, for example, SQLite to store them.
In your manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and
<receiver android:name="developer.marat.apps.days.Alarms.BootCompletedReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="developer.marat.apps.days.Alarms.RestartAlarmsService"/>
Special receiver:
public class BootCompletedReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent i = new Intent(context, RestartAlarmsService.class);
ComponentName service = context.startService(i);
}
}
}
RestartAlarms:
public class RestartAlarmsService extends IntentService{
public RestartAlarmsService() {
super("RestartAlarmsService");
}
#Override
protected void onHandleIntent(Intent intent) {
// Restart your alarms here.
// open database, iterate through every alarm and set them again
}
}
Related
I am working on an Android app and I want to activate a daily Alarm (I used 5 min interval just as an example to test).
I used a Brodacast receiver (Static one declared in the manifest file),
but the app still doesn't work. Here's my code:
The Manifest file:
</activity> <receiver android:name=".ExecutableService" android:enabled="true" ></receiver </application>
The AlarmHandler class:
public class AlarmHandler {
private Context context;
public AlarmHandler(Context context) {
this.context = context;
}
//This will active the alarm
public void setAlarmManager(){
Intent intent = new Intent(context,ExecutableService.class);
PendingIntent sender = PendingIntent.getBroadcast(context ,2,intent,0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
long triggerAfter=60*5*1000;//this will trigger the service after 5 min
long triggerEvery=60*5*1000;//this will repeat alarm every 5 min after that
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,triggerAfter,triggerEvery,sender);
}
}
//This will cancel the alarm
public void cancelAlarm (){
Intent intent = new Intent(context,ExecutableService.class);
PendingIntent sender = PendingIntent.getBroadcast(context,2,intent,0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.cancel(sender);
}
}
}
This is the Broadcast receiver:
import ...
public class ExecutableService extends BroadcastReceiver {
private static final String TAG="Executable Service";
#Override
public void onReceive(Context context, Intent intent) {
//this will be executed at selected interval Notification show
Toast.makeText(context, "Hello World 2! ", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onReceive: it worked ");
Vibrator v=(Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
//deprecated in API 26
v.vibrate(500);
}}}
And this is the MainActivty where I activate the alarm:
public class MainActivity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
AlarmHandler alarmHandler = new AlarmHandler(this);
//cancel the previous scheduled alarm
alarmHandler.cancelAlarm();
//set the new alarm after one hour
alarmHandler.setAlarmManager();
Toast.makeText(this, "Alarm Set ! ", Toast.LENGTH_SHORT).show();
}
If this is not the way that I should use to run the app in the background and push a notification (or a simple toast at a specific time), what is the best way to do it?
I tried also jobscheduler services.
you set the alarm start time to long triggerAfter=60*5*1000;
I suggest changing this to
long triggerAfter =60*5*1000+ System.currentTimeMillis()
I am trying to create an app that will open another app at a specified time. To do this, I used an AlarmManager that starts a service. It works just fine if my app is open when the alarm is triggered. I get a notification that the service started, and the other app opens. However, if my app is in the background (after pressing the home button), and the alarm triggers, I get a notification that the service started, but the other app does not launch. What am I doing wrong? I am testing this on a Pixel 3 emulator running API level 29 (Android 10/Q).
MainActivity.java
public class MainActivity extends AppCompatActivity {
public static final int REQUEST_CODE=101;
public static int aHour;
public static int aMinute;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void setAlarm() {
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, amReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, aHour);
calendar.set(Calendar.MINUTE, aMinute);
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
//Some code that sets aHour and aMinute
//Some code that triggers setAlarm()
}
amReciever.java
public class amReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, launcherService.class);
ContextCompat.startForegroundService(getApplicationContext(), i);
}
}
launcherService.java
public class launcherService extends Service {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText("App is launching.")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
Intent launcher = getApplicationContext().getPackageManager().getLaunchIntentForPackage("com.example.app");
if (launcher != null) {
startActivity(launcher);
}
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<service android:name=".launcherService"
android:enabled="true"
android:exported="true" />
As of Android 10 (API level 29), you cannot start activities from the background anymore.
There are a number of exceptions to this rule that may or may not apply to your given scenario.
If none of the exceptions apply, you might want to consider displaying a high-priority notification, possibly with a full-screen Intent.
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);
}
I would create an alarm clock, i wrote this code but return this error:
2019-02-05 10:58:13.902 2663-10077/com.google.android.gms
E/ChromeSync: [Sync,SyncIntentOperation] Error handling the intent:
Intent { act=android.intent.action.PACKAGE_ADDED
dat=package:com.example.iacopo.alarmgroup flg=0x4000010
cmp=com.google.android.gms/.chimera.GmsIntentOperationService (has
extras) }.
How can i fix it? thanks
And this code doesn't create a icon af alarm in the notification panel, near the clock
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.clear();
cal.set(2018,1,5,10,0);
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
this.startService(intent);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
}
}
and the receiver
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("test","ok");
}
}
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));