Unity Android 之 获取系统Calendar 日历日程 (涉及指定日期时间判断是星期几的方法使用)的方法整理

 

目录

Unity Android 之 获取系统Calendar 日历日程 (涉及指定日期时间判断是星期几的方法使用)的方法整理

一、简单介绍

二、实现原理

三、注意实现

四、效果预览

五、实现步骤

Android 端:

Unity 端

六、关键代码

Android 端

Unity 端


 

一、简单介绍

Unity Android 开发上会用到的技术简单整理,方便自己日后查看,能帮助到大家就更好了。

本节介绍,Unity 开发中,把从 Android 获取手机设备的获取系统Calendar 日历日程 (涉及指定日期时间判断是星期几的方法使用)的方法整理封装给Unity调用,方法不唯一,欢迎指正。

 

二、实现原理

1、getContentResolver().query(Uri.parse(CALENDER_EVENT_URL), null, null, null, "dtstart"+" DESC");
获取日历日程事件 Cursor,然后循环获取每个日程事件
2、getContentResolver().query(Uri.parse(CALENDER_EVENT_URL), null, null, null, "dtstart"+" DESC");
"dtstart"+" DESC",实现日历日程事件按日程事件开始时间降序排序得到日程事件结果
3、Cursor.getString(eventCursor.getColumnIndex("title")) 得到日程事件标题
4、Cursor.getString(eventCursor.getColumnIndex("description")) 得到日程事件描述
5、Cursor.getString(eventCursor.getColumnIndex("eventLocation")) 得到日程事件位置
6、Cursor.getString(eventCursor.getColumnIndex("dtstart"))  得到日程事件开始时间
7、Cursor.getString(eventCursor.getColumnIndex("dtend")) 得到日程事件结束时间
8、Calendar.getInstance().setTime(format.parse("yyyy-MM-dd HH:mm:ss")) 判断指定日期时间是星期几
9、打包成 aar ,Unity 调用 aar 的封装好的接口

 

三、注意实现

1、添加Calendar 相关权限

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

 

2、getContentResolver().query() 最后一个参数进行数据排序,这里是 "dtstart"+" DESC" 日程事件开始时间降序排序, "dtstart"+" AXSC" 日程事件开始时间升序排序

 

3、这里进行了动态权限申请,所以需要 android-support-v4.jar ,作为 implementation files('libs/android-support-v4.jar')

(注意 0.54M 的缺少接口,建议 jar 1.23M 左右的 android-support-v4.jar)

 

四、效果预览

unity 获取系统时间 年月日 unity日历_日历日程事件

 

五、实现步骤

Android 端:

1、新建一个Android Library 模块,其他默认设置就好

unity 获取系统时间 年月日 unity日历_Android_02

 

2、这里动态申请权限需要用到 android-support-v4.jar ,引入

unity 获取系统时间 年月日 unity日历_unity 获取系统时间 年月日_03

 

3、在模块中新建两个脚本,CalendarUtil 封装各个功能,CalenderDataStruct 一个 Calendar 数据模型函数,

unity 获取系统时间 年月日 unity日历_Unity_04

 

3、脚本编辑 OK,Build - Make Module ‘xxxx’,打包 aar

unity 获取系统时间 年月日 unity日历_Calendar_05

 

4、打包成功,build 文件夹outputs/aar中就会 有对应的 aar 生成

unity 获取系统时间 年月日 unity日历_Unity_06

 

Unity 端

1、把 Android 打包的 aar 导入 Unity,这里用到 LitJson 也一并导入

unity 获取系统时间 年月日 unity日历_日历日程事件_07

 

2、在场景中布局UI,Button 获取 Calendar 日程事件,Text 显示日程

unity 获取系统时间 年月日 unity日历_Android_08

 

3、在 Unity工程中,新建脚本,编辑对应功能

unity 获取系统时间 年月日 unity日历_Android_09

 

4、把 TestCalendarWrapper 挂载到场景中,并对应赋值

unity 获取系统时间 年月日 unity日历_日历日程事件_10

 

5、运行场景,没有问题,即可打包到真机上测试

unity 获取系统时间 年月日 unity日历_日历日程事件_11

unity 获取系统时间 年月日 unity日历_unity 获取系统时间 年月日_12

 

6、真机上的测试效果如上

unity 获取系统时间 年月日 unity日历_Android_13

 

六、关键代码

Android 端

1、CalendarUtil

package com.example.calendarwrapper;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;


import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.telephony.TelephonyManager;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;


