2

I am developing application that will sends birthday wishes automatically based on the birthday date with time registered by wisher. i have created a thread with infinite for loop that will get the records from Database for today's date to send message automatically for every minute automatically.

my code is running properly in normal activity. i want to place inside the SERVICE.so help me how to place this code and call the service when application starts.

this is my code

// function to run thread
void startThread()
{
       Thread th=new Thread(){  
            @Override
            public void run(){  
                // 
               try
                {   
                    for (;;)
                    {
                                runOnUiThread(new Runnable() { 
                                @Override
                                public void run() {
                                    try {
                                        //Getting the system date                                       
                                        Calendar today=new GregorianCalendar();                   
                                        SimpleDateFormat simdate=new SimpleDateFormat("yyyy-MM-dd");                                            
                                        SimpleDateFormat timeFormat=new SimpleDateFormat("hh:mm a");                                    
                                        String systemDate=simdate.format(today.getTime());
                                        String systemTime=timeFormat.format(today.getTime());

                                        // system process

                                        minText.setText(systemTime);

                                        control.open();
                                        ArrayList<UserPOJO> event=control.MyDatabaseRecords(systemDate);//get the records for system date
                                        for(int i=0;i<event.size();i++)
                                        {
                                            String dbContactID=event.get(i).getContactID(); 
                                            String dbContactNumber=event.get(i).getContactNumber(); 
                                            String dbContactMessage=event.get(i).getContactMessageBody();   
                                            String dbDate=event.get(i).getContactWishDate();    
                                            String dbTime=event.get(i).getContactWishTime();    


                                            String[] time=dbTime.split("[ \\:]");
                                            String myhr=time[0];
                                            String mymin=time[1];
                                            String aorp=time[2];
                                            String myDBhr=addZeroBeforeDate(myhr);
                                                                 // adding zero before time hour
                                            String CurrentDBTime=myDBhr+":"+mymin+" "+aorp;



                                            Toast.makeText(getApplicationContext(),"Searching.....", 300).show();

                                            //Toast.makeText(getApplicationContext(),"DB Time:"+CurrentDBTime+"System Time"+systemTime, 300).show();


                                            if((dbDate.equals(systemDate))&& (CurrentDBTime.equals(systemTime)))
                                            {// 
                                                System.out.println("Message Send at:"+systemTime);
                                                Toast.makeText(getApplicationContext(),"Message Sent to :"+dbContactNumber+"on System time:"+systemTime, 300).show();
                                                 sendSMS(dbContactNumber, dbContactMessage);                

                                                //send.sendSMS(dbContactNumber, dbContactMessage);
                                            }
                                    }

                                    }
                                    catch(Exception e) 
                                    {
                                        e.printStackTrace();
                                    } 
                                }
                                });  
                                Thread.sleep(60000);
                               // Thread.sleep(20000);
                     // set the scan for 60 seconds
                    }
                }
                catch (InterruptedException e) {
                }

            }   // run
        };
    th.start();
}

   // Add zero if it is 

   dateval<10
   private static String addZeroBeforeDate(String datevalue)
   {
        String dval=datevalue;

        for(int i=dval.length();i<2;i++)
        {
            dval="0"+dval;
        }

        return dval;
   }
Chris Schiffhauer
  • 17,102
  • 15
  • 79
  • 88
  • Use the AlarmManager do not query the database every minute in a permanent for loop. It wouldn't take long for the user's battery to completely drain. – Boardy Jun 12 '13 at 13:16

2 Answers2

3

You should use an IntentService with AlarmManager to call the service periodically:

the onHandleIntent() method of IntentService is called in a different thread, so you don't have to worry about block the UI.

AlarmManager should also be more efficient than TimerTask. (See Timer Task VS Alarm Manager usage in Android Service)

public class MyService extends IntentService {

    private AlarmManager alarmManager;

    private boolean started;
    private PendingIntent pendingIntent;

    public MyService() {
        super(MyService.class.getSimpleName());
    }

    @Override
    public void onCreate() {
        super.onCreate();
        alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (! started) {
            started = true;

            // Call the service periodically every 15 minutes
            pendingIntent = PendingIntent.getService(
                    getApplicationContext(), 
                    0, 
                    intent, 
                    PendingIntent.FLAG_UPDATE_CURRENT);

            alarmManager.setRepeating(
                    AlarmManager.ELAPSED_REALTIME, 
                    AlarmManager.INTERVAL_FIFTEEN_MINUTES,
                    AlarmManager.INTERVAL_FIFTEEN_MINUTES,
                    pendingIntent);
        }

        // DO YOUR STUFF HERE
    }
}

Have a look at the AlarmManager documention for the options you can use.

Community
  • 1
  • 1
nicopico
  • 3,606
  • 1
  • 28
  • 30
  • when I assign `alarmManager` in the constructor I get null pointer on `getApplicationContext` because it runs on a different thread. Can you improve your answer ? – Iero Oct 16 '16 at 12:14
  • Indeed, the AlarmManager should be initialized in the onCreate() method. I will update my answer accordingly – nicopico Oct 16 '16 at 12:18
  • please do it as I use your answer in my current work :D – Iero Oct 16 '16 at 12:20
  • Also do not forget to call `super.OnCreate()` in `onCreate` method otherwise it will give you null pointer when trying to call `obtainMessage()` – Iero Oct 16 '16 at 12:31
2

Firstly there is a class called Timer in java, use it.. Don't write endless for loops that run in threads, that is a VERY sticky way of doing things and can cause all types of problems.

Here I have a Timer implemented in a Service. You can start off with trying this code. I suggest you also look at the android Alarm class.

public class SomeService extends Service {
    private static final String TAG = SomeService.class.getSimpleName();
    private static final long UPDATE_INTERVAL = 1 * 15 * 1000;
    private static final long DELAY_INTERVAL = 0;

    private Timer timer;

    public SomeService() {
    }

    public void onCreate() {
        Log.d(TAG, "STARTING SERVICE");

        super.onCreate();

    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        timer.scheduleAtFixedRate(
                    new TimerTask() {
                        public void run() {
                            //DO YOUR CODE
                        }
                    },
                    DELAY_INTERVAL,
                    UPDATE_INTERVAL
            );

        super.onStartCommand(intent, flags, startId);

        return 0;
    }

    @Override
    public void onDestroy() {
        timer.cancel();

        super.onDestroy();
    }
}

You can start your Service by calling this startService(new Intent(this, NotificationService.class)); from your starting Activity

Furthermore look at this and this links for more info.

Community
  • 1
  • 1
the-ginger-geek
  • 7,041
  • 4
  • 27
  • 45