国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android 操作系統(tǒng)日歷完成提醒功能 附帶開(kāi)關(guān)鬧鐘 適配高版本安卓

這篇具有很好參考價(jià)值的文章主要介紹了Android 操作系統(tǒng)日歷完成提醒功能 附帶開(kāi)關(guān)鬧鐘 適配高版本安卓。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Android 操作系統(tǒng)日歷完成提醒功能 附帶開(kāi)關(guān)鬧鐘

如果想要一個(gè)穩(wěn)定且不用擔(dān)心生命周期的提醒方式,可以試試?yán)孟到y(tǒng)日歷去完成任務(wù)的提醒或某個(gè)活動(dòng)的預(yù)約。
項(xiàng)目倉(cāng)庫(kù)地址在文末

環(huán)境

  • Java 11

  • Android sdk 30

  • Gredle 7.1

    minSdkVersion 23
    targetSdkVersion 30
    
  • 測(cè)試機(jī)型 mi 8(安卓 9) mi10 pro(安卓11) huawei m8(安卓7)

前置知識(shí)

日歷操作表

? 其實(shí)完成這個(gè)功能本質(zhì)是對(duì)安卓原生數(shù)據(jù)庫(kù)的增刪改查操作,下圖就是30sdk中我們可以用到的系統(tǒng)常量

每一個(gè)靜態(tài)類(lèi)都對(duì)應(yīng)這一個(gè)系統(tǒng)中的數(shù)據(jù)表??梢酝ㄟ^(guò) 下面命令去找到對(duì)應(yīng)的路徑

CalendarContract.{table_name}.CONTENT_URI

android 添加日歷提醒,Android,android,java

  • events 是我們主要的任務(wù)內(nèi)容和配置表
  • Reminders 是日歷提醒設(shè)置表
  • extendedProperties 是拓展屬性類(lèi)
  • Calendars 存放基礎(chǔ)信息 如日歷賬戶(hù)等信息

操作日歷和設(shè)置鬧鐘提醒 其實(shí)就是對(duì)上述三張表的處理

ContentValues

? 這個(gè)類(lèi)是用來(lái)存放我們自己定義的一些條件 ,在插入系統(tǒng)表之前 組裝數(shù)據(jù)和一些必備的配置,使用的方式與Map一致。

PS: 因?yàn)榈讓泳S護(hù)了一個(gè)arrayMap 所以允許我們傳入K,V形式的數(shù)據(jù)

    ContentValues event = new ContentValues();
        event.put("title", title);
        event.put("description", description);
        event.put("calendar_id", calId); //插入賬戶(hù)的id
        event.put("eventStatus", 1);
        event.put(CalendarContract.Events._ID, eventId);
        event.put(CalendarContract.Events.HAS_EXTENDED_PROPERTIES, true);
        event.put(CalendarContract.Events.DTSTART, start);
        event.put(CalendarContract.Events.DTEND, end);

我們插入數(shù)據(jù)表的步驟為

  1. 使用 ContentValues 組裝數(shù)據(jù)/加入需要的系統(tǒng)配置
  2. 使用 CalendarContract 拿到對(duì)應(yīng)的系統(tǒng)路徑
  3. 調(diào)用 context.getContentResolver() 這里有封裝好的增上改查方法來(lái)完成對(duì)底層數(shù)據(jù)庫(kù)的操作

功能流程

1、獲取權(quán)限

AndroidManifest 中添加權(quán)限

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

如果安卓版本高 最好在activity中使用動(dòng)態(tài)的權(quán)限校驗(yàn),在初始化的時(shí)候調(diào)用此方法,就可以完成彈窗動(dòng)態(tài)權(quán)限校驗(yàn)了

 checkPermission(0, Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR);   

//     權(quán)限獲取
    private void checkPermission(int callbackId, String... permissionsId) {
        boolean permissions = true;
        for (String p : permissionsId) {
            permissions = permissions && ContextCompat.checkSelfPermission(this, p) == PERMISSION_GRANTED;
        }

        if (!permissions)
            ActivityCompat.requestPermissions(this, permissionsId, callbackId);
    }

android 添加日歷提醒,Android,android,java

2、創(chuàng)建日歷賬戶(hù)

系統(tǒng)其實(shí)有為我們創(chuàng)建默認(rèn)賬戶(hù),但是既然日歷有為我們準(zhǔn)備創(chuàng)建用戶(hù)的接口,那么我們還是創(chuàng)建一個(gè)屬于自己app的用戶(hù),之后的各種操作也不會(huì)影響到系統(tǒng)的內(nèi)容

