Start service on boot and repeat - android

im trying to do somekind of auto GoogleDrive backup(uploading a file) timer, but i cant set the specific time, even if i set to 5 seconds(testing purpouse, it just run every 1minute) and when the user reboot the phone, it only RUN one time (the Alarm is not called =/, so the application has to be opened one time after the boot)
Manifest Configuration:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application...>
<receiver
android:name=".Tools.AutoBackupAlarmBroadCast"
android:process=":remote" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name=".Tools.AutoBackupService"
android:exported="false" />
</application>
and with this WakeBroadCast:
public class AutoBackupBootStarter extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, AutoBackupService.class);
context.startService(startServiceIntent);
}
}
make sure that the AutoBackupAlarm is called on boot, but it only happens ONE time, i need it to start the trigger to repeat by the user setted time(will get it from shared Preferences)
the service:
AutoBackupService:
public class AutoBackupService extends IntentService {
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
*/
public AutoBackupService() {
super("AutoBackup");
}
#Override
protected void onHandleIntent(Intent intent) {
WakefulBroadcastReceiver.completeWakefulIntent(intent);
//HERE i must start the Async to make the GoogleDrive Backup
//the next doubt will be how can i get sharedpreferences and activity to pass to the async from HERE?
Log.d("BACKUP", "AutoBackupLogTest");
}
}
the broadcast
public class AutoBackupAlarmBroadCast extends BroadcastReceiver {
public static final int REQUEST_CODE = 12345;
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, AutoBackupService.class);
i.putExtra("foo", "bar");
context.startService(i);
}
}
the AlarmFunction called on onCreate, that almost works how i want, it cant repeat every 5 seconds like the time below, it only show every 1 minute
public void scheduleAlarm() {
// Construct an intent that will execute the AlarmReceiver
Intent intent = new Intent(getApplicationContext(), AutoBackupAlarmBroadCast.class);
// Create a PendingIntent to be triggered when the alarm goes off
final PendingIntent pIntent = PendingIntent.getBroadcast(this, AutoBackupAlarmBroadCast.REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Setup periodic alarm every 5 seconds
long firstMillis = System.currentTimeMillis(); // alarm is set right away
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
// First parameter is the type: ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC_WAKEUP
// Interval can be INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_DAY
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
1 * 5 * 1000, pIntent);
}

Try below code to repeat task after particular time interval
boolean alarmUp = (PendingIntent.getBroadcast(this, 444, new Intent(this, AlarmReceiver.class), PendingIntent.FLAG_NO_CREATE) != null);
if(!alarmUp){
AlarmManager alarmManager = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
Intent DataSyncIntent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 444, DataSyncIntent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(),
15 * 60000, // 60000 = 1 minute,
pendingIntent);
}

Related

Alarm manager and broadcast receiver in force closed app

I want to do some network job periodically even when app if force closed.
Now it works until it's force closed.
What i am missing?
Also if i add to manifest this: android:process=":remote" - it's not triggering onReceive method (like app is force closed), but in logs i found that:
V/AlarmManager: triggered: cmp=com.cryptorulezz.cryptosignals/.Code.Alarm Pkg: com.cryptorulezz.cryptosignals
My code:
public class Alarm extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
// Put here YOUR code.
Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
System.out.println("ALARM !!!!!!!!!!!!!!!!!!!!");
wl.release();
}
public void setAlarm(Context context)
{
AlarmManager am =(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
//Intent i = new Intent(context, Alarm.class);
Intent i = new Intent("Coinsider.START_ALARM");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 1, pi); // Millisec * Second * Minute
}
public void cancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
How i set alarm in MainActivity:
Alarm alarm = new Alarm();
alarm.setAlarm(this);
Manifest:
<receiver android:name=".Code.Alarm" android:exported="false">
<intent-filter>
<action android:name="Coinsider.START_ALARM" >
</action>
</intent-filter>
</receiver>
Once the app gets force killed, it won't receive the intent and the intent filter won't be triggered. To overcome this, I suggest a sort of watchDog, that relies on some system events (like android.intent.action.BOOT_COMPLETED), that simply checks if one of your process is alive, and fires it if not. In the manifest, you 'd have something like this:
<receiver
android:name="it.angelic.receivers.WatchDogSetupReceiver"
android:process=":souliss_process">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.USER_PRESENT"/>
</intent-filter>
</receiver>
The class WatchDogSetupReceiver would then check if the dog is alive, and fire a new one if needed:
Intent i = new Intent(ctx, WatchDogEventReceiver.class); // explicit intent
PendingIntent patTheDog = PendingIntent.getBroadcast(ctx, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, now.getTimeInMillis(), 5000,
patTheDog);
Last, WatchDogEventReceiver would simply do the required un-killable job. It is important that the watchdog stays light, as it will be fired upon every screen on event. This solution is non-optimal, but works even after force-kill:
public class WatchDogEventReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context ctx, final Intent intent) {
Log.d(Constants.TAG + ":WatchDog", "WatchDog.onReceive() called, looking for Dataservice:");
ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
//Fire Service
Intent eventService = new Intent(ctx, YourDamnService.class);
ctx.startService(eventService);//sempre, ci pensa poi lui
}

