Kinjal Android
Kinjal Android

Reputation: 55

Alarm is not triggering when app is killed

I am facing a issue while adding a alarmManager.

Basicly I'm trying to add a alarm on specific time and it's working fine whether app is in background or in foreground. but the issue is that it's not going to trigger when app is removed from background or app is killed.

I want to trigger alarm whether app is running or not (issue faced when app is closed).

I'm little bit desperate.

Here is my Code :

public class AlarmReciver extends BroadcastReceiver {


public AlarmReciver(){
    super();
}
@Override
public void onReceive(Context context, Intent intent) {
    Log.d("called","called");
    Toast.makeText(context, "Alarm received!", Toast.LENGTH_LONG).show();

    //This will send a notification message and show notification in notification tray
   /* ComponentName comp = new ComponentName(context.getPackageName(),
            AlarmNotificationService.class.getName());
    startWakefulService(context, (intent.setComponent(comp)));*/
   try {
       ManageDatabase manageDatabase = new ManageDatabase();
       // manageDatabase.setupdatabase(context);
       // For our recurring task, we'll just display a message
       //  Toast.makeText(context, "Alarm received!", Toast.LENGTH_LONG).show();
       Calendar calendar = Calendar.getInstance();
       calendar.setTimeInMillis(System.currentTimeMillis());
       String today_date=String.valueOf(calendar.get(Calendar.DAY_OF_MONTH))+"/"+String.valueOf((calendar.get(Calendar.MONTH)+1))+"/"+String.valueOf(calendar.get(Calendar.YEAR));
        today_date= datetimeformat.getdate(today_date);

       String id = intent.getStringExtra("id").toString();
       String pid = intent.getStringExtra("pid").toString();
       manageDatabase.cancelallreminders_without_update(context);
       manageDatabase.setallactivatedalarm(context);
       manageDatabase.addtodaysidlist(id,today_date,context);
       // Enable a receiver
      /* ComponentName receiver = new ComponentName(context, AlarmReciver.class);
       PackageManager pm = context.getPackageManager();
       pm.setComponentEnabledSetting(receiver,
               PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
               PackageManager.DONT_KILL_APP);*/
       Intent service1 = new Intent(context, Show_Reminder.class);
       service1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       service1.putExtra("id", id);
       service1.putExtra("pid", pid);
       context.startActivity(service1);
       Toast.makeText(context,"alarm is triggered...", Toast.LENGTH_LONG).show();
       Log.d("alarm is","triggered");

   }catch (Exception e)
   {
       Log.e("error",e.toString());
       e.printStackTrace();

   }

  }
}

Manifest file :

  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


  <receiver android:name="com.pragma.healthopediaplus.Medicine_reminder.Utils.Reminders.AlarmReciver"
        android:exported="false"
        android:process=":remote">
        <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_RESTARTED" />
        </intent-filter>
        <intent-filter>
        <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