我們自己定義了日歷賬戶(hù)信息 在每次操作日歷前 確保我們的app日歷賬戶(hù)存在于系統(tǒng)日歷,如果不存在就去創(chuàng)建一個(gè) (不會(huì)重復(fù)創(chuàng)建 不用擔(dān)心賬號(hào)冗余)

    private static String CALENDARS_NAME = "TaskList";
    private static String CALENDARS_ACCOUNT_NAME = "MyTaskList";
    private static String CALENDARS_ACCOUNT_TYPE = "MyTaskList";
    /**
     * 這里創(chuàng)建賬戶(hù)的展示名稱(chēng),系統(tǒng)日歷為我們提供了創(chuàng)建賬戶(hù)的入口,那我們就不使用系統(tǒng)自帶的賬戶(hù),創(chuàng)建一個(gè)自己app的賬戶(hù)
     */
    private static String CALENDARS_DISPLAY_NAME = "靠譜的任務(wù)清單";    

/**
     * 檢查是否存在現(xiàn)有賬戶(hù),存在則返回賬戶(hù)id,否則返回-1
     */
    @SuppressLint("Range")
    private static int checkCalendarAccount(Context context) {
        Cursor userCursor = context.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI, null, null, null, null);
        try {
            if (userCursor == null) { //查詢(xún)返回空值
                return -1;
            }
            int count = userCursor.getCount();
            if (count > 0) { //存在現(xiàn)有賬戶(hù),取第一個(gè)賬戶(hù)的id返回
                for (int i = 0; i <= count - 1; i++) {
                    if (i == 0) {
                        userCursor.moveToFirst();
                    } else {
                        userCursor.moveToNext();
                    }
                    String type = userCursor.getString(userCursor.getColumnIndex(CalendarContract.Calendars.ACCOUNT_TYPE));
                    if (type.equals(CALENDARS_ACCOUNT_TYPE)) {
                        return userCursor.getInt(userCursor.getColumnIndex(CalendarContract.Calendars._ID));
                    }
                }
            }
            return -1;
        } finally {
            if (userCursor != null) {
                userCursor.close();
            }
        }
    }

添加方法

其實(shí)添加方法就和我們平時(shí)操作數(shù)據(jù)庫(kù)十分類(lèi)似,就是組裝數(shù)據(jù),放入到數(shù)據(jù)表中

    private static String CALENDARS_NAME = "TaskList";
    private static String CALENDARS_ACCOUNT_NAME = "MyTaskList";
    private static String CALENDARS_ACCOUNT_TYPE = "MyTaskList";
    /**
     * 這里創(chuàng)建賬戶(hù)的展示名稱(chēng),系統(tǒng)日歷為我們提供了創(chuàng)建賬戶(hù)的入口,那我們就不使用系統(tǒng)自帶的賬戶(hù),創(chuàng)建一個(gè)自己app的賬戶(hù)
     */
    private static String CALENDARS_DISPLAY_NAME = "靠譜的任務(wù)清單";       

    /**
     * 添加日歷賬戶(hù),賬戶(hù)創(chuàng)建成功則返回賬戶(hù)id,否則返回-1
     */
    private static long addCalendarAccount(Context context) {
        TimeZone timeZone = TimeZone.getDefault();
        ContentValues value = new ContentValues();

        value.put(CalendarContract.Calendars.NAME, CALENDARS_NAME);
        value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME);
        value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE);
        value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME);
//        可見(jiàn)度
        value.put(CalendarContract.Calendars.VISIBLE, 1);
//        日歷顏色
        value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE);
//        權(quán)限
        value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
        value.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
//        時(shí)區(qū)
        value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID());
        value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME);
        value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);

        Uri calendarUri = CalendarContract.Calendars.CONTENT_URI;
        calendarUri = calendarUri.buildUpon()
                .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
                .build();

        Uri result = context.getContentResolver().insert(calendarUri, value);
        long id = result == null ? -1 : ContentUris.parseId(result);
        return id;
    }

在擁有檢查和創(chuàng)建方法后,我們?nèi)コ橄笠粋€(gè)條件判斷方法,來(lái)用于一次調(diào)用完成創(chuàng)建日歷賬戶(hù) 檢查的完成流程

