Previously am using IntentService to trigger the Background services with AlaramManager. Now am changed the IntentService to JobIntentService for trigger Background process to fetch the data from Server. In Some devices JobIntentService not triggering, it will trigger only after open the application.
Set AlaramManager
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
PendingIntent pi;
AlarmManager am;
pi = PendingIntent.getBroadcast(getActivity(), requestCode, new Intent(getActivity(), PendingCampaignReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
am = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
BroadCastReceiver Class
public class PendingCampaignReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
PendingCampaign.enqueueWork(context, intent);
}
}
<receiver
android:name=".broadcast.receiver.PendingCampaignReceiver"
android:enabled="true"
android:process=":remote" />
JobIntentService Class
public class PendingCampaign extends JobIntentService {
public static void enqueueWork(Context context, Intent intent) {
enqueueWork(context, PendingCampaign.class, PENDING_CAMPAIGN_JOB_ID, intent);
}
#Override
protected void onHandleWork(#NonNull Intent intent) {
//am doing my API calling here
}
}
<service
android:name=".services.PendingCampaign"
android:permission="android.permission.BIND_JOB_SERVICE" />
Is there any issue in my Coding. Help me to solve the issue.
Related
I've been stuck on this for days now.
I want my alarm manager to fire off every 15 minutes even when the app is closed but it does not work when app is closed. It works while app is open though.
In my manifest file I have:
<!-- Used to consume the alarm manager alerts when app clsoed -->
<receiver
android:name="biz.customName.pkg.AlarmReceiver"
android:enabled="true">
<intent-filter>
<action android:name="biz.customName.pkg.msg"/>
</intent-filter>
</receiver>
My BroadcastReceiver class (AlarmReceiver)
public class AlarmReceiver extends BroadcastReceiver
{
// Alarm manager used to run install when app is closed
AlarmManager alarmManager;
// Called when alarm received
#Override
public void onReceive(Context context, Intent intent)
{
// Enable alarm
setupAlarm(context);
// Perform background task
}
// Setup alarm
public void setupAlarm(Context context)
{
// Setup reciever for alarm
// context.registerReceiver(this, new IntentFilter("biz.customName.pkg.msg"));
// Setup pending intent
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(Loader.filterName), PendingIntent.FLAG_UPDATE_CURRENT);
// Setup alarm
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
final long triggerTime = System.currentTimeMillis() + 900 * 1000;
// Newest OS
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 23)
{
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}
}
}
In main I call setup alarm to get the alarm going initially then each time the onReceive inside my Broadcast receiver is called I reset the alarm.
What am I doing wrong that it doesn't work when the app is closed?
Add this in your AndroidManifest.xml
<service
android:name=".MyService"
android:enabled="true"
android:exported="true" />
<receiver
android:name=".MyAlarmReceiver"
android:enabled="true"
android:exported="true" />
MyAlarmReceiver.java
public class MyAlarmReceiver extends BroadcastReceiver {
Context context;
public MyAlarmReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
intent = new Intent(context, MyService.class);
context.startService(intent);
}
}
MyService.java
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
YourTask();
return Service.START_STICKY;
}
private void YourTask(){
// call api in background
// send push notification
//etc...
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
PendingIntent pendingIntent;
AlarmManager alarmManager;
Intent alarmIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AutoUpdateDataInBackground();
}
private void AutoUpdateDataInBackground() {
// Retrieve a PendingIntent that will perform a broadcast
alarmIntent = new Intent(MainActivity.this, MyReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, 0);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
long interval = 15 * 60 * 1000;
// Repeating on every 15 minutes interval
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),interval, pendingIntent);
}
}
BTW : AlarmManager will not be called with locked screen and enabled energy saving mode
How do I implement a periodic Task that queries the db and deletes row periodically? I want to do this so that I prevent my database from growing too big over time.
Using a Sticky Service with AlarmManager and BroadcastReceiver is what you need.
public class MY_SERVICE extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// remove last alarm you set
Intent intent = new Intent(context, MY_DB_PROCEDURE_BROADCAST.class);
intent.setAction("myDbProcedure");
PendingIntent alarmIntent = PendingIntent.getBroadcast(context,1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.cancel(alarmIntent);
// add new alarm manager
intent = new Intent(context, MY_DB_PROCEDURE_BROADCAST.class);
intent.setAction("myDbProcedure");
alarmIntent = PendingIntent.getBroadcast(ct, 1, intent, 0);
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(),
intervalMin*60*1000, alarmIntent);
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
your BroadcastReceiver class :
public class MY_DB_PROCEDURE_BROADCAST extends BroadcastReceiver {
private final String TAG=getClass().getName();
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG,"Started");
// DO YOUR DB TASK HERE
}
}
In your manifest define the service and broadcastReceiver:
<service
android:name="MY_SERVICE"
android:enabled="true"
android:exported="true" />
<receiver android:name="MY_DB_PROCEDURE_BROADCAST" android:enabled="true"/>
Here is my class which launches and sets an alarm when the phone is rebooted.
public class NotifStart extends BroadcastReceiver
{
private static AlarmNotif reAlarm = new AlarmNotif();
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
reAlarm.SetAlarm(context.getApplicationContext());
}
}
}
and here's my alarm's receiver class:
public class AlarmNotifReceiver extends BroadcastReceiver {
PendingIntent pi;
#Override
public void onReceive(Context context, Intent intent)
{
//stuff
}
public void SetAlarm(Context context)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, AlarmNotifReceiver.class);
pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10*1000, pi); // Millisec * Second
}
public void CancelAlarm(Context context)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(pi);
}
}
Now, if I use SetAlarm() as the phone is open I am able to use CancelAlarm() and actually cancel it. But whenever I reboot the phone and set the alarm by using the above class NotifStart I am unable to cancel it. I tried to use the cancel method from within the NotifStart but since I can't really give the context of a non-activity class as onReceive it just doesn't work.
From the docs:
A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this function, the system considers the object to be finished and no longer active.
So when you call your CancelAlarm your pending intent might be null or not equal to pending intent used for setting alarm.
In CancelAlarm(Context context) your pi might be null, check and re-create it with the same requestCode before performing cancel.
public void CancelAlarm(Context context)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, AlarmNotifReceiver.class);
pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pi);
}
I have created the start alarm as shown below
public class MyScheduleReceiver extends BroadcastReceiver {
// Restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 5;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), REPEAT_TIME, pending);
I crate this for stop alarm and i call it from main activity.Manifest i think is ok...Work repeat but no stop!!!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup);
sendBroadcast(new Intent(this,MyScheduleReceiver.class));
}
public void StopRepeat(View view) {
sendBroadcast(new Intent(this,MyStopReceiver.class));
}
public class MyStartServiceReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Repeat service!.",
Toast.LENGTH_LONG).show();
}
public class MyStopReceiver extends BroadcastReceiver {
// Restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 5;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent istop = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, istop,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
service.cancel(pending);
But the service is not stopping. What might be the issue?Thanks.
The simplest option is to restart your device. (If you created a BOOT_COMPLETED listener just remove it for now.)
You can also cancel an alarm by passing the PendingIntent you used to create the alarm to AlarmManager#cancel(). You have already written the code to do this, but do you have a Button with the XML attribute android:onClick="StopRepeat" in setup.xml? Did you click it?
Solution
We eventually discovered you had a mistake in your Manifest file, so MyStopServiceReceiver was never called...
I've a service that runs after android starts. I'd like show a toast every days at 9am. The problem is: how can I implement the code (alarmamanger within service)?
Start service after boot:
public class AutoStart extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent();
serviceIntent.setAction("com.example.startatboot.UnUsedService");
context.startService(serviceIntent);
}
}
public class Service extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(UnUsedService.this, "Start Alarm", Toast.LENGTH_LONG).show();
}};
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0); AlarmManager am = (AlarmManager) context.getSystemService (Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, new Intent(context, MyClass.class), PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
Just replace your code with my code,
public class Service extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(UnUsedService.this, "Start Alarm", Toast.LENGTH_LONG).show();
}};
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0); AlarmManager am = (AlarmManager) context.getSystemService (Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, new Intent(context, AlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
Now create a new class AlarmReceiver in the same package and add the following code to it.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();
}
}
Now define it in the PendingIntent of the Alarm.
Add following code in the manifest file,
<receiver android:name=".AlarmReceiver" />
Now run your application. that's it. It will definitely show a toast at 9.
Let me know if it worked or not.