how to schedule a task every night at 12 AM - android

I want to start ScheduledExecutorService exactly on 12 AM daily, but in my code schedule is not started. Can any one tell me Whether my code is Correct or not? If any other way available that would also helpful
public class MainActivity extends AppCompatActivity{
ScheduledExecutorService scheduler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scheduler = Executors.newScheduledThreadPool(1);
scheduleTask();
}
public void scheduleTask() {
final Runnable beeper = new Runnable() {
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(),"SCHEDULE STARTED",Toast.LENGTH_LONG).show();
}
}
}
}, 1500);
}
});
}
};
Calendar midnight = Calendar.getInstance();
midnight.set(Calendar.HOUR_OF_DAY, 0);
midnight.set(Calendar.MINUTE, 0);
midnight.set(Calendar.SECOND, 0);
midnight.set(Calendar.MILLISECOND, 1);
midnight.set(Calendar.DAY_OF_YEAR, midnight.get(Calendar.DAY_OF_YEAR) + 1);
long tillMidnight = midnight.getTimeInMillis() - System.currentTimeMillis() - 1;
long ticksTillMidnight = tillMidnight / 50;
final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(beeper, ticksTillMidnight,20*60*60*24, TimeUnit.MILLISECONDS
);
scheduler.schedule(new Runnable() {
public void run() {
beeperHandle.cancel(true);
}
}, 6*6, TimeUnit.MILLISECONDS
);
}}

The answer is quite simple. In your case, a ScheduledExecutorService is bound to the lifetime of your process. If your process gets killed, then the ScheduledExecutorService will get killed along with it. Instead use an AlarmManager
Here are 3 steps
Create the Alarm
Create the BroadcastReceiver
Register the Receiver in the App Manifest
1. Create the Alarm
public void createAlarm() {
//System request code
int DATA_FETCHER_RC = 123;
//Create an alarm manager
AlarmManager mAlarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//Create the time of day you would like it to go off. Use a calendar
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
//Create an intent that points to the receiver. The system will notify the app about the current time, and send a broadcast to the app
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, DATA_FETCHER_RC,intent, PendingIntent.FLAG_UPDATE_CURRENT);
//initialize the alarm by using inexactrepeating. This allows the system to scheduler your alarm at the most efficient time around your
//set time, it is usually a few seconds off your requested time.
// you can also use setExact however this is not recommended. Use this only if it must be done then.
//Also set the interval using the AlarmManager constants
mAlarmManager.setInexactRepeating(AlarmManager.RTC,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, pendingIntent);
}
2. Create the BroadcastReceiver
//This is the broadcast receiver you create where you place your logic once the alarm is run. Once the system realizes your alarm should be run, it will communicate to your app via the BroadcastReceiver. You must implement onReceive.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Your code once the alarm is set off goes here
//You can use an intent filter to filter the specified intent
}
}
3. In your app manifest register the receiver
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.package">
//This is a useful permission as it allows your apps alarm to still be active once a reboot takes place
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".MainActivity$AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>

Related

BroadcastReceiver not being triggered when app is closed

I'm attempting to make it so my app runs some code once per day at 6AM. This works just fine when the app is open and in the foreground, but if the app is closed by swiping it away, the code is never called at the appropriate time.
AlarmReceiver.java (For testing purposes, I have it just trying to display a Toast to verify it runs)
public class AlarmReceiver extends BroadcastReceiver {
public static final String intentAction = "com.mpagliaro98.action.NOTIFICATIONS";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(intentAction)) {
Toast.makeText(context, "RECEIVER CALLED", Toast.LENGTH_LONG).show();
}
}
}
MainActivity.java (Where the alarm is being set)
public class MainActivity extends AppCompatActivity {
...
private void setRecurringAlarm() {
// Set this to run at 6am
Calendar updateTime = Calendar.getInstance();
updateTime.setTimeZone(TimeZone.getDefault());
updateTime.set(Calendar.HOUR_OF_DAY, 6);
updateTime.set(Calendar.MINUTE, 0);
updateTime.set(Calendar.SECOND, 0);
updateTime.set(Calendar.MILLISECOND, 0);
// Build the pending intent and set the alarm
Intent i = new Intent(AlarmReceiver.intentAction);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(),
0, i, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
assert am != null;
am.setRepeating(AlarmManager.RTC, updateTime.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
}
}
AndroidManifest.xml (Just the relevant parts)
<uses-permission android:name="android.permission.SET_ALARM" />
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.mpagliaro98.action.NOTIFICATIONS" />
</intent-filter>
</receiver>
I've read through dozens of similar problems to this on this site and elsewhere and I'm seriously at a loss for why this won't work. Any help would be appreciated.
Try changing receiver to
<receiver android:process=":remote" android:name="AlarmReceiver"></receiver>
Should I use android: process =":remote" in my receiver?

Android Service Start is not working when app start?

I am try to set a alarm to restart app on 8:30.am in every day , so I design service and receiver,
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
</intent-filter>
</receiver>
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_SCREEN_ON.equals(action)){ //not working ?
Log.d("BootReceiver", "screen on completed");
Intent Alarm = new Intent(context,LongRunningService.class); //start Service
context.startService(Alarm);
}
if (Intent.ACTION_BOOT_COMPLETED.equals(action)){ //not working ?
Log.d("BootReceiver", "system boot completed");
Intent Alarm = new Intent(context,LongRunningService.class); //start Service
context.startService(Alarm);
}
if ("startAlarm".equals(intent.getAction())){
Intent home = new Intent(context, MainActivity.class);
home.putExtra("RELOAD",1);
home.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(home);
}
LongRunningService.java
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable(){
#Override
public void run() {
Log.i(TAG, "run: executed at "+ new Date().toString()); //not working?
}
}).start();
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 00);
}
In fact , I start service in MainActivity , but I don't want to start service
onCrate in MainActivity , because My alarm set 8:30 to restart MainActivity,
that will be problem , 8:30:00 ~ 8:30:30 will repeat restart my app....
According to docs
Apps that target Android 8.0 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. An implicit broadcast is a broadcast that does not target that app specifically
So, if you want receive this broadcast you need to register them during app run (and it will work only if you app not destroyed).
JobScheduler will better fit your needs, i think.