checkAndAddCalendarAccount

    /**
     * 檢查是否已經(jīng)添加了日歷賬戶(hù),如果沒(méi)有添加先添加一個(gè)日歷賬戶(hù)再查詢(xún)
     * 獲取賬戶(hù)成功返回賬戶(hù)id,否則返回-1
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    private static int checkAndAddCalendarAccount(Context context) {
        int oldId = checkCalendarAccount(context);
        if (oldId >= 0) {
            return oldId;
        } else {
            long addId = addCalendarAccount(context);
            if (addId >= 0) {
                return checkCalendarAccount(context);
            } else {
                return -1;
            }
        }
    }

3、組裝數(shù)據(jù),添加日程

這個(gè)其實(shí)就比較簡(jiǎn)單了 ,就是為數(shù)據(jù)表添加行數(shù)和內(nèi)容

  1. 檢查日歷賬戶(hù) 并且獲取id

  2. 組裝event 新增event

  3. 根據(jù)isAlarm判斷是否需要添加鬧鐘提醒

    1. 在event數(shù)據(jù)中

       event.put(CalendarContract.Events.HAS_ALARM, 1);
      

      是用于老版本安卓的鬧鐘提醒 比較新的國(guó)內(nèi)安卓版本都不在根據(jù)這個(gè)字段來(lái)判斷了

    2. 新一些的安卓版本 使用ExtendedProperties 來(lái)添加額外屬性,目前已知miui的高版本是需要設(shè)置

       extendedProperties.put(CalendarContract.ExtendedProperties.VALUE, "{\"need_alarm\":true}");
      

      并且賬戶(hù)內(nèi)容要是我們自己創(chuàng)建的賬戶(hù)才可以完成鬧鐘提示

      PS: 在封裝工具類(lèi)前 我是用系統(tǒng)默認(rèn)用戶(hù) 無(wú)法設(shè)置 不知道原因

  4. 設(shè)置 Reminders 日程提醒方式等

  5. 完成日程設(shè)置

調(diào)用完這個(gè)方法你就可以發(fā)現(xiàn)日歷里 有對(duì)應(yīng)的日程了

    /**
     * 這個(gè)是關(guān)鍵方法,調(diào)用插入日程提醒
     *
     * @param context
     * @param eventId         事件id
     * @param title           提醒事件標(biāo)題
     * @param description     事件描述
     * @param reminderTime    任務(wù)開(kāi)始時(shí)間,這里參數(shù)名不太合適,后面會(huì)加提醒時(shí)間,
     * @param endTime         任務(wù)結(jié)束時(shí)間
     * @param previousMinutes 提前多少分鐘提醒,后續(xù)使用
     * @param isAlarm         是否需要鬧鐘提醒
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    @SuppressLint("Range")
    public static Long addCalendarEvent(Context context, long eventId, String title, String description, long reminderTime, long endTime, int previousMinutes, boolean isAlarm) {

        if (context == null) {
            return -1L;
        }
        int calId = checkAndAddCalendarAccount(context); //獲取日歷賬戶(hù)的id
        if (calId < 0) { //獲取賬戶(hù)id失敗直接返回,添加日歷事件失敗
            return -1L;
        }

        //添加日歷事件
        Calendar mCalendar = Calendar.getInstance();
        mCalendar.setTimeInMillis(reminderTime);//設(shè)置開(kāi)始時(shí)間
        long start = mCalendar.getTime().getTime();
        mCalendar.setTimeInMillis(endTime);//設(shè)置終止時(shí)間
        long end = mCalendar.getTime().getTime();
        ContentValues event = new ContentValues();
        event.put("title", title);
        event.put("description", description);
        event.put("calendar_id", calId); //插入賬戶(hù)的id
        event.put("eventStatus", 1);
        event.put(CalendarContract.Events._ID, eventId);
        event.put(CalendarContract.Events.HAS_EXTENDED_PROPERTIES, true);
        event.put(CalendarContract.Events.DTSTART, start);
        event.put(CalendarContract.Events.DTEND, end);
        if (isAlarm) {
            event.put(CalendarContract.Events.HAS_ALARM, 1);//設(shè)置有鬧鐘提醒,但是經(jīng)測(cè)試,此方案無(wú)效
        }
        event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getDisplayName());//這個(gè)是時(shí)區(qū),必須有
        Uri newEvent = context.getContentResolver().insert(CalendarContract.Events.CONTENT_URI, event); //添加事件
        if (newEvent == null) { //添加日歷事件失敗直接返回
            return -1L;
        }
        //擴(kuò)展屬性 用于高版本安卓系統(tǒng)設(shè)置鬧鐘提醒
        if (isAlarm) {
            Uri extendedPropUri = CalendarContract.ExtendedProperties.CONTENT_URI;
            extendedPropUri = extendedPropUri.buildUpon()
                    .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                    .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
                    .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE).build();
            ContentValues extendedProperties = new ContentValues();
            extendedProperties.put(CalendarContract.ExtendedProperties.EVENT_ID, ContentUris.parseId(newEvent));
            extendedProperties.put(CalendarContract.ExtendedProperties.VALUE, "{\"need_alarm\":true}");
            extendedProperties.put(CalendarContract.ExtendedProperties.NAME, "agenda_info");
            Uri uriExtended = context.getContentResolver().insert(extendedPropUri, extendedProperties);
            if (uriExtended == null) { //添加事件提醒失敗直接返回
                return -1L;
            }
        }
        //事件提醒的設(shè)定
        ContentValues values = new ContentValues();
        values.put(CalendarContract.Reminders.EVENT_ID, ContentUris.parseId(newEvent));
        values.put(CalendarContract.Reminders.MINUTES, 0);// 提前previousDate天有提醒
        values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
        Uri uri = context.getContentResolver().insert(CalendarContract.Reminders.CONTENT_URI, values);
        if (uri == null) { //添加事件提醒失敗直接返回
            return -1L;
        }
        Toast.makeText(context, "設(shè)置日程成功!!!", Toast.LENGTH_LONG).show();
        return eventId;
    }

4、 刪除日程

這個(gè)就比較簡(jiǎn)單,因?yàn)槲覀兪亲远x日程id 所以我們直接通過(guò)傳入的id 刪除對(duì)應(yīng)的日程即可,網(wǎng)上的工具類(lèi)都是用title 容易刪除同名日程

    /**
     * 刪除日歷事件
     */
    public static void deleteCalendarEvent(Context context, Long delEventID) {
        if (context == null) {
            return;
        }
        Uri deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, delEventID);
        int rows = context.getContentResolver().delete(deleteUri, null, null);
        if (rows == -1) { //事件刪除失敗
            return;
        }
    }