public class CalendarUtil {

    private static final String TAG ="Main_calendarUtil";

    private static String CALENDER_URL = "content://com.android.calendar/calendars";
    private static String CALENDER_EVENT_URL = "content://com.android.calendar/events";
    private static String CALENDER_REMINDER_URL = "content://com.android.calendar/reminders";
    private static TelephonyManager mTm;


    public static ArrayList<CalenderDataStruct> GetCalenderSchedule(Context context){

        String startTime = "";
        String endTime = "";
        String eventTitle = "";
        String description = "";
        String location = "";
        String week = "";

        ArrayList<CalenderDataStruct> arr=new ArrayList<CalenderDataStruct>();
        Cursor eventCursor = context.getContentResolver().query(Uri.parse(CALENDER_EVENT_URL), null,
                null, null,  "dtstart"+" DESC");
        while (eventCursor.moveToNext()){

            eventTitle = eventCursor.getString(eventCursor.getColumnIndex("title"));
            description = eventCursor.getString(eventCursor.getColumnIndex("description"));
            location = eventCursor.getString(eventCursor.getColumnIndex("eventLocation"));
            startTime = timeStamp2Date(Long.parseLong(eventCursor.getString(eventCursor.getColumnIndex("dtstart"))));
            endTime = timeStamp2Date(Long.parseLong(eventCursor.getString(eventCursor.getColumnIndex("dtend"))));
            week = ""+ (getWeek(startTime));
            CalenderDataStruct item=new CalenderDataStruct(eventTitle, startTime, endTime,description, location,week);

            arr.add(item);
        }
        return arr;
    }

    /**
     * 获得日历日程 Json 字符串
     * @return
     */
    public static String GetCalendarSchedule(){

        return getcalendar(getActivity()).toString();
    }

    private static JSONArray getcalendar(Context context){
        String startTime = "";
        String endTime = "";
        String eventTitle = "";
        String description = "";
        String location = "";
        String week = "";

        JSONArray arr=new JSONArray();
        Cursor eventCursor = context.getContentResolver().query(Uri.parse(CALENDER_EVENT_URL), null,
                null, null, null);
        while (eventCursor.moveToNext()){
            JSONObject json=new JSONObject();
            eventTitle = eventCursor.getString(eventCursor.getColumnIndex("title"));
            description = eventCursor.getString(eventCursor.getColumnIndex("description"));
            location = eventCursor.getString(eventCursor.getColumnIndex("eventLocation"));
            startTime = timeStamp2Date(Long.parseLong(eventCursor.getString(eventCursor.getColumnIndex("dtstart"))));
            endTime = timeStamp2Date(Long.parseLong(eventCursor.getString(eventCursor.getColumnIndex("dtend"))));
            week = ""+ (getWeek(startTime));
            try {
                json.put("eventTitle",eventTitle);
                json.put("description",description);
                json.put("location",location);
                json.put("startTime",startTime);
                json.put("endTime",endTime);
                json.put("week",week);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            arr.put(json);
        }
        return arr;
    }

    /**
     * 时间戳转换为字符串
     * @param time:时间戳
     * @return
     */
    private static String timeStamp2Date(long time) {
        String format = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(time));
    }

    /**
     * 判断当前日期是星期几
     *
     * @param  pTime     设置的需要判断的时间  //格式如2012-09-08
     *

     * @return dayForWeek 判断结果
     * @Exception 发生异常
     */

//  String pTime = "2012-03-12";
    private static int getWeek(String pTime) {


        int Week = 0;


        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        try {

            c.setTime(format.parse(pTime));

        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            Week = 0;
        }
        if (c.get(Calendar.DAY_OF_WEEK) == 2) {
            Week = 1;
        }
        if (c.get(Calendar.DAY_OF_WEEK) == 3) {
            Week = 2;
        }
        if (c.get(Calendar.DAY_OF_WEEK) == 4) {
            Week = 3;
        }
        if (c.get(Calendar.DAY_OF_WEEK) == 5) {
            Week = 4;
        }
        if (c.get(Calendar.DAY_OF_WEEK) == 6) {
            Week = 5;
        }
        if (c.get(Calendar.DAY_OF_WEEK) == 7) {
            Week = 6;
        }



        return Week;
    }



    // 添加需要的动态申请的权限(危险权限才会弹出跳出)
    static String[] permissions = new String[] { "android.permission.READ_CALENDAR"

    };