how to repeat alarm in background

I am trying an alarm for every fifteen minute and problem is that I hear that alarm will work when app is not running, but in my case alarm works first time and even second time if app is on screen. else not.also I want to know when first alarm is set and time was in previous time,alarm will start in recent time, but if I set pending intent for 24 hours and at that time mobile was shut down and I turned my mobile after one or two hours, will pending intent that was for a day work after 25 or 26 hours or not.please help
here is my code.
public class MainActivity extends AppCompatActivity {
Calendar calendar=Calendar.getInstance();
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn=(Button)findViewById(R.id.bt);
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,13);
calendar.set(Calendar.MINUTE,54);
calendar.set(Calendar.SECOND,1);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,13);
calendar.set(Calendar.MINUTE,54);
calendar.set(Calendar.SECOND,1);
setAlarm(calendar.getTimeInMillis());
}
});
}
private void setAlarm(long time) {
calendar.setTimeInMillis(System.currentTimeMillis());
//getting the alarm manager
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//creating a new intent specifying the broadcast receiver
Intent i = new Intent(this, MyAlarm.class);
//creating a pending intent using the intent
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
//setting the repeating alarm that will be fired every day
am.setRepeating(AlarmManager.RTC, time, AlarmManager.INTERVAL_FIFTEEN_MINUTES, pi);
Toast.makeText(this, "Alarm is set", Toast.LENGTH_SHORT).show();
}
}
and here is my service
public class MyAlarm extends BroadcastReceiver{
MediaPlayer mp;
#Override
public void onReceive(Context context,Intent intent){
mp=MediaPlayer.create(context,R.raw.song);
mp.start();
}
}
manifest is here
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bilal.pkr">
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.BOOT_COPLETED"></action>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".MyAlarm"
android:enabled="true"
android:exported="true" />
</application>
</manifest>
am.setRepeating(AlarmManager.RTC_WAKEUP, time, AlarmManager.INTERVAL_FIFTEEN_MINUTES, pi);
Use this.

Pending Intent Fires Immediately