工具類(lèi)代碼

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.provider.CalendarContract;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.RequiresApi;

import java.util.Calendar;
import java.util.TimeZone;

public class CalendarReminderUtils {

    private static String CALENDARS_NAME = "TaskList";
    private static String CALENDARS_ACCOUNT_NAME = "MyTaskList";
    private static String CALENDARS_ACCOUNT_TYPE = "MyTaskList";
    /**
     * 這里創(chuàng)建賬戶(hù)的展示名稱(chēng),系統(tǒng)日歷為我們提供了創(chuàng)建賬戶(hù)的入口,那我們就不使用系統(tǒng)自帶的賬戶(hù),創(chuàng)建一個(gè)自己app的賬戶(hù)
     */
    private static String CALENDARS_DISPLAY_NAME = "靠譜的任務(wù)清單";

    /**
     * 檢查是否已經(jīng)添加了日歷賬戶(hù),如果沒(méi)有添加先添加一個(gè)日歷賬戶(hù)再查詢(xún)
     * 獲取賬戶(hù)成功返回賬戶(hù)id,否則返回-1
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    private static int checkAndAddCalendarAccount(Context context) {
        int oldId = checkCalendarAccount(context);
        if (oldId >= 0) {
            return oldId;
        } else {
            long addId = addCalendarAccount(context);
            if (addId >= 0) {
                return checkCalendarAccount(context);
            } else {
                return -1;
            }
        }
    }

    /**
     * 檢查是否存在現(xiàn)有賬戶(hù),存在則返回賬戶(hù)id,否則返回-1
     */
    @SuppressLint("Range")
    private static int checkCalendarAccount(Context context) {
        Cursor userCursor = context.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI, null, null, null, null);
        try {
            if (userCursor == null) { //查詢(xún)返回空值
                return -1;
            }
            int count = userCursor.getCount();
            if (count > 0) { //存在現(xiàn)有賬戶(hù),取第一個(gè)賬戶(hù)的id返回
                for (int i = 0; i <= count - 1; i++) {
                    if (i == 0) {
                        userCursor.moveToFirst();
                    } else {
                        userCursor.moveToNext();
                    }
                    String type = userCursor.getString(userCursor.getColumnIndex(CalendarContract.Calendars.ACCOUNT_TYPE));
                    if (type.equals(CALENDARS_ACCOUNT_TYPE)) {
                        return userCursor.getInt(userCursor.getColumnIndex(CalendarContract.Calendars._ID));
                    }
                }
            }
            return -1;
        } finally {
            if (userCursor != null) {
                userCursor.close();
            }
        }
    }

    /**
     * 添加日歷賬戶(hù),賬戶(hù)創(chuàng)建成功則返回賬戶(hù)id,否則返回-1
     */
    private static long addCalendarAccount(Context context) {
        TimeZone timeZone = TimeZone.getDefault();
        ContentValues value = new ContentValues();

        value.put(CalendarContract.Calendars.NAME, CALENDARS_NAME);
        value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME);
        value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE);
        value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME);