    /**
     * 检测权限,然后动态申请未授权的权限
     * (给 Unity 使用)
     */
    public  void checkCalendarPermissions( ){



        // 申请权限
        checkPermissions(getActivity(), permissions);
    }


    /**
     * 动态权限申请,可给Android 自己调用
     * @param activity
     * @param MANDATORY_PERMISSIONS
     */
    private  void checkPermissions(Activity activity, String[] MANDATORY_PERMISSIONS) {

        Log.i(TAG, "checkPermissions: 检测权限");
        // 判断授权列表
        List<String> unGrantedPermissions;
        unGrantedPermissions = new ArrayList();

        // 检测权限
        for (String permission : MANDATORY_PERMISSIONS) {
            Log.i(TAG, "checkPermissions: permission " +permission);
            if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
                unGrantedPermissions.add(permission);
            }
        }

        // 权限请求是否授权
        if (unGrantedPermissions.size() != 0) {
            String[] array = new String[unGrantedPermissions.size()];
            ActivityCompat.requestPermissions(activity, unGrantedPermissions.toArray(array), 0);
            Log.i(TAG, "checkPermissions: 已经获得了所有权限");
        }

        Log.i(TAG, "checkPermissions: Is Over");
    }


    // 设置一个 Activity 参数
    private static Activity _unityActivity;

    // 通过反射获取 Unity 的 Activity 的上下文
    static Activity getActivity(){

        if(null == _unityActivity){

            try{

                Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");

                Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);

                _unityActivity = activity;

            }catch (ClassNotFoundException e){

                e.printStackTrace();

            }catch (IllegalAccessException e){

                e.printStackTrace();

            }catch (NoSuchFieldException e){

                e.printStackTrace();

            }

        }

        return _unityActivity;

    }
}

 

2、CalenderDataStruct

package com.example.calendarwrapper;

/**
 * 日历日程数据结构
 */
public class CalenderDataStruct {
    String eventTitle = "";
    String startTime = "";
    String endTime = "";
    String description = "";
    String location = "";
    String week = "";

    public CalenderDataStruct(String eventTitle, String startTime, String endTime, String description, String location,String week) {
        this.eventTitle = eventTitle;
        this.startTime = startTime;
        this.endTime = endTime;
        this.description = description;
        this.location = location;
        this.week = week;
    }

    public String getEventTitle() {
        return eventTitle;
    }

    public void setEventTitle(String eventTitle) {
        this.eventTitle = eventTitle;
    }

    public String getStartTime() {
        return startTime;
    }

    public void setStartTime(String startTime) {
        this.startTime = startTime;
    }

    public String getEndTime() {
        return endTime;
    }