I am trying to make an app that allows the user to enter two times using two TimePickers and the phone will set to silent between these times. I am using PendingIntent and AlarmManager to trigger the BroadcastReceiver at the times the user chooses.
At the moment, it is setting the phone on and off silent immediately when the user clicks the save button. My "alarm scheduled" toast then appears and my "broadcast received" appears twice but it doesn't do anything after that.
Here is my main activity code:
public class MainActivity extends AppCompatActivity {
AlarmManager alarm;
TimePicker timePickerStart;
TimePicker timePickerEnd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timePickerStart = (TimePicker)findViewById(R.id.timePickerStart);
timePickerStart.setIs24HourView(true);
timePickerEnd = (TimePicker)findViewById(R.id.timePickerEnd);
timePickerEnd.setIs24HourView(true);
}
//method is called when save button is clicked
public void setAlarm(View view) {
Calendar calendarStart;
Calendar calendarEnd;
calendarStart = Calendar.getInstance();
calendarEnd = Calendar.getInstance();
//Set calendars to the times in both TimePickers
calendarStart.set(Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, timePickerStart.getCurrentHour(), timePickerStart.getCurrentMinute());
long startTimeMillis = calendarStart.getTimeInMillis();
calendarEnd.set(Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, timePickerEnd.getCurrentHour(), timePickerEnd.getCurrentMinute());
long endTimeMillis = calendarEnd.getTimeInMillis();
//create an intent and set the class that will be triggered by the intent
Intent intent = new Intent(MainActivity.this, Receiver.class);
PendingIntent pIntent = null;
pIntent = PendingIntent.getBroadcast(this, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//create alarm manager
alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//set alarms to go off at the time specified by the timePickers
alarm.set(AlarmManager.RTC_WAKEUP, calendarStart.getTimeInMillis(), pIntent);
alarm.set(AlarmManager.RTC_WAKEUP, calendarEnd.getTimeInMillis(), pIntent);
//Toast for feedback
Toast.makeText(this, "Alarm Scheduled", Toast.LENGTH_SHORT).show();
}
Here is my BroadcastReceiver:
public class Receiver extends BroadcastReceiver {
AudioManager audioManager;
int modeNum;
#Override
public void onReceive(Context context, Intent intent) {
//toast for feedback
Toast.makeText(context, "Broadcast Received", Toast.LENGTH_SHORT).show();
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
modeNum = audioManager.getRingerMode();
if (modeNum == 0) {
audioManager.setRingerMode(2);
} else {
audioManager.setRingerMode(0);
}
}
}
This is my Manifest:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".Receiver"></receiver>
</application>
You have multiple problems.
First, you are trying to create two alarms with the same PendingIntent. That will not work. Your second alarm request will cancel the first one. You need distinct PendingIntent objects, which means either substantially different Intent objects wrapped by the PendingIntent objects, or use two different values where you have 123.
Second, your set() calls on Calendar are incorrect. For example, in both places, your first parameter is supposed to be year. You are passing Calendar.YEAR, which is 1, not 2015.

Sending SMS in background after first bootup

I want to send an SMS without user intervention so I crated a BroadcastReceiver to solve this problem. This BroadcastReceiver will receive "BOOT_COMPLETED" notification at bootup. In the OnReceive function we can send SMS (After 5 minutes of bootup). I tried this logic but it is not working.
I came to know from some other posts on this site that after Android 3.1+ we cannot use this kind of logic to meet this requirement. But I tried this logic on Android 2.3 and it seems that it is not working there either.
Please suggest to me how to solve this problem on Android 2.3 and Android 4.0+ versions. I don't want to create any UI for this requirement.
I am trying following piece of code.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.CountDownTimer;
import android.telephony.SmsManager;
import android.util.Log;
class MyCountDownTimer extends CountDownTimer {
private int no_of_attempts;
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
no_of_attempts = 0;
}
#Override
public void onFinish() {
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("+9198104084753", null, "Test Message ", null, null);
} catch (Exception e) {
Log.d("BGSMS","SMS Sending failed..Try to resend SMS");
no_of_attempts++;
if (no_of_attempts <= 3)
{
long startTime = 5 * 1000;
long interval = 1 * 1000;
CountDownTimer countDownTimer;
countDownTimer = new MyCountDownTimer(startTime, interval);
countDownTimer.start();
}
}
}
#Override
public void onTick(long millisUntilFinished) {
}
}
public class SalestrackerReceiver extends BroadcastReceiver {
private CountDownTimer countDownTimer;
private final long startTime = 5 * 1000;
private final long interval = 1 * 1000;
#Override
public void onReceive(Context context, Intent intent) {
Log.v("Anshul","Anshul Broadcast receiver received");
countDownTimer = new MyCountDownTimer(startTime, interval);
countDownTimer.start();
}
}
Manifest File :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sales_tracker"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="10" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="SalestrackerReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
You have to create one service,which going to send sms after 5 min.
In Broadcastreceiver call your service.
public class MyReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
TimerTask hourlyTask = new TimerTask () {
#Override
public void run () {
Intent myIntent = new Intent(context,MyService.class);
startService(myIntent);
}
};
// schedule the task to run starting now and then every hour...
timer.schedule (hourlyTask,5000 * 60 * 1);
}
}
}
in myservice class you write code to send sms in Onstart() method.
You should start a service from your onReceive method in your (BOOT_COMPLETED) BroadcastReceiver.
See here:
http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html#startingservices_alarmmanager
Also note:
If you application is installed on the SD card, then it is not available after the android.intent.action.BOOT_COMPLETED event. Register yourself in this case for the android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE event.
Also note that as of Android 3.0 the user needs to have started the application at least once before your application can receive android.intent.action.BOOT_COMPLETED events.
Use pending Intent and Alarm Manager for send message after 5 minutes of boot up.
Intent i = new Intent(this,Shedulesms.class);
Bundle msg = new Bundle();
msg .putString("number", "1234567890");
msg .putString("message", "This is test message");
i.putExtras(msg );
PendingIntent pu=PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_ONE_SHOT);
AlarmManager am=(AlarmManager)getSystemService(ALARM_SERVICE);
Calendar cal= Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.MINUTE,cal.get(Calendar.MINUTE)+5);
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),pu);
in Shedulesms.java
enter code here
SmsManager sms=SmsManager.getDefault();
Bundle b=getIntent().getExtras();
String number=b.getString("number");
String msg=b.getString("message");
sms.sendTextMessage(number, null,msg, null, null);
Give Permission in android manifiest file
<uses-permission android:name="android.permission.SEND_SMS" />
and register broadcast receiver in manifiest
As described in some answers in Trying to start a service on boot on Android, some phones have a fastboot-option. To support these phones, add
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
to your intent-filter.

Categories

Resources