//        可見(jiàn)度
        value.put(CalendarContract.Calendars.VISIBLE, 1);
//        日歷顏色
        value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE);
//        權(quán)限
        value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
        value.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
//        時(shí)區(qū)
        value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID());
        value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME);
        value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);

        Uri calendarUri = CalendarContract.Calendars.CONTENT_URI;
        calendarUri = calendarUri.buildUpon()
                .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
                .build();

        Uri result = context.getContentResolver().insert(calendarUri, value);
        long id = result == null ? -1 : ContentUris.parseId(result);
        return id;
    }

    /**
     * 這個(gè)是關(guān)鍵方法,調(diào)用插入日程提醒
     *
     * @param context
     * @param eventId         事件id
     * @param title           提醒事件標(biāo)題
     * @param description     事件描述
     * @param reminderTime    任務(wù)開(kāi)始時(shí)間,這里參數(shù)名不太合適,后面會(huì)加提醒時(shí)間,
     * @param endTime         任務(wù)結(jié)束時(shí)間
     * @param previousMinutes 提前多少分鐘提醒,后續(xù)使用
     * @param isAlarm         是否需要鬧鐘提醒
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    @SuppressLint("Range")
    public static Long addCalendarEvent(Context context, long eventId, String title, String description, long reminderTime, long endTime, int previousMinutes, boolean isAlarm) {

        if (context == null) {
            return -1L;
        }
        int calId = checkAndAddCalendarAccount(context); //獲取日歷賬戶(hù)的id
        if (calId < 0) { //獲取賬戶(hù)id失敗直接返回,添加日歷事件失敗
            return -1L;
        }

        //添加日歷事件
        Calendar mCalendar = Calendar.getInstance();
        mCalendar.setTimeInMillis(reminderTime);//設(shè)置開(kāi)始時(shí)間
        long start = mCalendar.getTime().getTime();
        mCalendar.setTimeInMillis(endTime);//設(shè)置終止時(shí)間
        long end = mCalendar.getTime().getTime();
        ContentValues event = new ContentValues();
        event.put("title", title);
        event.put("description", description);
        event.put("calendar_id", calId); //插入賬戶(hù)的id
        event.put("eventStatus", 1);
        event.put(CalendarContract.Events._ID, eventId);
        event.put(CalendarContract.Events.HAS_EXTENDED_PROPERTIES, true);
        event.put(CalendarContract.Events.DTSTART, start);
        event.put(CalendarContract.Events.DTEND, end);
        if (isAlarm) {
            event.put(CalendarContract.Events.HAS_ALARM, 1);//設(shè)置有鬧鐘提醒,但是經(jīng)測(cè)試,此方案無(wú)效
        }
        event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getDisplayName());//這個(gè)是時(shí)區(qū),必須有
        Uri newEvent = context.getContentResolver().insert(CalendarContract.Events.CONTENT_URI, event); //添加事件
        if (newEvent == null) { //添加日歷事件失敗直接返回
            return -1L;
        }
        //擴(kuò)展屬性 用于高版本安卓系統(tǒng)設(shè)置鬧鐘提醒
        if (isAlarm) {
            Uri extendedPropUri = CalendarContract.ExtendedProperties.CONTENT_URI;
            extendedPropUri = extendedPropUri.buildUpon()
                    .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                    .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
                    .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE).build();
            ContentValues extendedProperties = new ContentValues();
            extendedProperties.put(CalendarContract.ExtendedProperties.EVENT_ID, ContentUris.parseId(newEvent));
            extendedProperties.put(CalendarContract.ExtendedProperties.VALUE, "{\"need_alarm\":true}");
            extendedProperties.put(CalendarContract.ExtendedProperties.NAME, "agenda_info");
            Uri uriExtended = context.getContentResolver().insert(extendedPropUri, extendedProperties);
            if (uriExtended == null) { //添加事件提醒失敗直接返回
                return -1L;
            }
        }
        //事件提醒的設(shè)定
        ContentValues values = new ContentValues();
        values.put(CalendarContract.Reminders.EVENT_ID, ContentUris.parseId(newEvent));
        values.put(CalendarContract.Reminders.MINUTES, 0);// 提前previousDate天有提醒
        values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
        Uri uri = context.getContentResolver().insert(CalendarContract.Reminders.CONTENT_URI, values);
        if (uri == null) { //添加事件提醒失敗直接返回
            return -1L;
        }
        Toast.makeText(context, "設(shè)置日程成功!!!", Toast.LENGTH_LONG).show();
        return eventId;
    }

    /**
     * 刪除日歷事件
     */
    public static void deleteCalendarEvent(Context context, Long delEventID) {
        if (context == null) {
            return;
        }
        Uri deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, delEventID);
        int rows = context.getContentResolver().delete(deleteUri, null, null);
        if (rows == -1) { //事件刪除失敗
            return;
        }
    }

    /**
     * 查詢(xún)?nèi)諝v日程相關(guān)的數(shù)據(jù)庫(kù)表(查詢(xún)其他表也適用),方法將查詢(xún)表的所有列的所有行都展示出來(lái)了,就是這么人性化
     *
     * @param uri 用來(lái)區(qū)分查詢(xún)的表的類(lèi)型,查詢(xún)不同的表,使用不同的URI即可,其他的都一樣
     */
    @SuppressLint("Range")
    public void queryCalendarData(Uri uri, Activity context) {
        Cursor cursor = context.getContentResolver().query(uri, null,
                null, null, null);
        while (cursor.moveToNext()) {
            int columnCount = cursor.getColumnCount();
            Log.e("TAG", "columnCount :" + columnCount);//多少個(gè)屬性
            for (int i = 0; i < columnCount; i++) {
                //獲取到屬性的名稱(chēng)
                String columnName = cursor.getColumnName(i);
                //獲取到屬性對(duì)應(yīng)的值
                String message = cursor.getString(cursor.getColumnIndex(columnName));
                //打印屬性和對(duì)應(yīng)的值
                Log.e("TAG", columnName + " : " + message);
            }
        }
    }
}


