2017-03-28 8 views
0

API 호출을 통해 서버에서 이벤트 목록 (일주일)을 얻었고 내 앱은 캘린더와 동기화해야합니다. 이벤트는 앱에서 인터뷰를하지 않고 서버에서 업데이트하거나 삭제할 수 있습니다. 그리고 화면을 새로 고침 할 때마다 캘린더에 동기화해야합니다. Android 캘린더에서 이벤트가 중복되지 않도록하려면 어떻게해야하나요?

내 서버와 최신 일정까지 내 이벤트를 만들려면, 나는 새로 고침 다음 작업을 수행하고 있습니다 :

  1. 일정에서 주어진 일주일의 모든 이벤트를 삭제.
  2. 그런 다음 서버에서 가져온 이벤트를 삽입하십시오.

    public static void doAddCalendarEvent(MyEvent myEvent, Activity activity, int calendarId) { 
        try { 
         if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) { 
          return; 
         } 
         String desc = myEvent.getDesc(); 
         desc += "\n\n Added by MyApp"; 
    
         ContentResolver cr = activity.getContentResolver(); 
         ContentValues values = new ContentValues(); 
         values.put(Events.DTSTART, myEvent.getEventStartTime()); 
         values.put(Events.DTEND, myEvent.getEventEndTime()); 
         values.put(Events.TITLE, myEvent.getTitle()); 
         values.put(Events.DESCRIPTION, desc); 
         values.put(Events.CALENDAR_ID, calendarId); 
         values.put(Events.EVENT_LOCATION, myEvent.getLocation()); 
         values.put(Events.STATUS, Events.STATUS_CONFIRMED); 
         values.put(Events.AVAILABILITY, Events.AVAILABILITY_BUSY); 
         if (hasAlarm) { 
          values.put(Events.HAS_ALARM, true); 
         } 
         values.put(Events.EVENT_TIMEZONE, TimeZone.getDefault().getID()); 
         long eventId = 0; 
         Uri uri = cr.insert(Events.CONTENT_URI, values); 
         if (uri != null) { 
          eventId = Long.parseLong(uri.getLastPathSegment()); 
          Log.v(TAG, "INSERTED EVENT ID=>" + eventId + "--->" + startDate); 
         } 
         if (hasAlarm) { 
          setReminder(cr, reminderValue, eventId); 
         } 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
    } 
    

    문제

    가 : 때때로 이벤트가 달력에 중복 여기에
    public static void deleteAllEventsInWeekOfCalendar(Activity activity, int calId, long weekStartTimeMillis, long weekEndTimeMillis) { 
        try { 
        Uri eventUri = Uri.parse("content://com.android.calendar/events"); 
        String[] projection = new String[]{Events._ID, Events.TITLE, Events.DTSTART, Events.DESCRIPTION}; 
        String whereClause = Events.CALENDAR_ID + "=" + calId + 
          " AND " + Events.DTSTART + " >= " + weekStartTimeMillis + 
          " AND " + Events.DTSTART + " <= " + weekEndTimeMillis + 
          " AND " + Events.DESCRIPTION + " LIKE '% Added by MyApp'"; 
    
        Cursor cursor = activity.getContentResolver().query(eventUri, projection, whereClause, null, Events.DTSTART); 
        if (cursor != null && cursor.moveToFirst()) { 
         Log.v("HowMany", cursor.getCount() + " matching events Found"); 
         int numOfDeleted = 0; 
         do { 
          try { 
           String event_id = cursor.getString(cursor.getColumnIndexOrThrow(projection[0])); 
           int numOfRowsDeleted = activity.getContentResolver().delete(ContentUris.withAppendedId(eventUri, Long.parseLong(event_id)), null, null); 
           if (numOfRowsDeleted == 1) { 
            ++numOfDeleted; 
           } 
          } catch (Exception e) { 
           e.printStackTrace(); 
          } 
         } while (cursor.moveToNext()); 
         cursor.close(); 
         Log.v("HowMany", numOfDeleted + " deleted"); 
        } 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } 
    } 
    

그리고

는 일정에 모든 이벤트를 삽입하는 내 코드입니다. 중복을 피하려면 어떻게해야합니까? 어디가 잘못 됐어? 제발 제안 해주세요.

답변

0

캘린더와 인터페이스하기 위해 동기화 어댑터를 사용한다고 가정합니다. 당신이 ContentResolver.requestSync 전화를 걸 때마다 또는 자동 동기화가 true로 설정되어있는 경우

onPerformSync(...)하고,라고 onSyncCanceled(...)

onPerformSync :

동기화 어댑터는 두 가지 중요한 방법이 있습니다.

실행하는 동안, onPerformSync는 안드로이드에 의해 중단 될 수있다. 앱이 포 그라운드에 더 이상 존재하지 않는 경우 기기의 리소스가 부족한 경우이 문제가 발생할 수 있습니다.

동기화가 완료되면 동기화 어댑터는 실행중인 위치에서 실행을 중지하고 onSyncCanceled을 호출합니다. 동기화 어댑터의 기본 동작은 실패한 동기화 메시지를 처음 시도 할 때 다시 시도하는 것입니다. 따라서 앱이 OS 리소스를 다시 잡아 내면 중단 된 동기화 메시지를 재생합니다.

onPerformSync 완료하는 것입니다 직전, 메시지의 일부가 완전히 처리되는 것이 가능하며는, 동기화 어댑터는 중단됩니다. 이 시점에서 이벤트를 저장했지만 동기화 어댑터는 동기화가 실패했다고 생각하므로 다음에 동기화를 시도 할 때 동일한 메시지를 다시 재생합니다.

한 번에 하나의 이벤트를 동기화하는 경우 확실하지 않아 확실한 해결책을 제시 할 수 없습니다. 그러나 수행 할 수있는 작업은 동기화 어댑터의 기본 동작을 변경하여 "실패한"메시지를 재생하지 못하게하는 것입니다.

Bundle extras = new Bundle(); ... extras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true); CalendarConstants.AUTHORITY, true); ContentResolver.requestSync(mAccount, CalendarConstants.AUTHORITY, extras);

OnSyncCanceled, 당신은 즉, 메시지가 성공해야합니다 달력의 이벤트 테이블에 존재하기 위해 몇 가지 가벼운 검사를 할 수 있습니다. 그렇지 않다면, 수동으로 재생. 메시지가 있으면 SyncAdapter는 다음 메시지로 넘어 가서 복제본을 가져 오지 않습니다.

또는 onPerformSync 내의 모든 작업이 원자적일 수 있습니다.