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)
四、效果预览
五、实现步骤
Android 端:
1、新建一个Android Library 模块,其他默认设置就好
2、这里动态申请权限需要用到 android-support-v4.jar ,引入
3、在模块中新建两个脚本,CalendarUtil 封装各个功能,CalenderDataStruct 一个 Calendar 数据模型函数,
3、脚本编辑 OK,Build - Make Module ‘xxxx’,打包 aar
4、打包成功,build 文件夹outputs/aar中就会 有对应的 aar 生成
Unity 端
1、把 Android 打包的 aar 导入 Unity,这里用到 LitJson 也一并导入
2、在场景中布局UI,Button 获取 Calendar 日程事件,Text 显示日程
3、在 Unity工程中,新建脚本,编辑对应功能
4、把 TestCalendarWrapper 挂载到场景中,并对应赋值
5、运行场景,没有问题,即可打包到真机上测试
6、真机上的测试效果如上
六、关键代码
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;
}
}