Demo

頁(yè)面布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    
    <Button
        android:id="@+id/deleteEventButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="delete a Event" />

    <Button
        android:id="@+id/writeEventButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Input a Event" />
</LinearLayout>

Activity


public class CalenderDemoActivity extends AppCompatActivity implements View.OnClickListener {


    private Button mDeleteEventButton;
    private Button mWriteEventButton;
    final int callbackId = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_calender_demo);
        checkPermission(callbackId, Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR);
        setupViews();
    }

    private void checkPermission(int callbackId, String... permissionsId) {
        boolean permissions = true;
        for (String p : permissionsId) {
            permissions = permissions && ContextCompat.checkSelfPermission(this, p) == PERMISSION_GRANTED;
        }

        if (!permissions)
            ActivityCompat.requestPermissions(this, permissionsId, callbackId);
    }

    private void setupViews() {
        mDeleteEventButton = (Button) findViewById(R.id.deleteEventButton);
        mWriteEventButton = (Button) findViewById(R.id.writeEventButton);
        mDeleteEventButton.setOnClickListener(this);
        mWriteEventButton.setOnClickListener(this);
    }

    /**
     * 檢查是否存在現(xiàn)有賬戶(hù),存在則返回賬戶(hù)id,否則返回-1
     */

    /**
     * 添加日歷賬戶(hù),賬戶(hù)創(chuàng)建成功則返回賬戶(hù)id,否則返回-1
     */


    @SuppressLint("Range")
    @Override
    public void onClick(View v) {
        Long eventId = Long.parseLong(String.valueOf((int)Math.random()*999+1));
        if (v == mWriteEventButton) {
            Calendar mCalendar = Calendar.getInstance();
            mCalendar.setTimeInMillis(System.currentTimeMillis() + 1 * 60 * 1000);
            long start = mCalendar.getTime().getTime();
            mCalendar.setTimeInMillis(start + 1 * 60 * 1000);
            long end = mCalendar.getTime().getTime();
            CalendarReminderUtils.addCalendarEvent(this, eventId,"工作提醒", "該休息啦", start, end, 0,true);
            Log.d("============eventid", "onClick: " + eventId);
        } else if (v == mDeleteEventButton) {
//            CalendarReminderUtils.queryCalendarData(CalendarContract.Calendars.CONTENT_URI, this);
            CalendarReminderUtils.deleteCalendarEvent(this, eventId);
        }
    }
}

