Researcher1996
Researcher1996

Reputation: 23

Google Calendar API & Alarm Manager Error

I get the free 1 hour time slots from the Google calendar API using this code.

MainActivity.java:

 private List<String> getDataFromApi() throws IOException {
        LocalDateTime now = LocalDateTime.now();
        int year = now.getYear();
        int month = now.getMonthOfYear();
        int day = now.getDayOfMonth();

        org.joda.time.DateTime startDateJoda= new org.joda.time.DateTime(year,month,day,7,00);
        org.joda.time.DateTime endDateJoda= new org.joda.time.DateTime(year,month,day,22,00);

        // Convert from Joda-Time to old bundled j.u.Date
        java.util.Date juDateStart = startDateJoda.toDate();
        java.util.Date juDateEnd = endDateJoda.toDate();
        Log.v(TAG,"Start Date joda value: "+juDateStart.toString());
        Log.v(TAG,"End Date joda value: "+juDateEnd.toString());

        // Convert from j.u.Date to Google Date.
        com.google.api.client.util.DateTime googleDateTimeStart = new com.google.api.client.util.DateTime( juDateStart );
        com.google.api.client.util.DateTime googleDateTimeEnd = new com.google.api.client.util.DateTime( juDateEnd );
        Log.v(TAG,"Start Date Google value: "+googleDateTimeStart.toString());
        Log.v(TAG,"End Date Google value: "+googleDateTimeEnd.toString());

        List<String> eventStrings = new ArrayList<String>();

        org.joda.time.DateTime rootStart = startDateJoda;
        org.joda.time.DateTime rootEnd = endDateJoda;

        Events events = mService.events().list("primary")
                .setMaxResults(10)
                .setTimeMin(googleDateTimeStart)
                .setTimeMax(googleDateTimeEnd)
                .setOrderBy("startTime")
                .setSingleEvents(true)
                .execute();


        List<Event> items = events.getItems();
        Log.v(TAG,"Items : "+items.toString()+"\n");
        Log.v(TAG,"Items size : "+items.size());
        int interval = 1 ; // how big single slot should be (in this case 1 hrs)

        ArrayList<MyEvent> freeSlots = new ArrayList<MyEvent>();
        for (int index =0;index<items.size();index++) {
            Event event = items.get(index);
            Log.v(TAG,"Items Index: "+event.toString()+"\n");

            DateTime teststart=event.getStart().getDateTime();
            DateTime testend=event.getEnd().getDateTime();
            Log.v(TAG,"Test Start Date value: "+teststart.toString());
            Log.v(TAG,"Test End Date value: "+testend.toString());

            long milliseconds1 = teststart.getValue();
            long milliseconds2 = testend.getValue();

            org.joda.time.DateTime eventStartJoda= new org.joda.time.DateTime(milliseconds1);
            org.joda.time.DateTime eventEndJoda= new org.joda.time.DateTime(milliseconds2);

            Log.v(TAG,"Event Start Date joda value: "+eventStartJoda.toString());
            Log.v(TAG,"Event Date joda value: "+eventEndJoda.toString());

            Log.v(TAG,"Before if index == 0 && start<end");
            if ((index == 0) && (startDateJoda.isBefore(eventStartJoda)) ) {
                Log.v(TAG,"Before Inside if index == 0 && start<end");
                freeSlots.add( new MyEvent(startDateJoda,eventEndJoda) );
                Log.v(TAG,"After Inside if index == 0 && start<end");
            }

            if (index == 0) {
                Log.v(TAG,"Before else if index == 0");
                DateTime teststart2=event.getEnd().getDateTime();
                long milliseconds3 = teststart2.getValue();
                startDateJoda=new org.joda.time.DateTime(milliseconds3);
                Log.v(TAG,"startDateJoda value: "+startDateJoda.toString());
            }

            long milliseconds5=0;
            Log.v(TAG,"Before teststart4");
            if(index!=0) {
                DateTime teststart4 = items.get(index - 1).getEnd().getDateTime();
                Log.v(TAG, "After teststart4");
                milliseconds5 = teststart4.getValue();
                Log.v(TAG, "Before if milliseconds5");
            }
            if (new org.joda.time.DateTime(milliseconds5).isBefore(eventStartJoda)) {
                if(index!=0) {
                    freeSlots.add(new MyEvent
                            (new org.joda.time.DateTime(milliseconds5), eventStartJoda));
                Log.v(TAG,"xxxxxxx1 value: "+ new org.joda.time.DateTime(milliseconds5).toString());
                }
            }

            DateTime teststart3=event.getEnd().getDateTime();
            long milliseconds4 = teststart3.getValue();

            if ((items.size() == (index + 1)) && new org.joda.time.DateTime(milliseconds4).isBefore(endDateJoda)) {
                freeSlots.add(new MyEvent(eventEndJoda, endDateJoda));
                Log.v(TAG,"xxxxxxx2 value: "+ new org.joda.time.DateTime(milliseconds4).toString());
            }
        }
        Log.v(TAG,"Before outside items size == 0 ");
        if (items.size() == 0) {
            Log.v(TAG,"Before Inside items size == 0 ");
            freeSlots.add(new MyEvent(startDateJoda,endDateJoda));
            Log.v(TAG,"After Inside items size == 0 ");
        }
        Log.v(TAG,"After outside items size == 0 ");

        ArrayList<MyEvent> hourSlots = new ArrayList<MyEvent>();
        org.joda.time.DateTime tempstart= null;
        org.joda.time.DateTime tempend= null;
        MyEvent temp = new MyEvent();
        int val=0;
        for(int index =0;index<freeSlots.size();index++){
            MyEvent free = (MyEvent) freeSlots.get(index);
            Log.v(TAG,"Free slot size : "+freeSlots.size());
            int freeHours = free.endDate.getHourOfDay()- free.startDate.getHourOfDay();
            Log.v(TAG,"FreeHours: "+freeHours);
            org.joda.time.DateTime freeStart = free.startDate, freeEnd = free.endDate;
            Log.v(TAG,"Free Start Date: "+free.startDate.toString()+"Free End Date: "+free.endDate.toString());
            Log.v(TAG,"Before eventStrings: "+free.startDate.toString()+" : "+free.endDate.toString());

                while(freeStart.getHourOfDay() + freeHours + interval>=0) {                         if(freeHours>=interval) {
                        Log.v(TAG,"free startDate : "+free.startDate);
                        tempend=free.startDate;
                        Log.v(TAG,"Temp startDate : "+tempend);
                        tempend= tempend.hourOfDay().setCopy(tempend.getHourOfDay()+freeHours);
                        Log.v(TAG,"Tmp Start Date1: "+String.valueOf(tempstart)+"Tmp End Date1: "+String.valueOf(tempend));
                        tempstart=free.startDate;
                        Log.v(TAG,"Temp endDate : "+tempstart);
                    tempstart = tempstart.hourOfDay().setCopy(tempstart.getHourOfDay()+freeHours-interval);
                    Log.v(TAG,"Tmp Start Date2: "+tempstart+"Tmp End Date2: "+tempend);
                    if(tempstart.getHourOfDay() >= freeStart.getHourOfDay() && tempend.getHourOfDay() <= freeEnd.getHourOfDay()) {
                        Log.v(TAG,"While loop inside if condition inside if condition inside");
                        if(val!=0) {
                            hourSlots.add(new MyEvent(tempstart, tempend));
                            Log.v(TAG, "Tmp hour slot: " + tempstart + " : " + tempend);
                            eventStrings.add(
                                    String.format(" " + tempstart.toString("dd/MM/yy HH:mm:ss") + " - " + tempend.toString("dd/MM/yy HH:mm:ss")));
                            Log.v(TAG, "After eventStrings: " + tempstart.toString("dd/MM/yy HH:mm:ss") + " : " + tempend.toString("dd/MM/yy HH:mm:ss"));
                            int hour=Integer.valueOf(tempstart.toString("HH"));
                            int mminute=Integer.valueOf(tempstart.toString("mm"));
                            Log.v(TAG,"Alarm Time "+hour+":"+mminute);
                            startAlarm(hour,mminute);
                        }
                        val++;
                        tempstart=null;
                        tempend=null;
                    }
                }
                freeHours--;
            }
        }
        Log.v(TAG,"Event Strings : "+eventStrings);
        return eventStrings;
    }