set alarm from database.java

    public  void setallactivatedalarm(Context context) {

    db= context.openOrCreateDatabase("Reminder"+ SharedPreference.getvalue("username",context)+".db",Context.MODE_PRIVATE,null);

    Cursor c1 = db.rawQuery("select * from reminderdata",null);

    Log.d("Set all activate alarm","inside");

    while (c1.moveToNext())

    {
        if(c1.getString(6).equals("active"))
        {

            Date date_type=new Date();
            SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
            try {
                Gson gson = new Gson();
                ArrayList<Info> infodata = gson.fromJson(c1.getString(2), new TypeToken<ArrayList<Info>>() {
                }.getType());
            //    Log.d("reminder", " setReminder " + c1.getString(1) + " " + c1.getString(3) + " " + c1.getString(5) + " " + infodata + " " + Integer.parseInt(c1.getString(4)) + " " + context + " " + Integer.parseInt(c1.getString(0)));
                String alltime[]=infodata.get(7).getValue().split(",");
                String maxtime= datetimeformat.gettimehhmm(alltime[0]);

                String weekday;
                for(int i=1;i<alltime.length;i++)
                {
                    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
                    Date inTime = sdf.parse(maxtime);
                    Date outTime = sdf.parse(datetimeformat.gettimehhmm(alltime[i]));

                    if(outTime.compareTo(inTime) > 0){

                        maxtime= datetimeformat.gettimehhmm(alltime[i]);
                    }


                }

                String timedata=maxtime;
                String timearray[]=timedata.split(":");

                date_type = format.parse(c1.getString(3));

                Calendar newtime = Calendar.getInstance();
                newtime.setTime(date_type);

                newtime.set(Calendar.MINUTE,Integer.parseInt(timearray[1]));
                newtime.set(Calendar.SECOND,00);
                newtime.set(Calendar.HOUR_OF_DAY,Integer.parseInt(timearray[0]));

                Calendar currenttime=Calendar.getInstance();
               if(newtime.getTimeInMillis()<=currenttime.getTimeInMillis())
                {
                    /*  flag 1 for everyday 2 for month 3 for everyyear 4 onetime*/
                    if(c1.getString(4).equals("1"))
                    {
                        newtime.add(Calendar.DATE, 1);
                    }
                    else if(c1.getString(4).equals("2"))
                    {
                        newtime.add(Calendar.MONTH, 1);
                    }

                    else if(c1.getString(4).equals("3"))
                    {
                        newtime.add(Calendar.YEAR, 1);
                    }
                    else if(c1.getString(4).equals("5"))
                    {


                        int weekdayint = 0;
                        int dayOfWeek=newtime.get(Calendar.DAY_OF_WEEK);
                        String weekDay = null;
                        if (Calendar.MONDAY == dayOfWeek) {
                            weekdayint=Calendar.MONDAY;
                            weekDay = context.getString(R.string.Monday);

                        } else if (Calendar.TUESDAY == dayOfWeek) {
                            weekdayint=Calendar.TUESDAY;
                            weekDay = context.getString(R.string.Tuesday);

                        } else if (Calendar.WEDNESDAY == dayOfWeek) {
                            weekdayint=Calendar.WEDNESDAY;
                            weekDay = context.getString(R.string.Wednesday);

                        } else if (Calendar.THURSDAY == dayOfWeek) {
                            weekdayint=Calendar.THURSDAY;
                            weekDay = context.getString(R.string.Thursday);

                        } else if (Calendar.FRIDAY == dayOfWeek) {
                            weekdayint=Calendar.FRIDAY;
                            weekDay = context.getString(R.string.Friday);

                        } else if (Calendar.SATURDAY == dayOfWeek) {
                            weekdayint=Calendar.SATURDAY;
                            weekDay = context.getString(R.string.Saturday);

                        } else if (Calendar.SUNDAY == dayOfWeek) {
                            weekdayint=Calendar.SUNDAY;
                            weekDay = context.getString(R.string.Sunday);

                        }

                        weekday=infodata.get(9).getValue();

                        String day[]=weekday.split(",");
                        String next="";
                        int nxtday = 0;
                        int addday;

                        int count[]={1,2,3,4,5,6,7,1,2,3,4,5,6,7};
                        String getweek[]={"",context.getString(R.string.Sunday),context.getString(R.string.Monday),context.getString(R.string.Tuesday)
                        ,context.getString(R.string.Wednesday), context.getString(R.string.Thursday),
                        context.getString(R.string.Friday),context.getString(R.string.Saturday)};
                        for(int i=weekdayint;i<weekdayint+7;i++)
                        {
                            int c=count[i];
                            if (Arrays.asList(day).contains(getweek[c])) {

                                next=getweek[c];
                                nxtday=c;

                                break;
                            }

                        }

                        if(nxtday>weekdayint)
                        {
                            addday=nxtday-weekdayint;
                        }else
                        {
                            addday=nxtday-weekdayint+7;
                        }


                        newtime.add(Calendar.DATE, addday);
                    }
                    int thisYear = newtime.get(Calendar.YEAR);
                    int thisMonth = newtime.get(Calendar.MONTH);
                    int thisDay = newtime.get(Calendar.DAY_OF_MONTH);

                    String newdate=thisDay+"/"+(thisMonth+1)+"/"+thisYear;
                    newdate=datetimeformat.getdate(newdate);
                    db.execSQL("update reminderdata set duedate='"+newdate+"'where id='"+c1.getString(0)+"'");

                }


            } catch (Exception e) {
                // TODO Auto-generated catch block
             Log.d("error",e.toString());
            }

            Gson gson = new Gson();
            ArrayList<Info> infodata = gson.fromJson(c1.getString(2), new TypeToken<ArrayList<Info>>() {
            }.getType());
           // Log.d("reminder", " setReminder "+c1.getString(1)+" "+c1.getString(3)+" "+ c1.getString(5)+" "+ infodata+" "+Integer.parseInt(c1.getString(4))+" "+ context+" "+Integer.parseInt(c1.getString(0)));
            String alltime[]=infodata.get(7).getValue().split(",");

            Log.d("all time",infodata.get(7).getValue());
            Log.d("all time length",alltime.length+"");
            String pid[]=getPidsfromrid(Integer.parseInt(c1.getString(0)),context).split(",");

            for(int i=0;i<alltime.length;i++)
            {Log.d("pids",pid[i]);
                Log.d("set reminder called",alltime[i]);
                setReminder( c1.getString(3), context,
                        Integer.parseInt(c1.getString(0)),alltime[i],Integer.parseInt(pid[i]));

            }


        }
    }


    db.close();

}