AlarmManager keeps bringing activity to foreground

I'm trying to write code that will run in the background and call server APIs. Googling led me to use AlarmManager, here is my code:
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int interval = 4000;
Intent alarmIntent = new Intent(getApplicationContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmIntent, 0);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
The problem here though, is when my app is on the foreground (currently in android main menu, or on another app), whenever the alarm fires, it sends my activity to the front.
Anyone know why this happens and how I can avoid this? I have a service that is started by the AlarmReceiver class, and I want it to run on the background.
AlarmReceiver.class:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, LogService.class);
i.putExtra("param1", "index.html");
i.putExtra("param2",
"http://www.vogella.com/index.html");
context.startService(i);
}
}
LogService.class
public class LogService extends IntentService{
public LogService() {
super("LogService");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
String param1 = intent.getStringExtra("param1");
String param2 = intent.getStringExtra("param2");
Log.i("Hello from logservice!", "!!! -- " + param1 + " - " + param2);
}
}
Added stuff to manifest:
<receiver android:name="com.example.app.alarm.AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name="com.example.app.alarm.LogService" >
</service>
Thanks in advance!
After reading around, I've found out that since API 19, all repeating alarms are inexact. After knowing about this, I tried using the setRepeating function. I don't know why it behaves differently, but all is working as intended now.

AlarmManager fires late or doesn't fire at all

Hi everybody I'm trying to learn how to use AlarmManager and BroadcastReceiver in Android.
I'm having some problems with the AlarmManager:
I'm setting two alarms at 1 minute distance, but only one fires and it is some minutes late (not predictable i guess).
Here's my main activity (i'm setting Alarms by tapping a button)
public class MainActivity extends AppCompatActivity {
AlarmManager alarmManager;
Intent intent;
PendingIntent pendingIntent;
AtomicInteger atomicInteger;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
intent = new Intent(Constants.EXTENDED_DATA_STATUS);
atomicInteger = new AtomicInteger();
setContentView(R.layout.activity_main);
Button startButton = (Button) findViewById(R.id.start_button);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = atomicInteger.incrementAndGet();
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),id,intent,0);
Calendar firstLullo = Calendar.getInstance();
Calendar secondLullo = Calendar.getInstance();
firstLullo.set(Calendar.HOUR_OF_DAY,10);
firstLullo.set(Calendar.MINUTE,55);
secondLullo.set(Calendar.HOUR_OF_DAY,10);
secondLullo.set(Calendar.MINUTE,56);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP,firstLullo.getTimeInMillis(),pendingIntent);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,secondLullo.getTimeInMillis(),pendingIntent);
}
Log.d("ALARM","settato con id " + String.valueOf(id));
}
});
}
}
My Receiver simply shows a Toast and makes the phone vibrate.
Constants.EXTENDED_DATA_STATUS is a string from a Constants class and it's added to the intent-filter of my Reveiver in the Android Manifest.
What am i missing? I googled a lot and only found that i have to use setExact() but no luck..
Thanks in advance
The reason why only one fires is because your canceling your first one always
From the docs: If there is already an alarm scheduled for the same IntentSender, that previous alarm will first be canceled.
To fix this, use different PendingIntents for both alarms.
- To let your receiver fire multiple times, reschedule it in your onReceive()
Example:
Only if u want two receivers apart from eachother!
//Declare AlarmManager
AlarmManager am = (AlarmManager) LayoutActivity.this.getSystemService(ALARM_SERVICE);
//create new calendar instance for your first alarm
Calendar startTime= Calendar.getInstance();
//set the time of your first alarm
firstLullo.set(Calendar.HOUR_OF_DAY,10);
firstLullo.set(Calendar.MINUTE, 55);
firstLullo.set(Calendar.SECOND, 0);
//create a pending intent
PendingIntent firstPI = PendingIntent.getBroadcast(yourActivity.this, 0, new Intent("yourFirstAlarmReceiver"), PendingIntent.FLAG_UPDATE_CURRENT);
//schedule time for pending intent, and set the interval to day so that this event will repeat at the selected time every day
am.setRepeating(AlarmManager.RTC_WAKEUP, firstAlarm.getTimeInMillis(), firstPI);
//----------------------------------------------------
//create new calendar instance for your second alarm
Calendar endCalender = Calendar.getInstance();
//Set the time alarm of your second alarm
secondLullo.set(Calendar.HOUR_OF_DAY,10);
secondLullo.set(Calendar.MINUTE,56);
secondLullo.set(Calendar.SECOND, 0);
//create a pending intent to be
PendingIntent secondPI= PendingIntent.getBroadcast(yourActivity.this, 0, new Intent("yourSecondAlarmReceiver"), PendingIntent.FLAG_UPDATE_CURRENT);
//schedule time for pending intent, and set the interval to day so that this event will repeat at the selected time every day
am.setRepeating(AlarmManager.RTC_WAKEUP, secondLullo.getTimeInMillis(), secondPI);
Register alarms in Manifest.XML:
<receiver android:name="firstAlarm" >
<intent-filter>
<action android:name="yourFirstAlarmReceiver" >
</action>
</intent-filter>
</receiver>
<receiver android:name="secondAlarm" >
<intent-filter>
<action android:name="yourSecondAlarmReceiver" >
</action>
</intent-filter>
</receiver>
Now u can call your alarms with:
First Alarm:
public class yourFirstAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Do something when first alarm goes off
}
}
Second Alarm:
public class yourSecondAlarmReceiverextends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//Do something when second alarm goes off
}
}
Should help u out.
Yes, of course the above code will trigger only one Alarm, because you are setting same id for both alarms.
Alarm are identified and differentiated by their id in pendingintent.
Use different id for different alarms
Update Code:
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1234 ,intent,0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,firstLullo.getTimeInMillis(),pendingIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 5678, intent,0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP,secondLullo.getTimeInMillis(),pendingIntent);

