广告
返回顶部
首页 > 资讯 > 精选 >Android怎么实现系统日历同步日程
  • 181
分享到

Android怎么实现系统日历同步日程

2023-06-14 20:06:37 181人浏览 八月长安
摘要

这篇文章主要介绍Android怎么实现系统日历同步日程,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Android是什么Android是一种基于linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手

这篇文章主要介绍Android怎么实现系统日历同步日程,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

Android是什么

Android是一种基于linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发

Android实现系统日历同步日程的具体内容如下

Android怎么实现系统日历同步日程

权限

<uses-permission android:name="android.permission.WRITE_CALENDAR" /><uses-permission android:name="android.permission.READ_CALENDAR" />

动态权限Activity中

if (ContextCompat.checkSelfPermission(this,                Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {            ActivityCompat.requestPermissions(this,                    new String[]{Manifest.permission.WRITE_CALENDAR,                            Manifest.permission.READ_CALENDAR}, 1);  }

使用

String tipTime = "2021-04-25 12:00";long start = TimeUtils.stringToLong(tipTime ,"yyyy-MM-dd HH:mm");        long end = start + 60 * 60 * 1000L;        LogUtil.d("start:" + start);        LogUtil.d("end:" + end);         String[] split = tipTime.split(" ");        String[] dateStr = split[0].split("-");        int month = Integer.parseInt(dateStr[1]);        int day = Integer.parseInt(dateStr[2]);         String until = "20221231T235959Z";//截止时间:2022年12月31日23点59分59秒        String mRule = "";         switch (mRepeatType) {            case 1://不重复                mRule = null;                break;            case 2://按年重复(每年的某月某日)                mRule = "FREQ=YEARLY;UNTIL=" + until + ";WKST=SU;BYMONTH=" + month + ";BYMONTHDAY=" + day;                break;            case 3://按月重复(每月的某天)                mRule = "FREQ=MONTHLY;UNTIL=" + until + ";WKST=SU;BYMONTHDAY=" + day;                break;            case 4://按周重复                String date = split[0];                String week = TimeUtils.getWeek(date);                switch (week) {                    case "周日":                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=SU";                        break;                    case "周一":                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=MO";                        break;                    case "周二":                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=TU";                        break;                    case "周三":                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=WE";                        break;                    case "周四":                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=TH";                        break;                    case "周五":                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=FR";                        break;                    case "周六":                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=SA";                        break;                }                break;            case 5://按天(每天)                mRule = "FREQ=DaiLY;UNTIL=" + until;                break;            case 6://自定义周几重复,可多选                mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=";                String[] weeks = mSelectedWeekStr.split(",");                for (int i = 0; i < weeks.length; i++) {                    if (weeks[i].equals("周日")) {                        mRule += "SU,";                    } else if (weeks[i].equals("周一")) {                        mRule += "MO,";                    } else if (weeks[i].equals("周二")) {                        mRule += "TU,";                    } else if (weeks[i].equals("周三")) {                        mRule += "WE,";                    } else if (weeks[i].equals("周四")) {                        mRule += "TH,";                    } else if (weeks[i].equals("周五")) {                        mRule += "FR,";                    } else if (weeks[i].equals("周六")) {                        mRule += "SA,";                    }                }                if (mRule.endsWith(",")) {                    mRule.substring(0, mRule.length() - 1);                }                break;        }        LogUtil.d("mRule:" + mRule);         CalendarEvent calendarEvent = new CalendarEvent(                mContent, mContent,                "",                start,                end,                0, mRule        ); // 添加事件int addResult = CalendarProviderManager.addCalendarEvent(AddScheduleActivity.this, calendarEvent);if (addResult == 0) {        ToastUtil.showShortToast("插入成功"); } else if (addResult == -1) {         ToastUtil.showShortToast("插入失败"); } else if (addResult == -2) {         ToastUtil.showShortToast("没有权限"); }

时间转换方法

public static long stringToLong(String strTime, String fORMatType) {        Date date = null; // String类型转成date类型        try {            date = stringToDate(strTime, formatType);        } catch (Exception e) {            e.printStackTrace();        }        if (date == null) {            return 0;        } else {            long currentTime = dateToLong(date); // date类型转成long类型            return currentTime;        }    }       public static Date stringToDate(String strTime, String formatType) {        SimpleDateFormat formatter = new SimpleDateFormat(formatType);        Date date = null;        try {            date = formatter.parse(strTime);        } catch (ParseException e) {            e.printStackTrace();        }        return date;    }   // date要转换的date类型的时间    public static long dateToLong(Date date) {        return date.getTime();    }

CalendarProviderManager 类

import android.content.ContentUris;import android.content.ContentValues;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager;import android.database.Cursor;import android.graphics.Color;import android.net.Uri;import android.os.Build;import android.provider.CalendarContract; import calendarprovider.Util; import java.util.ArrayList;import java.util.List;import java.util.TimeZone; import static com.kyle.calendarprovider.Util.checkContextNull; public class CalendarProviderManager {     private static StringBuilder builder = new StringBuilder();          @SuppressWarnings("WeakerAccess")    public static long obtainCalendarAccountID(Context context) {        long calID = checkCalendarAccount(context);        if (calID >= 0) {            return calID;        } else {            return createCalendarAccount(context);        }    }         private static long checkCalendarAccount(Context context) {        try (Cursor cursor = context.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI,                null, null, null, null)) {            // 不存在日历账户            if (null == cursor) {                return -1;            }            int count = cursor.getCount();            // 存在日历账户,获取第一个账户的ID            if (count > 0) {                cursor.moveToFirst();                return cursor.getInt(cursor.getColumnIndex(CalendarContract.Calendars._ID));            } else {                return -1;            }        }    }         private static long createCalendarAccount(Context context) {        // 系统日历表        Uri uri = CalendarContract.Calendars.CONTENT_URI;         // 要创建的账户        Uri accountUri;         // 开始组装账户数据        ContentValues account = new ContentValues();        // 账户类型:本地        // 在添加账户时,如果账户类型不存在系统中,则可能该新增记录会被标记为脏数据而被删除        // 设置为ACCOUNT_TYPE_LOCAL可以保证在不存在账户类型时,该新增数据不会被删除        account.put(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);        // 日历在表中的名称        account.put(CalendarContract.Calendars.NAME, CALENDAR_NAME);        // 日历账户的名称        account.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDAR_ACCOUNT_NAME);        // 账户显示的名称        account.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDAR_DISPLAY_NAME);        // 日历的颜色        account.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.parseColor("#515bd4"));        // 用户对此日历的获取使用权限等级        account.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);        // 设置此日历可见        account.put(CalendarContract.Calendars.VISIBLE, 1);        // 日历时区        account.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, TimeZone.getDefault().getID());        // 可以修改日历时区        account.put(CalendarContract.Calendars.CAN_MODIFY_TIME_ZONE, 1);        // 同步此日历到设备上        account.put(CalendarContract.Calendars.SYNC_EVENTS, 1);        // 拥有者的账户        account.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDAR_ACCOUNT_NAME);        // 可以响应事件        account.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 1);        // 单个事件设置的最大的提醒数        account.put(CalendarContract.Calendars.MAX_REMINDERS, 8);        // 设置允许提醒的方式        account.put(CalendarContract.Calendars.ALLOWED_REMINDERS, "0,1,2,3,4");        // 设置日历支持的可用性类型        account.put(CalendarContract.Calendars.ALLOWED_AVAILABILITY, "0,1,2");        // 设置日历允许的出席者类型        account.put(CalendarContract.Calendars.ALLOWED_ATTENDEE_TYPES, "0,1,2");                 uri = uri.buildUpon()                .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDAR_ACCOUNT_NAME)                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE,                        CalendarContract.Calendars.CALENDAR_LOCATION)                .build();         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            // 检查日历权限            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(                    "android.permission.WRITE_CALENDAR")) {                accountUri = context.getContentResolver().insert(uri, account);            } else {                return -2;            }        } else {            accountUri = context.getContentResolver().insert(uri, account);        }         return accountUri == null ? -1 : ContentUris.parseId(accountUri);    }         public static int deleteCalendarAccountByName(Context context) {        checkContextNull(context);         int deleteCount;        Uri uri = CalendarContract.Calendars.CONTENT_URI;         String selection = "((" + CalendarContract.Calendars.ACCOUNT_NAME + " = ?) AND ("                + CalendarContract.Calendars.ACCOUNT_TYPE + " = ?))";        String[] selectionArgs = new String[]{CALENDAR_ACCOUNT_NAME, CalendarContract.ACCOUNT_TYPE_LOCAL};         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(                    "android.permission.WRITE_CALENDAR")) {                deleteCount = context.getContentResolver().delete(uri, selection, selectionArgs);            } else {                return -2;            }        } else {            deleteCount = context.getContentResolver().delete(uri, selection, selectionArgs);        }         return deleteCount;    }      // ------------------------------- 添加日历事件 -----------------------------------         public static int addCalendarEvent(Context context, CalendarEvent calendarEvent) {                   checkContextNull(context);         // 获取日历账户ID,也就是要将事件插入到的账户        long calID = obtainCalendarAccountID(context);         // 系统日历事件表        Uri uri1 = CalendarContract.Events.CONTENT_URI;        // 创建的日历事件        Uri eventUri;         // 系统日历事件提醒表        Uri uri2 = CalendarContract.Reminders.CONTENT_URI;        // 创建的日历事件提醒        Uri reminderUri;         // 开始组装事件数据        ContentValues event = new ContentValues();        // 事件要插入到的日历账户        event.put(CalendarContract.Events.CALENDAR_ID, calID);        setupEvent(calendarEvent, event);          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            // 判断权限            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(                    "android.permission.WRITE_CALENDAR")) {                eventUri = context.getContentResolver().insert(uri1, event);            } else {                return -2;            }        } else {            eventUri = context.getContentResolver().insert(uri1, event);        }         if (null == eventUri) {            return -1;        }          if (-2 != calendarEvent.getAdvanceTime()) {            // 获取事件ID            long eventID = ContentUris.parseId(eventUri);             // 开始组装事件提醒数据            ContentValues reminders = new ContentValues();            // 此提醒所对应的事件ID            reminders.put(CalendarContract.Reminders.EVENT_ID, eventID);            // 设置提醒提前的时间(0:准时  -1:使用系统默认)            reminders.put(CalendarContract.Reminders.MINUTES, calendarEvent.getAdvanceTime());            // 设置事件提醒方式为通知警报            reminders.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);            reminderUri = context.getContentResolver().insert(uri2, reminders);             if (null == reminderUri) {                return -1;            }        }         return 0;    }      // ------------------------------- 更新日历事件 -----------------------------------         public static int updateCalendarEvent(Context context, long eventID, CalendarEvent newCalendarEvent) {        checkContextNull(context);         int updatedCount1;         Uri uri1 = CalendarContract.Events.CONTENT_URI;        Uri uri2 = CalendarContract.Reminders.CONTENT_URI;         ContentValues event = new ContentValues();        setupEvent(newCalendarEvent, event);         // 更新匹配条件        String selection1 = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs1 = new String[]{String.valueOf(eventID)};         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(                    "android.permission.WRITE_CALENDAR")) {                updatedCount1 = context.getContentResolver().update(uri1, event, selection1, selectionArgs1);            } else {                return -2;            }        } else {            updatedCount1 = context.getContentResolver().update(uri1, event, selection1, selectionArgs1);        }          ContentValues reminders = new ContentValues();        reminders.put(CalendarContract.Reminders.MINUTES, newCalendarEvent.getAdvanceTime());        reminders.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);         // 更新匹配条件        String selection2 = "(" + CalendarContract.Reminders.EVENT_ID + " = ?)";        String[] selectionArgs2 = new String[]{String.valueOf(eventID)};         int updatedCount2 = context.getContentResolver().update(uri2, reminders, selection2, selectionArgs2);         return (updatedCount1 + updatedCount2) / 2;    }         public static int updateCalendarEventbeginTime(Context context, long eventID, long newBeginTime) {        checkContextNull(context);         Uri uri = CalendarContract.Events.CONTENT_URI;         // 新的数据        ContentValues event = new ContentValues();        event.put(CalendarContract.Events.DTSTART, newBeginTime);         // 匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, event, selection, selectionArgs);    }         public static int updateCalendarEventEndTime(Context context, long eventID, long newEndTime) {        checkContextNull(context);         Uri uri = CalendarContract.Events.CONTENT_URI;         // 新的数据        ContentValues event = new ContentValues();        event.put(CalendarContract.Events.DTEND, newEndTime);          // 匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, event, selection, selectionArgs);    }         public static int updateCalendarEventTime(Context context, long eventID, long newBeginTime,                                              long newEndTime) {        checkContextNull(context);         Uri uri = CalendarContract.Events.CONTENT_URI;         // 新的数据        ContentValues event = new ContentValues();        event.put(CalendarContract.Events.DTSTART, newBeginTime);        event.put(CalendarContract.Events.DTEND, newEndTime);          // 匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, event, selection, selectionArgs);    }         public static int updateCalendarEventTitle(Context context, long eventID, String newTitle) {        checkContextNull(context);         Uri uri = CalendarContract.Events.CONTENT_URI;         // 新的数据        ContentValues event = new ContentValues();        event.put(CalendarContract.Events.TITLE, newTitle);          // 匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, event, selection, selectionArgs);    }         public static int updateCalendarEventDes(Context context, long eventID, String newEventDes) {        checkContextNull(context);         Uri uri = CalendarContract.Events.CONTENT_URI;         // 新的数据        ContentValues event = new ContentValues();        event.put(CalendarContract.Events.DESCRIPTION, newEventDes);          // 匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, event, selection, selectionArgs);    }         public static int updateCalendarEventLocation(Context context, long eventID, String newEventLocation) {        checkContextNull(context);         Uri uri = CalendarContract.Events.CONTENT_URI;         // 新的数据        ContentValues event = new ContentValues();        event.put(CalendarContract.Events.EVENT_LOCATION, newEventLocation);          // 匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, event, selection, selectionArgs);    }         public static int updateCalendarEventTitAndDes(Context context, long eventID, String newEventTitle,                                                   String newEventDes) {        checkContextNull(context);         Uri uri = CalendarContract.Events.CONTENT_URI;         // 新的数据        ContentValues event = new ContentValues();        event.put(CalendarContract.Events.TITLE, newEventTitle);        event.put(CalendarContract.Events.DESCRIPTION, newEventDes);          // 匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, event, selection, selectionArgs);    }         public static int updateCalendarEventCommonInfo(Context context, long eventID, String newEventTitle,                                                    String newEventDes, String newEventLocation) {        checkContextNull(context);         Uri uri = CalendarContract.Events.CONTENT_URI;         // 新的数据        ContentValues event = new ContentValues();        event.put(CalendarContract.Events.TITLE, newEventTitle);        event.put(CalendarContract.Events.DESCRIPTION, newEventDes);        event.put(CalendarContract.Events.EVENT_LOCATION, newEventLocation);          // 匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, event, selection, selectionArgs);    }         private static int updateCalendarEventReminder(Context context, long eventID, long newAdvanceTime) {        checkContextNull(context);         Uri uri = CalendarContract.Reminders.CONTENT_URI;         ContentValues reminders = new ContentValues();        reminders.put(CalendarContract.Reminders.MINUTES, newAdvanceTime);         // 更新匹配条件        String selection2 = "(" + CalendarContract.Reminders.EVENT_ID + " = ?)";        String[] selectionArgs2 = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, reminders, selection2, selectionArgs2);    }         private static int updateCalendarEventRRule(Context context, long eventID, String newRRule) {        checkContextNull(context);         Uri uri = CalendarContract.Events.CONTENT_URI;         // 新的数据        ContentValues event = new ContentValues();        event.put(CalendarContract.Events.RRULE, newRRule);         // 匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         return context.getContentResolver().update(uri, event, selection, selectionArgs);    }      // ------------------------------- 删除日历事件 -----------------------------------         public static int deleteCalendarEvent(Context context, long eventID) {        checkContextNull(context);         int deletedCount1;        Uri uri1 = CalendarContract.Events.CONTENT_URI;        Uri uri2 = CalendarContract.Reminders.CONTENT_URI;         // 删除匹配条件        String selection = "(" + CalendarContract.Events._ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(eventID)};         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(                    "android.permission.WRITE_CALENDAR")) {                deletedCount1 = context.getContentResolver().delete(uri1, selection, selectionArgs);            } else {                return -2;            }        } else {            deletedCount1 = context.getContentResolver().delete(uri1, selection, selectionArgs);        }         // 删除匹配条件        String selection2 = "(" + CalendarContract.Reminders.EVENT_ID + " = ?)";        String[] selectionArgs2 = new String[]{String.valueOf(eventID)};         int deletedCount2 = context.getContentResolver().delete(uri2, selection2, selectionArgs2);         return (deletedCount1 + deletedCount2) / 2;    }      // ------------------------------- 查询日历事件 -----------------------------------         public static List<CalendarEvent> queryAccountEvent(Context context, long calID) {        checkContextNull(context);         final String[] EVENT_PROJECTION = new String[]{                CalendarContract.Events.CALENDAR_ID,             // 在表中的列索引0                CalendarContract.Events.TITLE,                   // 在表中的列索引1                CalendarContract.Events.DESCRIPTION,             // 在表中的列索引2                CalendarContract.Events.EVENT_LOCATION,          // 在表中的列索引3                CalendarContract.Events.DISPLAY_COLOR,           // 在表中的列索引4                CalendarContract.Events.STATUS,                  // 在表中的列索引5                CalendarContract.Events.DTSTART,                 // 在表中的列索引6                CalendarContract.Events.DTEND,                   // 在表中的列索引7                CalendarContract.Events.DURATION,                // 在表中的列索引8                CalendarContract.Events.EVENT_TIMEZONE,          // 在表中的列索引9                CalendarContract.Events.EVENT_END_TIMEZONE,      // 在表中的列索引10                CalendarContract.Events.ALL_DAY,                 // 在表中的列索引11                CalendarContract.Events.ACCESS_LEVEL,            // 在表中的列索引12                CalendarContract.Events.AVAILABILITY,            // 在表中的列索引13                CalendarContract.Events.HAS_ALARM,               // 在表中的列索引14                CalendarContract.Events.RRULE,                   // 在表中的列索引15                CalendarContract.Events.RDATE,                   // 在表中的列索引16                CalendarContract.Events.HAS_ATTENDEE_DATA,       // 在表中的列索引17                CalendarContract.Events.LAST_DATE,               // 在表中的列索引18                CalendarContract.Events.ORGANIZER,               // 在表中的列索引19                CalendarContract.Events.IS_ORGANIZER,            // 在表中的列索引20                CalendarContract.Events._ID                      // 在表中的列索引21        };         // 事件匹配        Uri uri = CalendarContract.Events.CONTENT_URI;        Uri uri2 = CalendarContract.Reminders.CONTENT_URI;         String selection = "(" + CalendarContract.Events.CALENDAR_ID + " = ?)";        String[] selectionArgs = new String[]{String.valueOf(calID)};         Cursor cursor;         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(                    "android.permission.READ_CALENDAR")) {                cursor = context.getContentResolver().query(uri, EVENT_PROJECTION, selection,                        selectionArgs, null);            } else {                return null;            }        } else {            cursor = context.getContentResolver().query(uri, EVENT_PROJECTION, selection,                    selectionArgs, null);        }         if (null == cursor) {            return null;        }         // 查询结果        List<CalendarEvent> result = new ArrayList<>();         // 开始查询数据        if (cursor.moveToFirst()) {            do {                CalendarEvent calendarEvent = new CalendarEvent();                result.add(calendarEvent);                calendarEvent.setId(cursor.getLong(cursor.getColumnIndex(                        CalendarContract.Events._ID)));                calendarEvent.setCalID(cursor.getLong(cursor.getColumnIndex(                        CalendarContract.Events.CALENDAR_ID)));                calendarEvent.setTitle(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.TITLE)));                calendarEvent.setDescription(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.DESCRIPTION)));                calendarEvent.setEventLocation(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.EVENT_LOCATION)));                calendarEvent.setDisplayColor(cursor.getInt(cursor.getColumnIndex(                        CalendarContract.Events.DISPLAY_COLOR)));                calendarEvent.setStatus(cursor.getInt(cursor.getColumnIndex(                        CalendarContract.Events.STATUS)));                calendarEvent.setStart(cursor.getLong(cursor.getColumnIndex(                        CalendarContract.Events.DTSTART)));                calendarEvent.setEnd(cursor.getLong(cursor.getColumnIndex(                        CalendarContract.Events.DTEND)));                calendarEvent.setDuration(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.DURATION)));                calendarEvent.setEventTimeZone(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.EVENT_TIMEZONE)));                calendarEvent.setEventEndTimeZone(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.EVENT_END_TIMEZONE)));                calendarEvent.setAllDay(cursor.getInt(cursor.getColumnIndex(                        CalendarContract.Events.ALL_DAY)));                calendarEvent.setAccessLevel(cursor.getInt(cursor.getColumnIndex(                        CalendarContract.Events.ACCESS_LEVEL)));                calendarEvent.setAvailability(cursor.getInt(cursor.getColumnIndex(                        CalendarContract.Events.AVAILABILITY)));                calendarEvent.setHasAlarm(cursor.getInt(cursor.getColumnIndex(                        CalendarContract.Events.HAS_ALARM)));                calendarEvent.setRRule(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.RRULE)));                calendarEvent.setRDate(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.RDATE)));                calendarEvent.setHasAttendeeData(cursor.getInt(cursor.getColumnIndex(                        CalendarContract.Events.HAS_ATTENDEE_DATA)));                calendarEvent.setLastDate(cursor.getInt(cursor.getColumnIndex(                        CalendarContract.Events.LAST_DATE)));                calendarEvent.setOrganizer(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.ORGANIZER)));                calendarEvent.setIsOrganizer(cursor.getString(cursor.getColumnIndex(                        CalendarContract.Events.IS_ORGANIZER)));                  // ----------------------- 开始查询事件提醒 ------------------------------                String[] REMINDER_PROJECTION = new String[]{                        CalendarContract.Reminders._ID,                     // 在表中的列索引0                        CalendarContract.Reminders.EVENT_ID,                // 在表中的列索引1                        CalendarContract.Reminders.MINUTES,                 // 在表中的列索引2                        CalendarContract.Reminders.METHOD,                  // 在表中的列索引3                };                String selection2 = "(" + CalendarContract.Reminders.EVENT_ID + " = ?)";                String[] selectionArgs2 = new String[]{String.valueOf(calendarEvent.getId())};                 try (Cursor reminderCursor = context.getContentResolver().query(uri2, REMINDER_PROJECTION,                        selection2, selectionArgs2, null)) {                    if (null != reminderCursor) {                        if (reminderCursor.moveToFirst()) {                            List<CalendarEvent.EventReminders> reminders = new ArrayList<>();                            do {                                CalendarEvent.EventReminders reminders1 = new CalendarEvent.EventReminders();                                reminders.add(reminders1);                                reminders1.setReminderId(reminderCursor.getLong(                                        reminderCursor.getColumnIndex(CalendarContract.Reminders._ID)));                                reminders1.setReminderEventID(reminderCursor.getLong(                                        reminderCursor.getColumnIndex(CalendarContract.Reminders.EVENT_ID)));                                reminders1.setReminderMinute(reminderCursor.getInt(                                        reminderCursor.getColumnIndex(CalendarContract.Reminders.MINUTES)));                                reminders1.setReminderMethod(reminderCursor.getInt(                                        reminderCursor.getColumnIndex(CalendarContract.Reminders.METHOD)));                            } while (reminderCursor.moveToNext());                            calendarEvent.setReminders(reminders);                        }                    }                }            } while (cursor.moveToNext());            cursor.close();        }         return result;    }         public static boolean isEventAlreadyExist(Context context, long begin, long end, String title) {        String[] projection = new String[]{                CalendarContract.Instances.BEGIN,                CalendarContract.Instances.END,                CalendarContract.Instances.TITLE        };         Cursor cursor = CalendarContract.Instances.query(                context.getContentResolver(), projection, begin, end, title);         return null != cursor && cursor.moveToFirst()                && cursor.getString(                cursor.getColumnIndex(CalendarContract.Instances.TITLE)).equals(title);    }      // ------------------------------- 日历事件相关 -----------------------------------         private static void setupEvent(CalendarEvent calendarEvent, ContentValues event) {        // 事件开始时间        event.put(CalendarContract.Events.DTSTART, calendarEvent.getStart());        // 事件结束时间        event.put(CalendarContract.Events.DTEND, calendarEvent.getEnd());        // 事件标题        event.put(CalendarContract.Events.TITLE, calendarEvent.getTitle());        // 事件描述(对应手机系统日历备注栏)        event.put(CalendarContract.Events.DESCRIPTION, calendarEvent.getDescription());        // 事件地点        event.put(CalendarContract.Events.EVENT_LOCATION, calendarEvent.getEventLocation());        // 事件时区        event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());        // 定义事件的显示,默认即可        event.put(CalendarContract.Events.ACCESS_LEVEL, CalendarContract.Events.ACCESS_DEFAULT);        // 事件的状态        event.put(CalendarContract.Events.STATUS, 0);        // 设置事件提醒警报可用        event.put(CalendarContract.Events.HAS_ALARM, 1);        // 设置事件忙        event.put(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY);        if (null != calendarEvent.getRRule()) {            // 设置事件重复规则            event.put(CalendarContract.Events.RRULE,                    getFullRRuleForRRule(calendarEvent.getRRule(),                            calendarEvent.getStart(), calendarEvent.getEnd()));        }    }         private static String getFullRRuleForRRule(String rRule, long beginTime, long endTime) {        builder.delete(0, builder.length());         switch (rRule) {            case RRuleConstant.REPEAT_WEEKLY_BY_MO:            case RRuleConstant.REPEAT_WEEKLY_BY_TU:            case RRuleConstant.REPEAT_WEEKLY_BY_WE:            case RRuleConstant.REPEAT_WEEKLY_BY_TH:            case RRuleConstant.REPEAT_WEEKLY_BY_FR:            case RRuleConstant.REPEAT_WEEKLY_BY_SA:            case RRuleConstant.REPEAT_WEEKLY_BY_SU:                return builder.append(rRule).append(Util.getFinalRRuleMode(endTime)).toString();            case RRuleConstant.REPEAT_CYCLE_WEEKLY:                return builder.append(rRule).append(Util.getWeekForDate(beginTime)).append("; UNTIL = ")                        .append(Util.getFinalRRuleMode(endTime)).toString();            case RRuleConstant.REPEAT_CYCLE_MONTHLY:                return builder.append(rRule).append(Util.getDayOfMonth(beginTime))                        .append("; UNTIL = ").append(Util.getFinalRRuleMode(endTime)).toString();            default:                return rRule;        }    }      // ------------------------------- 通过Intent启动系统日历 -----------------------------------              public static void startCalendarForIntentToInsert(Context context, long beginTime, long endTime,                                                      String title, String des, String location,                                                      boolean isAllDay) {        checkCalendarAccount(context);          // FIXME: 2019/3/6 VIVO手机无法打开界面,找不到对应的Activity  com.bbk.calendar        Intent intent = new Intent(Intent.ACTION_INSERT)                .setData(CalendarContract.Events.CONTENT_URI)                .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime)                .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime)                .putExtra(CalendarContract.Events.ALL_DAY, isAllDay)                .putExtra(CalendarContract.Events.TITLE, title)                .putExtra(CalendarContract.Events.DESCRIPTION, des)                .putExtra(CalendarContract.Events.EVENT_LOCATION, location);         if (null != intent.resolveActivity(context.getPackageManager())) {            context.startActivity(intent);        }    }         public static void startCalendarForIntentToEdit(Context context, long eventID) {        checkCalendarAccount(context);         Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);        Intent intent = new Intent(Intent.ACTION_EDIT).setData(uri);         if (null != intent.resolveActivity(context.getPackageManager())) {            context.startActivity(intent);        }    }         public static void startCalendarForIntentToView(Context context, long eventID) {        checkCalendarAccount(context);         Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);        Intent intent = new Intent(Intent.ACTION_VIEW).setData(uri);         if (null != intent.resolveActivity(context.getPackageManager())) {            context.startActivity(intent);        }    }      // ----------------------------- 日历账户名相关设置 -----------------------------------     public static String getCalendarName() {        return CALENDAR_NAME;    }     public static void setCalendarName(String calendarName) {        CALENDAR_NAME = calendarName;    }     public static String getCalendarAccountName() {        return CALENDAR_ACCOUNT_NAME;    }     public static void setCalendarAccountName(String calendarAccountName) {        CALENDAR_ACCOUNT_NAME = calendarAccountName;    }     public static String getCalendarDisplayName() {        return CALENDAR_DISPLAY_NAME;    }     public static void setCalendarDisplayName(String calendarDisplayName) {        CALENDAR_DISPLAY_NAME = calendarDisplayName;    } }

CalendarEvent类

public class CalendarEvent {     // ----------------------- 事件属性 -----------------------         private long id;        private long calID;    private String title;    private String description;    private String eventLocation;    private int displayColor;    private int status;    private long start;    private long end;    private String duration;    private String eventTimeZone;    private String eventEndTimeZone;    private int allDay;    private int accessLevel;    private int availability;    private int hasAlarm;    private String rRule;    private String rDate;    private int hasAttendeeData;    private int lastDate;    private String organizer;    private String isOrganizer;      // ----------------------------------------------------------------------------------------        private int advanceTime;    // ----------------------------------------------------------------------------------------      // ----------------------- 事件提醒属性 -----------------------    private List<EventReminders> reminders;     CalendarEvent() {    }         public CalendarEvent(String title, String description, String eventLocation,                         long start, long end, int advanceTime, String rRule) {        this.title = title;        this.description = description;        this.eventLocation = eventLocation;        this.start = start;        this.end = end;        this.advanceTime = advanceTime;        this.rRule = rRule;    }     public int getAdvanceTime() {        return advanceTime;    }     public void setAdvanceTime(int advanceTime) {        this.advanceTime = advanceTime;    }     public long getId() {        return id;    }     void setId(long id) {        this.id = id;    }     public long getCalID() {        return calID;    }     void setCalID(long calID) {        this.calID = calID;    }     public String getTitle() {        return title;    }     void setTitle(String title) {        this.title = title;    }     public String getDescription() {        return description;    }     void setDescription(String description) {        this.description = description;    }     public String getEventLocation() {        return eventLocation;    }     void setEventLocation(String eventLocation) {        this.eventLocation = eventLocation;    }     public int getDisplayColor() {        return displayColor;    }     void setDisplayColor(int displayColor) {        this.displayColor = displayColor;    }     public int getStatus() {        return status;    }     void setStatus(int status) {        this.status = status;    }     public long getStart() {        return start;    }     void setStart(long start) {        this.start = start;    }     public long getEnd() {        return end;    }     void setEnd(long end) {        this.end = end;    }     public String getDuration() {        return duration;    }     void setDuration(String duration) {        this.duration = duration;    }     public String getEventTimeZone() {        return eventTimeZone;    }     void setEventTimeZone(String eventTimeZone) {        this.eventTimeZone = eventTimeZone;    }     public String getEventEndTimeZone() {        return eventEndTimeZone;    }     void setEventEndTimeZone(String eventEndTimeZone) {        this.eventEndTimeZone = eventEndTimeZone;    }     public int getAllDay() {        return allDay;    }     void setAllDay(int allDay) {        this.allDay = allDay;    }     public int getAccessLevel() {        return accessLevel;    }     void setAccessLevel(int accessLevel) {        this.accessLevel = accessLevel;    }     public int getAvailability() {        return availability;    }     void setAvailability(int availability) {        this.availability = availability;    }     public int getHasAlarm() {        return hasAlarm;    }     void setHasAlarm(int hasAlarm) {        this.hasAlarm = hasAlarm;    }     public String getRRule() {        return rRule;    }     void setRRule(String rRule) {        this.rRule = rRule;    }     public String getRDate() {        return rDate;    }     void setRDate(String rDate) {        this.rDate = rDate;    }     public int getHasAttendeeData() {        return hasAttendeeData;    }     void setHasAttendeeData(int hasAttendeeData) {        this.hasAttendeeData = hasAttendeeData;    }     public int getLastDate() {        return lastDate;    }     void setLastDate(int lastDate) {        this.lastDate = lastDate;    }     public String getOrganizer() {        return organizer;    }     void setOrganizer(String organizer) {        this.organizer = organizer;    }     public String getIsOrganizer() {        return isOrganizer;    }     void setIsOrganizer(String isOrganizer) {        this.isOrganizer = isOrganizer;    }     public List<EventReminders> getReminders() {        return reminders;    }     void setReminders(List<EventReminders> reminders) {        this.reminders = reminders;    }     @NonNull    @Override    public String toString() {        return "CalendarEvent{" +                "\n id=" + id +                "\n calID=" + calID +                "\n title='" + title + '\'' +                "\n description='" + description + '\'' +                "\n eventLocation='" + eventLocation + '\'' +                "\n displayColor=" + displayColor +                "\n status=" + status +                "\n start=" + start +                "\n end=" + end +                "\n duration='" + duration + '\'' +                "\n eventTimeZone='" + eventTimeZone + '\'' +                "\n eventEndTimeZone='" + eventEndTimeZone + '\'' +                "\n allDay=" + allDay +                "\n accessLevel=" + accessLevel +                "\n availability=" + availability +                "\n hasAlarm=" + hasAlarm +                "\n rRule='" + rRule + '\'' +                "\n rDate='" + rDate + '\'' +                "\n hasAttendeeData=" + hasAttendeeData +                "\n lastDate=" + lastDate +                "\n organizer='" + organizer + '\'' +                "\n isOrganizer='" + isOrganizer + '\'' +                "\n reminders=" + reminders +                '}';    }     @Override    public int hashCode() {        return (int) (id * 37 + calID);    }         static class EventReminders {         // ----------------------- 事件提醒属性 -----------------------        private long reminderId;        private long reminderEventID;        private int reminderMinute;        private int reminderMethod;         public long getReminderId() {            return reminderId;        }         void setReminderId(long reminderId) {            this.reminderId = reminderId;        }         public long getReminderEventID() {            return reminderEventID;        }         void setReminderEventID(long reminderEventID) {            this.reminderEventID = reminderEventID;        }         public int getReminderMinute() {            return reminderMinute;        }         void setReminderMinute(int reminderMinute) {            this.reminderMinute = reminderMinute;        }         public int getReminderMethod() {            return reminderMethod;        }         void setReminderMethod(int reminderMethod) {            this.reminderMethod = reminderMethod;        }     } }

Util类

public class Util {         private static String getEndDate(long time) {        Date date = new Date(time);        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());        return format.format(date);    }         public static String getFinalRRuleMode(long time) {        return getEndDate(time) + "T235959Z";    }         private static String formatWeek(int week) {        switch (week) {            case 0:                return "SU";            case 1:                return "MO";            case 2:                return "TU";            case 3:                return "WE";            case 4:                return "TH";            case 5:                return "FR";            case 6:                return "SA";            default:                return null;        }    }         public static String getWeekForDate(long time) {        Date date = new Date(time);        Calendar calendar = Calendar.getInstance();        calendar.setTime(date);        int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;        if (week < 0) {            week = 0;        }        return formatWeek(week);    }         public static int getDayOfMonth(long time) {        Date date = new Date(time);        Calendar calendar = Calendar.getInstance();        calendar.setTime(date);        return calendar.get(Calendar.DAY_OF_MONTH);    }         public static void checkContextNull(Context context) {        if (null == context) {            throw new IllegalArgumentException("context can not be null");        }    } }

以上是“Android怎么实现系统日历同步日程”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

--结束END--

本文标题: Android怎么实现系统日历同步日程

本文链接: https://www.lsjlt.com/news/275182.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android怎么实现系统日历同步日程
    这篇文章主要介绍Android怎么实现系统日历同步日程,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Android是什么Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手...
    99+
    2023-06-14
  • Android实现系统日历同步日程
    本文实例为大家分享了Android实现系统日历同步日程的具体代码,供大家参考,具体内容如下 1、权限 <uses-permission android:name="and...
    99+
    2022-11-12
  • win10日历怎么同步到安卓手机
    这篇“win10日历怎么同步到安卓手机”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“win10日历怎么同步到安卓手机”文章吧...
    99+
    2023-07-01
  • php怎么实现日历
    本文操作环境:Windows7系统、PHP7.1版、DELL G3电脑php怎么实现日历?PHP实现的日历功能示例具体如下:<php header("Content-Type:text/html;charset=utf-8...
    99+
    2016-05-29
    PHP 日历
  • java日历表怎么实现
    Java中的日历类是Calendar,可以通过它来实现日历表。下面是一个简单的Java日历表的实现:import java.util...
    99+
    2023-05-13
    java日历表 java
  • java怎么获取系统农历日期
    在Java中,可以使用`java.util.Calendar`类来获取系统农历日期。但是,默认的`Calendar`类只能获取公历日...
    99+
    2023-08-17
    java
  • php js怎么实现日历签到
    本篇内容主要讲解“php js怎么实现日历签到”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php js怎么实现日历签到”吧!php js实现日历签到的方法:首先创建好前台代码“$("...
    99+
    2023-06-20
  • 微信小程序日历插件怎么实现
    这篇文章主要介绍了微信小程序日历插件怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇微信小程序日历插件怎么实现文章都会有所收获,下面我们一起来看看吧。微信小程序的日历插件,主要针对酒店选择时间段的日历,带...
    99+
    2023-06-26
  • 微信小程序日历签到怎么实现
    这篇文章主要介绍“微信小程序日历签到怎么实现”,在日常操作中,相信很多人在微信小程序日历签到怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”微信小程序日历签到怎么实现”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-26
  • 怎么在Android中实现一个可标记日历功能
    今天就跟大家聊聊有关怎么在Android中实现一个可标记日历功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。DatabaseHelper .java package co...
    99+
    2023-05-31
    android roi %d
  • 小程序下订单日历插件怎么实现
    今天小编给大家分享一下小程序下订单日历插件怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。  这个插件分为上下两部分,...
    99+
    2023-06-26
  • 怎么用纯CSS实现日历图标
    这篇文章主要介绍“怎么用纯CSS实现日历图标”,在日常操作中,相信很多人在怎么用纯CSS实现日历图标问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用纯CSS实现日历图标”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-17
  • 编程算法:如何实现 ASP 日志同步?
    ASP(Active Server Pages)是一种基于服务器端脚本的动态网页技术。在ASP应用程序中,日志文件是记录网站访问情况的重要组成部分。然而,在多服务器环境下,日志文件的同步和统计是一项具有挑战性的任务。本文将介绍如何通过编程...
    99+
    2023-08-17
    日志 同步 编程算法
  • 微信小程序向系统日历添加事件(提醒)实现
    直接上代码 // pages/calendar/calendar.jsPage({ // 点击添加日程按钮 handleAddCalendar() { wx.getSetting({ success(res) { ...
    99+
    2023-09-22
    微信小程序 小程序 javascript
  • JavaScript怎么实现自定义日历效果
    本篇内容主要讲解“JavaScript怎么实现自定义日历效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript怎么实现自定义日历效果”吧!实现思路:获取每个月的第一天是星期几,然...
    99+
    2023-06-25
  • C#中怎么实现一个日历控件
    本篇文章给大家分享的是有关C#中怎么实现一个日历控件,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。定制C#日历控件在把会议添加到数据库中之前,先修改一下日历的显示。***用另一...
    99+
    2023-06-18
  • vue怎么实现周日历切换效果
    本篇内容介绍了“vue怎么实现周日历切换效果”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!效果如下:代码:<!DOCTYPE ...
    99+
    2023-06-30
  • Java中怎么实现动态日历效果
    本篇文章为大家展示了Java中怎么实现动态日历效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。题目:动态日历输入年份,月份,显示当前月份日历布局分析实现日历的基本思想为:确定一个基准日期,计算从基...
    99+
    2023-06-20
  • 怎么用Python实现一本个性化日历
    今天小编给大家分享一下怎么用Python实现一本个性化日历的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、准备开始之前,你...
    99+
    2023-06-29
  • 使用JavaScript怎么实现一个日历效果
    这篇文章给大家介绍使用JavaScript怎么实现一个日历效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用...
    99+
    2023-06-07
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作