Google Calendar API和警报管理器错误

时间:2018-07-15 02:41:29

标签: android android-studio alarmmanager google-calendar-api android-googleapiclient

我使用此代码从Google Calendar API获得1小时的免费时段。

MainActivity.java(代码1的一部分)

这是我尝试过的代码。

 private List<String> getDataFromApi() throws IOException {
//             List the next 10 events from the primary calendar.

//            DateTime startDate = new DateTime(System.currentTimeMillis());
//            DateTime endDate = new DateTime(System.currentTimeMillis()+24 * 60 * 60 * 1000);
//
//            Log.v(TAG,"Start Date value: "+startDate .toString());
//            Log.v(TAG,"End Date value: "+endDate.toString());

        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>();
//            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());



//                eventStrings.add(
//                               String.format(" "+freeStart.toString("dd/MM/yy HH:mm:ss")+" - "+freeEnd.toString("dd/MM/yy HH:mm:ss")));
//                Log.v(TAG,"Before while eventStrings: "+free.startDate.toString("dd/MM/yy HH:mm:ss")+" : "+free.endDate.toString("dd/MM/yy HH:mm:ss"));
//
//
//                Log.v(TAG,"Hour slots : "+hourSlots.toString());
//                Log.v(TAG,"GetHour slots : "+freeStart.getHourOfDay());
//                Log.v(TAG,"free hours : "+freeHours);
//                Log.v(TAG,"interval : "+interval);

                while(freeStart.getHourOfDay() + freeHours + interval>=0) { // 11 + 4 + 1 >= 0
                    if(freeHours>=interval) {
                        Log.v(TAG,"free startDate : "+free.startDate);
//                        temp.endDate = free.startDate;
                        tempend=free.startDate;
                        Log.v(TAG,"Temp startDate : "+tempend);
//                        temp.endDate= temp.endDate.hourOfDay().setCopy(temp.endDate.getHourOfDay()+freeHours);
                        tempend= tempend.hourOfDay().setCopy(tempend.getHourOfDay()+freeHours);
                        Log.v(TAG,"Tmp Start Date1: "+String.valueOf(tempstart)+"Tmp End Date1: "+String.valueOf(tempend));
//                        temp.startDate = free.startDate;
                        tempstart=free.startDate;
                        Log.v(TAG,"Temp endDate : "+tempstart);
//                        temp.startDate = temp.startDate.hourOfDay().setCopy(temp.startDate.getHourOfDay()+freeHours-interval);
                    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(代码2的一部分)

在此代码段中,我用来为每个空闲时隙的开始时间创建警报。

 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);
//            alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal_alarm.getTimeInMillis(),
//                    AlarmManager.INTERVAL_DAY, 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);
//            alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal_alarm.getTimeInMillis(),
//                    AlarmManager.INTERVAL_DAY, pendingIntent);
                Toast.makeText(MainActivity.this,"Alarm < KITKAT & Alarm Set For: "+hour+" : "+mminute,Toast.LENGTH_SHORT).show();
            }
        }

当我在getDataFromApi()函数的while循环内调用startAlarm()函数时,

我收到此错误。

发生以下错误: 无法在未调用Looper.prepare()的线程内创建处理程序

很高兴能给我解决方案或指导。

谢谢

1 个答案:

答案 0 :(得分:0)

在此签出此链接: Can't create handler inside thread that has not called Looper.prepare()

但是问题出在像这样的startAlarm方法中的“ toast”行:

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

每次在Android中更新视图时,都必须在“主线程”(也称为“ UI线程”)上完成。

在这里使用日志记录而不是在吐司上比较好。