Как читать и редактировать события календаря Android с помощью нового Android 4.0 Ice Cream Sandwich API?
Мы пытаемся показать пользователю календарь календаря Ice cream Sandwich, когда они хотят добавить новое событие. Мы можем проверить это только в эмуляторе.
Другая проблема заключается в том, что мы не можем найти примеров использования CalendarProvider. Это правильный класс, когда дело касается сэндвич-календаря?
Было бы проще сделать это с API Google Gdata?
[EDIT]
Итак, что мы получили, это добавить событие в календарь, но не через API, мы открываем календарь в правильном виде. Но теперь проблема в том, что она не работает в эмуляторе, потому что мы не смогли синхронизировать календарь.
Итак, вопрос: как читать и, возможно, редактировать события календаря Android с помощью нового Android 4.0 Ice Cream Sandwich API?
Ответы
Ответ 1
Здесь код, который позволит вам добавить событие напрямую:
import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.provider.CalendarContract;
import java.util.Calendar;
// Construct event details
long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 9, 14, 7, 30);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 9, 14, 8, 45);
endMillis = endTime.getTimeInMillis();
// Insert Event
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
TimeZone timeZone = TimeZone.getDefault();
values.put(CalendarContract.Events.DTSTART, startMillis);
values.put(CalendarContract.Events.DTEND, endMillis);
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());
values.put(CalendarContract.Events.TITLE, "Walk The Dog");
values.put(CalendarContract.Events.DESCRIPTION, "My dog is bored, so we're going on a really long walk!");
values.put(CalendarContract.Events.CALENDAR_ID, 3);
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
// Retrieve ID for new event
String eventID = uri.getLastPathSegment();
Вам понадобится CALENDAR_ID, поэтому здесь, как запросить список календарей:
Uri uri = CalendarContract.Calendars.CONTENT_URI;
String[] projection = new String[] {
CalendarContract.Calendars._ID,
CalendarContract.Calendars.ACCOUNT_NAME,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
CalendarContract.Calendars.NAME,
CalendarContract.Calendars.CALENDAR_COLOR
};
Cursor calendarCursor = managedQuery(uri, projection, null, null, null);
Вам нужно запросить разрешение android.permission.READ_CALENDAR
для всего этого.
Если вы хотите избежать запроса разрешений, вы также можете попросить приложение "Календарь" создать новое событие от вашего имени с помощью Intent
:
Intent intent = new Intent(Intent.ACTION_INSERT)
.setType("vnd.android.cursor.item/event")
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
.putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY , false) // just included for completeness
.putExtra(Events.TITLE, "My Awesome Event")
.putExtra(Events.DESCRIPTION, "Heading out with friends to do something awesome.")
.putExtra(Events.EVENT_LOCATION, "Earth")
.putExtra(Events.RRULE, "FREQ=DAILY;COUNT=10")
.putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
.putExtra(Events.ACCESS_LEVEL, Events.ACCESS_PRIVATE)
.putExtra(Intent.EXTRA_EMAIL, "[email protected]");
startActivity(intent);
Ответ 2
Вы можете использовать следующий код для настройки часового пояса, и он работает для меня
TimeZone timeZone = TimeZone.getDefault();
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());
Ответ 3
Убедитесь, что вы не используете "visibilty" для устройств ICS и JellyBean (apiLevel >= 14)
Попробуйте это -
ContentValues values= new ContentValues();
int apiLevel = android.os.Build.VERSION.SDK_INT;
if(apiLevel<14)
values.put("visibility", 0);
Использовать видимость, только если версия устройства меньше 14 (ICS)
Ответ 4
У меня есть creted, следующий за методом для гибкости TIMEZONE
//Преобразование TimeZone в GMT, чтобы сэкономить на локальном Db, чтобы избежать
// Противоречие над сервером
private String convertDateTimeZone(long originalDate) {
String newDate = "";
Date date = new Date(originalDate);
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
Date parsed = null;
try {
parsed = formatter.parse(formatter.format(date).toString());
TimeZone tz = TimeZone.getTimeZone("GMT");
SimpleDateFormat destFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
destFormat.setTimeZone(tz);
newDate = destFormat.format(parsed);
} catch (Exception e) {
}
return newDate;
}
Ответ 5
Я использовал следующий код для чтения всех событий в календаре.
public boolean isEventInCal(Context context, String cal_meeting_id) {
Cursor cursor = context.getContentResolver().query(
Uri.parse("content://com.android.calendar/events"),
new String[] { "_id" }, " _id = ? ",
new String[] { cal_meeting_id }, null);
if (cursor.moveToFirst()) {
// will give all events
return true;
}
return false;
}
Ответ 6
public static ArrayList<String> readCalendarEvent(Context context) {
Cursor cursor = context.getContentResolver()
.query(
Uri.parse("content://com.android.calendar/events"),
new String[] { "calendar_id", "title", "description",
"dtstart", "dtend", "eventLocation" }, null,
null, null);
cursor.moveToFirst();
// fetching calendars name
String CNames[] = new String[cursor.getCount()];
// fetching calendars id
nameOfEvent.clear();
startDates.clear();
endDates.clear();
descriptions.clear();
Log.d("cnameslength",""+CNames.length);
if (CNames.length==0)
{
Toast.makeText(context,"No event exists in calendar",Toast.LENGTH_LONG).show();
}
for (int i = 0; i < CNames.length; i++) {
nameOfEvent.add(cursor.getString(1));
startDates.add(getDate(Long.parseLong(cursor.getString(3))));
endDates.add(getDate(Long.parseLong(cursor.getString(4))));
descriptions.add(cursor.getString(2));
CNames[i] = cursor.getString(1);
cursor.moveToNext();
Log.d("datacur",""+nameOfEvent.get(i));
Log.d("datacur",""+startDates.get(i));
Log.d("datacur",""+endDates.get(i));
Log.d("datacur",""+descriptions.get(i));
String filename=nameOfEvent.get(i)+"::"+startDates.get(i)+"::"+endDates.get(i)+"::"+descriptions.get(i);
generateNoteOnSD(context,nameOfEvent.get(i),filename);
}
return nameOfEvent;
}
public static void generateNoteOnSD(Context context, String sFileName, String sBody) {
try {
File root = new File(Environment.getExternalStorageDirectory(), "Notes");
if (!root.exists()) {
root.mkdirs();
}
File gpxfile = new File(root, sFileName);
FileWriter writer = new FileWriter(gpxfile);
writer.append(sBody);
writer.flush();
writer.close();
Toast.makeText(context, "Successfully Backup Created", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
Ответ 7
Я ИСПОЛЬЗУЮ ЖЕ КОДЕКС С ИСПОЛЬЗОВАНИЕМ CONTENT_RESOLVER И CONTENT_VALUES, НО ЭТО НЕ РАБОТАЕТ НА ВСЕХ СМАРТФОНАХ, КАК ЭТО РАБОТАЕТ АБСОЛЮТНО ШТРОНО В МИ-ТЕЛЕФОНАХ, НО ЭТО ИСКЛЮЧАЕТ ИСКЛЮЧЕНИЕ ИМЕНИ SQLITED, ИСКЛЮЧЕНИЕ ИМЕННО, ТАК ЧТО ТАК.... МОЯ АКТУАЛЬНАЯ НЕОБХОДИМОСТЬ ВСТАВЛЯТЬ СОБЫТИЯ И ПРИГЛАШАТЬ ПРИСУТСТВУЮЩИХ В КАЛЕНДАРЬ GOOGLE через ПРИЛОЖЕНИЕ ANDROID, ДЛЯ ЭТОГО ДОСТУПНЫ ЛЮБЫЕ ДРУГИЕ ОПЦИИ..?? ЕСЛИ ЛЮБЫЕ ПРЕДЛАГАЕТ ЕГО