public boolean setReminder(String date,Context context,int id,String time,int pid) {

        Intent myIntent = new Intent(context, AlarmReciver.class);
        myIntent.putExtra("id",String.valueOf(id));
        myIntent.putExtra("pid",String.valueOf(pid));
        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent,
                0);


        Date date_type=new Date();
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        try
        {
            date_type = format.parse(date);
        } catch (Exception e) {
            e.printStackTrace();
        }


        String timedata= datetimeformat.gettimehhmm(time);

        String timearray[]=timedata.split(":");
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date_type);
        calendar.set(Calendar.MINUTE,Integer.parseInt(timearray[1]));
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.HOUR_OF_DAY,Integer.parseInt(timearray[0]));


        Calendar current = Calendar.getInstance();


    Log.d("set reminder inside",time);
        if(calendar.compareTo(current) <= 0){
            calendar.add(Calendar.DATE, 1);
            Log.d("set reminder inside ","not set alarm"+time);
         // Toast.makeText(context,"Invalid Date/Time",Toast.LENGTH_LONG).show();
       } else{
            Log.d("set reminder inside ","set alarm"+time);

            Log.d("set reminder inside",time);


            alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(),
                    pendingIntent);

               /* int SDK_INT = Build.VERSION.SDK_INT;
                if (SDK_INT < Build.VERSION_CODES.KITKAT)
                    alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
                else if (Build.VERSION_CODES.KITKAT <= SDK_INT && SDK_INT < Build.VERSION_CODES.M)
                    alarmManager.setExact(AlarmManager.RTC_WAKEUP,
                            calendar.getTimeInMillis(), pendingIntent);
                else if (SDK_INT >= Build.VERSION_CODES.M) {
                    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
                            calendar.getTimeInMillis(), pendingIntent);
                }
*/


            /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis()+2000, pendingIntent);
            }else {
                alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis()+2000, pendingIntent);

            }*/
        }


        try {
            //Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  true;
    }

Upvotes: 0

Views: 464

Answers (1)

sudcha
sudcha

Reputation: 783

Closing the app closes all the Alarms as well. What you need instead is to set up Alarms from a Background Service instead.

You can reuse almost all of your existing code, and will have to create an additional class (preferably in new file) for the service. You'll also have to register the service in the manifest file, and move the code for creating alarm into the service class.

Example for creating a background service is here: https://developer.android.com/training/run-background-service/create-service

Note the background services have some limitations, but they can be set to be active even after REBOOT of the device.

Depending on your use case, you could also look into JobScheduler, that can run periodically and use that to set Alarms (dynamically, or otherwise). If your Alarms don't have to be 'Exact', you can just get the task done in JobScheduler itself, as it's almost as accurate as Alarm Manager. I say this because after Android O, doze mode takes away accuracy of Alarm Manager as well as JobScheduler.

Upvotes: 1

Related Questions