MainActivity.java(Part of code2):

In this code segment, I create the Alarm for each of the free time slots start time.

 int broadcastCode=0;
        public void startAlarm(int hour,int mminute){
            broadcastCode++;
            Intent intent=new Intent(MainActivity.this,MyBroadcastReceiver.class);
            PendingIntent pendingIntent=PendingIntent.getBroadcast(MainActivity.this,broadcastCode,intent,0);
            AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
            Calendar cal_alarm=Calendar.getInstance();
            cal_alarm.set(Calendar.HOUR_OF_DAY,hour);
            cal_alarm.set(Calendar.MINUTE,mminute);
            cal_alarm.set(Calendar.SECOND,00);


            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                alarmManager.setExact(AlarmManager.RTC_WAKEUP,cal_alarm.getTimeInMillis(),pendingIntent);
                Toast.makeText(MainActivity.this,"Alarm > KITKAT & Alarm Set For: "+hour+" : "+mminute,Toast.LENGTH_SHORT).show();
            }
            if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT){
                alarmManager.set(AlarmManager.RTC_WAKEUP,cal_alarm.getTimeInMillis(),pendingIntent);
                Toast.makeText(MainActivity.this,"Alarm < KITKAT & Alarm Set For: "+hour+" : "+mminute,Toast.LENGTH_SHORT).show();
            }
        }

When i call the startAlarm() function inside the while loop of getDataFromApi() function,

I get this Error:

can't create handler inside thread that has not called Looper.prepare()

I will be glad if anyone can give me a solution or guidance. Thank you.

Upvotes: 0

Views: 124

Answers (1)

Elletlar
Elletlar

Reputation: 3224

Checkout this link here: Can't create handler inside thread that has not called Looper.prepare()

But the problem is the 'toast' lines inside your startAlarm method like this one:

Toast.makeText(MainActivity.this,"Alarm > KITKAT & Alarm Set For: "+hour+" : "+mminute,Toast.LENGTH_SHORT).show();

Any time a view is updated in Android, it must be done on the 'main thread' also known as the 'UI thread'.

It might be better to use logging here rather than toast.

Upvotes: 0

Related Questions