    public void setEndTime(String endTime) {
        this.endTime = endTime;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getWeek() {
        return week;
    }

    public void setWeek(String week) {
        this.week = week;
    }

    @Override
    public String toString() {
        return "CalenderDataStruct{" +
                "eventTitle='" + eventTitle + '\'' +
                ", startTime='" + startTime + '\'' +
                ", endTime='" + endTime + '\'' +
                ", description='" + description + '\'' +
                ", location='" + location + '\'' +
                ", week='" + week + '\'' +
                '}';
    }
}

 

3、AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.calendarwrapper" >
    <uses-permission android:name="android.permission.READ_CALENDAR"/>
    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
</manifest>

 

Unity 端

1、CalendarWrapper

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace AndroidWrapper
{
    /// <summary>
    /// 日历日程
    /// 使用说明
    /// 1、检查是否有日历读取权限
    /// 2、获取日历日程内容
    /// </summary>
    public class CalendarWrapper : MonoSingleton<CalendarWrapper>
    {
        /// <summary>
        /// 检查是否有日历日程读取权限
        /// </summary>
        public void checkCalendarPermissions() {

            MAndroidJavaObject.Call("checkCalendarPermissions");
            
        }

        /// <summary>
        /// 获取日历日程数据
        /// </summary>
        /// <returns></returns>
        public List<CalenderDataStruct> GetCalendarSchedule() {
            string strJson = MAndroidJavaObject.CallStatic<string>("GetCalendarSchedule");
            Debug.Log(GetType()+ "/GetCalendarSchedule()/ 日历日程 strJson " +strJson);
            if (strJson != null)
            {
                //return JsonUtility.FromJson<List<CalenderDataStruct>>(strJson);
                return LitJson.JsonMapper.ToObject<List<CalenderDataStruct>>(strJson);
            }

            return null;
        }

#region 私有变量

        AndroidJavaObject _mAndroidJavaObject;

        public AndroidJavaObject MAndroidJavaObject
        {
            get
            {
                if (_mAndroidJavaObject == null)
                {
                    _mAndroidJavaObject = new AndroidJavaObject("com.example.calendarwrapper.CalendarUtil");
                }

                return _mAndroidJavaObject;
            }
        }


#endregion
    }
}

 

2、CalenderDataStruct

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace AndroidWrapper
{
    /// <summary>
    /// 日程数据结构
    /// </summary>
    [System.Serializable]
    public class CalenderDataStruct
    {
        // 日程标题
        public string eventTitle = "";
        // 日程开始时间
        public string startTime = "";
        // 日程结束时间
        public string endTime = "";
        // 日程具体内容
        public string description = "";
        // 日程位置
        public string location = "";
        // 日程时间周几
        public string week = "";

        public override string ToString()
        {
            return eventTitle +", " + startTime + ", " + endTime + ", " + description + ", " + location + ", " + week + "." ;
        }
    }
}

 

3、TestCalendarWrapper

using AndroidWrapper;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestCalendarWrapper : MonoBehaviour
{
    public Text Calendar_Text;
    public Button GetCalendar_Button;

    // Start is called before the first frame update
    void Start()
    {
        Calendar_Text.text = "";

        
#if UNITY_EDITOR
        Debug.Log(GetType() + "/Start()/ UNITY_EDITOR 测试");
        GetCalendar_Button.onClick.AddListener(() => {
            List<CalenderDataStruct> _listCalendarData = LitJson.JsonMapper.ToObject<List<CalenderDataStruct>>(@"[{'eventTitle':'test','startTime':'2020-08-21 16:13:00','endTime':'2020-08-21 16:13:00','week':'5'},{'eventTitle':'testcalendar','description':'也是她','startTime':'2020-08-21 08:00:00','endTime':'2020-08-22 08:00:00','week':'5'},{'eventTitle':'刚果共和国喜欢吃盒饭','description':'好的加分检查结果就感觉','startTime':'2019-08-21 16:40:00','endTime':'2019-08-21 17:40:00','week':'3'},{'eventTitle':'兔兔兔兔兔','description':'大大方方官方','startTime':'2020-08-22 16:44:00','endTime':'2020-08-22 17:44:00','week':'6'},{'eventTitle':'哈哈','description':'突然方法','startTime':'2020-08-21 19:14:00','endTime':'2020-08-21 20:14:00','week':'5'},{'eventTitle':'刚刚','description':'太阳公公发','startTime':'2020-08-26 19:16:00','endTime':'2020-08-26 20:16:00','week':'3'}]");
            //_listCalendarData.Add(new CalenderDataStruct() { eventTitle = "eventTitle", startTime = "startTime", endTime = "endTime", description = "description", location = "location", week= "week" });
            foreach (CalenderDataStruct item in _listCalendarData)
            {
                Calendar_Text.text += item.ToString() + "    ";
            }
        });

#else
        CalendarWrapper.Instance.checkCalendarPermissions();
        GetCalendar_Button.onClick.AddListener(()=> {
            List<CalenderDataStruct> _listCalendarData = CalendarWrapper.Instance.GetCalendarSchedule();
            foreach (CalenderDataStruct item in _listCalendarData)
            {
                Calendar_Text.text += item.ToString() + "      ";
            }
        });
        
#endif
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

4、MonoSingleton

using UnityEngine;

public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance = null;

    private static readonly object locker = new object();

    private static bool bAppQuitting;

    public static T Instance
    {
        get
        {
            if (bAppQuitting)
            {
                instance = null;
                return instance;
            }

            lock (locker)
            {
                if (instance == null)
                {
                    instance = FindObjectOfType<T>();
                    if (FindObjectsOfType<T>().Length > 1)
                    {
                        Debug.LogError("不应该存在多个单例!");
                        return instance;
                    }

                    if (instance == null)
                    {
                        var singleton = new GameObject();
                        instance = singleton.AddComponent<T>();
                        singleton.name = "(singleton)" + typeof(T);
                        singleton.hideFlags = HideFlags.None;
                        DontDestroyOnLoad(singleton);
                    }
                    else
                        DontDestroyOnLoad(instance.gameObject);
                }
                instance.hideFlags = HideFlags.None;
                return instance;
            }
        }
    }

    protected virtual void Awake()
    {
        bAppQuitting = false;
    }

    protected virtual void OnDestroy()
    {
        bAppQuitting = true;
    }
}