效果

android 添加日歷提醒,Android,android,java

倉(cāng)庫(kù)地址

Gitee地址 AndroidDemo文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-775827.html

到了這里,關(guān)于Android 操作系統(tǒng)日歷完成提醒功能 附帶開(kāi)關(guān)鬧鐘 適配高版本安卓的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • OpenStack云計(jì)算(七)——OpenStack鏡像管理與制作,命令行界面完成鏡像的基本操作,鏡像的命令行操作方法。基于預(yù)制鏡像定制Centos7操作系統(tǒng)云鏡像,基于標(biāo)準(zhǔn)鏡像定制鏡像的方法。

    OpenStack云計(jì)算(七)——OpenStack鏡像管理與制作,命令行界面完成鏡像的基本操作,鏡像的命令行操作方法。基于預(yù)制鏡像定制Centos7操作系統(tǒng)云鏡像,基于標(biāo)準(zhǔn)鏡像定制鏡像的方法。

    通過(guò)命令行界面完成鏡像的基本操作 掌握鏡像的命令行操作方法。 (1)復(fù)習(xí)openstack命令管理鏡像的基本方法。、 (2)確認(rèn)OpenStack主機(jī)能夠訪(fǎng)問(wèn)因特網(wǎng)。 (1)在OpenStack主機(jī)上進(jìn)入命令行界面。 (2)加載admin用戶(hù)的環(huán)境變量。 source keystonerc_admin ? (3)顯示鏡像列表,并查看

    2024年04月26日
    瀏覽(24)
  • Windows作為操作系統(tǒng)的典型特征和主要功能

    Windows作為操作系統(tǒng)的典型特征和主要功能

    我是荔園微風(fēng),作為一名在IT界整整25年的老兵,今天我們來(lái)重新審視一下Windows這個(gè)我們熟悉的不能再熟悉的系統(tǒng)。 我們每天都在用Windows操作系統(tǒng),但是其實(shí)我們每天直接在打交道的并不是Windows操作系統(tǒng)的內(nèi)核,而是Windows操作系統(tǒng)的人機(jī)交互界面,這個(gè)界面其實(shí)只是Window

    2024年02月12日
    瀏覽(23)
  • 【Linux】開(kāi)啟 Linux 操作系統(tǒng)的 IP 轉(zhuǎn)發(fā)功能

    要開(kāi)啟 Linux 操作系統(tǒng)的 IP 轉(zhuǎn)發(fā)功能,你可以按照以下步驟進(jìn)行操作: 臨時(shí)開(kāi)啟: 如果你只是希望臨時(shí)開(kāi)啟 IP 轉(zhuǎn)發(fā)功能,可以使用以下命令: 永久開(kāi)啟: 如果你希望永久開(kāi)啟 IP 轉(zhuǎn)發(fā)功能,需要編輯配置文件,使其在系統(tǒng)重啟時(shí)仍然生效。 編輯 /etc/sysctl.conf 文件: 在文件末

    2024年02月04日
    瀏覽(38)
  • Android 車(chē)載應(yīng)用開(kāi)發(fā)之車(chē)載操作系統(tǒng)

    到 2030 年,全球電動(dòng)汽車(chē)的銷(xiāo)量將超過(guò) 7000 萬(wàn)輛,保有量將達(dá)到 3.8 億輛,全球年度新車(chē)滲透率有望觸及 60% 。這一數(shù)據(jù)來(lái)自國(guó)際能源署(IEA)發(fā)布的《全球電動(dòng)汽車(chē)展望2023》。 市場(chǎng)趨勢(shì)和政策努力的雙加持下,新能源汽車(chē)來(lái)勢(shì)兇猛,燃油車(chē)保有量逐年遞減。此番景象讓死去

    2024年02月22日
    瀏覽(24)
  • Android 使用模擬器模擬Linux操作系統(tǒng)

    Android 使用模擬器模擬Linux操作系統(tǒng)

    在Android手機(jī)上使用模擬器模擬ubuntu等操作系統(tǒng),便于測(cè)試 Termux:是一款 Android 終端模擬器和 Linux 環(huán)境應(yīng)用程序,無(wú)需 root 或設(shè)置即可直接運(yùn)行。雖然酷安和谷歌菜市場(chǎng)都能下載,但這些渠道都很久沒(méi)更新了,建議到 F - Droid 下載。 下載鏈接: https://f-droid.org/packages/com.termu

    2024年02月07日
    瀏覽(26)
  • 安卓和Android是兩種不同的操作系統(tǒng)?

    安卓和Android是兩種不同的操作系統(tǒng)?

    實(shí)際上,安卓和Android并不是同一種操作系統(tǒng)! Android是由Google開(kāi)發(fā)并維護(hù)更新的一款操作系統(tǒng),目前僅能運(yùn)行在Pixel手機(jī)上。 Google Pixel 與 iPhone手機(jī):哪個(gè)更好? Google Pixel 與 Apple iPhone哪個(gè)手機(jī)才是性?xún)r(jià)比最高的手機(jī)? https://fostmar.online/archives/19/ 安卓泛指中國(guó)廠(chǎng)商在Android開(kāi)源

    2024年01月22日
    瀏覽(26)
  • Windows 10操作系統(tǒng)中開(kāi)啟Ping功能(ICMP)的方法

    Windows 10操作系統(tǒng)中開(kāi)啟Ping功能(ICMP)的方法

    本文主要介紹在 Windows 10 操作系統(tǒng)中打開(kāi)啟 Ping 功能,即 ICMP 回顯請(qǐng)求的方法。 1. 在“設(shè)置”中找到并打開(kāi)“Windows安全中心”; 2. 在“Windows安全中心”頁(yè)面中,打開(kāi)“防火墻和網(wǎng)絡(luò)保護(hù)-允許應(yīng)用通過(guò)防火墻”對(duì)應(yīng)頁(yè)面,在該頁(yè)面的“允許的應(yīng)用和功能(A)”窗口中找到“文

    2024年02月11日
    瀏覽(24)
  • Silverlight工作流控件功能缺失,Windows Server操作系統(tǒng) IIS添加WCF功能

    Silverlight工作流控件功能缺失,Windows Server操作系統(tǒng) IIS添加WCF功能

    注: Silverlight工作流控件,如果在網(wǎng)頁(yè)中打不開(kāi),則要判斷是否缺少 Silverlight工作流控件 的插件程序,如果不是則可以進(jìn)行一下步驟檢查,如果是以下原因則是:由于IIS版本問(wèn)題,安裝后可能出現(xiàn)不支持wcf服務(wù)的請(qǐng)求處理,需要手動(dòng)添加處理程序;數(shù)據(jù)庫(kù)客戶(hù)端如果是64位,

    2024年02月16日
    瀏覽(21)
  • 『可控』AI作畫(huà):我的畫(huà)布聽(tīng)我的;快速完成科研論文『流調(diào)』;教會(huì)小白搭類(lèi)Unix操作系統(tǒng);聯(lián)邦學(xué)習(xí)資源合輯;前沿論文 | ShowMeAI資訊日?qǐng)?bào)

    『可控』AI作畫(huà):我的畫(huà)布聽(tīng)我的;快速完成科研論文『流調(diào)』;教會(huì)小白搭類(lèi)Unix操作系統(tǒng);聯(lián)邦學(xué)習(xí)資源合輯;前沿論文 | ShowMeAI資訊日?qǐng)?bào)

    ShowMeAI 日?qǐng)?bào) 系列全新升級(jí)!覆蓋AI人工智能 工具框架 | 項(xiàng)目代碼 | 博文分享 | 數(shù)據(jù)資源 | 研究論文 等方向。點(diǎn)擊查看 歷史文章列表 ,在公眾號(hào)內(nèi)訂閱話(huà)題 #ShowMeAI資訊日?qǐng)?bào) ,可接收每日最新推送。點(diǎn)擊 專(zhuān)題合輯電子月刊 快速瀏覽各專(zhuān)題全集。點(diǎn)擊 這里 回復(fù) 日?qǐng)?bào) 免

    2024年02月09日
    瀏覽(19)
  • Win10/Win11日歷提醒與手機(jī)日歷同步互聯(lián)+自帶郵件收發(fā)配置

    Win10/Win11日歷提醒與手機(jī)日歷同步互聯(lián)+自帶郵件收發(fā)配置

    說(shuō)明 日歷同步 所需工具:此處以 QQ 郵箱為例,在 Windows 日歷與小米手機(jī)日歷之間相互同步提醒事件; 效果:在一端編輯提醒事件后,其他所綁定的平臺(tái)都會(huì)自動(dòng)同步,其他手機(jī)理論通; 延遲:自動(dòng)同步有時(shí)間間隔,也就幾分鐘而已,若想獲取最新事件可點(diǎn)擊手動(dòng)同步; 同

    2024年02月09日
    瀏覽(43)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包