Alarmmanager going off on reboot...but its set for 7 days ahead?

I'm failing to see why this alarm is going off on a reboot...I am setting it 7 days ahead here -
Intent intent = new Intent(MainActivity.this, Reminder.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MainActivity.this, 1, intent, 1);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
try {
am.cancel(pendingIntent);
} catch (Exception e) {
System.out.println("Derp");
}
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 7);
long time = calendar.getTimeInMillis();
am.set(AlarmManager.RTC_WAKEUP, time,
pendingIntent);
Here is my manifest that I have set for alarm to stick around on a reboot - Reminder is the class receiving the alarm-
<receiver android:name="com.practicum.notifications.Reminder" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
By default, all alarms are canceled when a device shuts down. To prevent this from happening, you can design your application to automatically restart a repeating alarm if the user reboots the device. This ensures that the AlarmManager will continue doing its task without the user needing to manually restart the alarm.
You have to manually reset the alarm once again in Bootup Receiver
public class SampleBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
// Set the alarm here.
}
}
All alarms are shut off when you power off the Android device.
You need to call setRepeating method
public class AlarmReceiver extends BroadcastReceiver {
private static final int PERIOD=5000;
#Override
public void onReceive(Context ctxt, Intent i) {
scheduleAlarms(ctxt);
}
static void scheduleAlarms(Context ctxt) {
AlarmManager am = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(ctxt, YourService.class);
PendingIntent pi = PendingIntent.getService(ctxt, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + PERIOD, PERIOD, pi);
}
}
Check this answer from CommonsWare.
For future reference, I misunderstood how receving the boot complete action worked. I had the intent filter in both of my receiver classes so they were both running, when instead I needed an intent filter on a new broadcastreceiver class to RESET my alarmmanagers.

Hovering toast every 5 minutes

I've seen several examples on how to make some event to be repeated even when the app isnt running, but still I'm not sure if I got it.
With AlarmManager you can make your app to wake up to do something in some fixed interval without it consuming system resources between the periods, right?
But can it be to show up a toast over your current activity instead of having an Activity with a layout for it?
AlarmReceiver class:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// this is where to start activity or service to launch toast message
}
}
In activity or boot receiver:
private static final int PERIOD = 60000; //or whatever you need for repeating alarm
AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent alIntent = new Intent(context, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, alIntent, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60000, PERIOD, pi);
In AndroidManifest, add:
<receiver android:name=".AlarmReceiver"></receiver>

Categories

Resources