From 97a3344e815fc624bfe0e14efe1a6e83122ebe65 Mon Sep 17 00:00:00 2001 From: jens Date: Fri, 29 Dec 2023 19:43:50 +0100 Subject: [PATCH] calendar trigger --- app/src/apkFlavor/AndroidManifest.xml | 7 +- .../ActivityManageTriggerCalendar.java | 96 +++++++++++++-- .../com/jens/automation2/Miscellaneous.java | 2 +- .../java/com/jens/automation2/Trigger.java | 53 ++++----- .../receivers/CalendarReceiver.java | 110 +++++++++++++++--- app/src/main/res/drawable-hdpi/ear.png | Bin 2312 -> 2335 bytes .../activity_manage_trigger_calendar.xml | 3 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values/strings.xml | 7 +- 9 files changed, 209 insertions(+), 71 deletions(-) diff --git a/app/src/apkFlavor/AndroidManifest.xml b/app/src/apkFlavor/AndroidManifest.xml index 38903380..cf6a6119 100644 --- a/app/src/apkFlavor/AndroidManifest.xml +++ b/app/src/apkFlavor/AndroidManifest.xml @@ -144,12 +144,7 @@ - - - - - - + directionSpinnerAdapter; + public static int requestCodePermissionReadCalendar = 815; @Override protected void onCreate(@Nullable Bundle savedInstanceState) @@ -79,14 +86,36 @@ public class ActivityManageTriggerCalendar extends Activity spinnerCalendarDescriptionDirection.setAdapter(directionSpinnerAdapter); directionSpinnerAdapter.notifyDataSetChanged(); - for(CalendarReceiver.AndroidCalendar cal : CalendarReceiver.readCalendars(ActivityManageTriggerCalendar.this)) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - CheckBox oneCalCheckbox = new CheckBox(ActivityManageTriggerCalendar.this); - oneCalCheckbox.setText(cal.toString()); - oneCalCheckbox.setTag(cal); - llCalendarSelection.addView(oneCalCheckbox); - checkboxesCalendars.add(oneCalCheckbox); + if(ActivityPermissions.havePermission(Manifest.permission.READ_CALENDAR, ActivityManageTriggerCalendar.this) || ActivityPermissions.havePermission(Manifest.permission.WRITE_CALENDAR, ActivityManageTriggerCalendar.this)) + populateCalenderCheckboxes(); + else + { + AlertDialog.Builder builder = new AlertDialog.Builder(ActivityManageTriggerCalendar.this); + builder.setTitle(getResources().getString(R.string.info)); + builder.setMessage(getResources().getString(R.string.permissionCalendarRequired)); + builder.setNegativeButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialogInterface, int i) + { + ActivityManageTriggerCalendar.this.finish(); + } + }); + builder.setPositiveButton(getResources().getString(R.string.ok), new DialogInterface.OnClickListener() + { + @Override + public void onClick(DialogInterface dialogInterface, int i) + { + requestPermissions(new String[]{ Manifest.permission.READ_CALENDAR } , requestCodePermissionReadCalendar); + } + }); + builder.show(); + } } + else + populateCalenderCheckboxes(); chkCalendarEventActive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @@ -172,6 +201,30 @@ public class ActivityManageTriggerCalendar extends Activity loadValuesIntoGui(inputIntent); } + private void populateCalenderCheckboxes() + { + List calList = CalendarReceiver.readCalendars(ActivityManageTriggerCalendar.this); + + if(calList != null) + { + if(calList.size() > 0) + { + for (CalendarReceiver.AndroidCalendar cal : calList) + { + CheckBox oneCalCheckbox = new CheckBox(ActivityManageTriggerCalendar.this); + oneCalCheckbox.setText(cal.toString()); + oneCalCheckbox.setTag(cal); + llCalendarSelection.addView(oneCalCheckbox); + checkboxesCalendars.add(oneCalCheckbox); + } + } + else + Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.noCalendarsOnYourDevice), ActivityManageTriggerCalendar.this).show(); + } + else + Miscellaneous.messageBox(getResources().getString(R.string.warning), getResources().getString(R.string.errorReadingCalendars), ActivityManageTriggerCalendar.this).show(); + } + void loadValuesIntoGui(Intent data) { //TODO:try-catch @@ -181,7 +234,7 @@ public class ActivityManageTriggerCalendar extends Activity if(data.hasExtra(ActivityManageRule.intentNameTriggerParameter2)) { - String input[] = data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split); + String input[] = data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split, -1); /* 0 = titleDir 1 = title @@ -216,10 +269,6 @@ public class ActivityManageTriggerCalendar extends Activity if(!StringUtils.isEmpty(input[7])) availabilities = input[7].split(separator); - String[] calendars = null; - if(!StringUtils.isEmpty(input[8])) - calendars = input[8].split(separator); - if(availabilities != null) { for (String avail : availabilities) @@ -237,6 +286,10 @@ public class ActivityManageTriggerCalendar extends Activity } } + String[] calendars = null; + if(!StringUtils.isEmpty(input[8])) + calendars = input[8].split(separator); + if(calendars != null) { List usedCalendarIDs = new ArrayList<>(); @@ -272,4 +325,25 @@ public class ActivityManageTriggerCalendar extends Activity } } } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) + { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + if(requestCode == requestCodePermissionReadCalendar) + { + if( + permissions[0].equals(Manifest.permission.READ_CALENDAR) + || + permissions[0].equals(Manifest.permission.WRITE_CALENDAR) + ) + { + if(grantResults[0] == PackageManager.PERMISSION_GRANTED) + populateCalenderCheckboxes(); + else + finish(); + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/jens/automation2/Miscellaneous.java b/app/src/main/java/com/jens/automation2/Miscellaneous.java index 4da9c912..cc035db1 100644 --- a/app/src/main/java/com/jens/automation2/Miscellaneous.java +++ b/app/src/main/java/com/jens/automation2/Miscellaneous.java @@ -806,7 +806,7 @@ public class Miscellaneous extends Service alertDialog.setTitle(title); alertDialog.setMessage(message); - alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() + alertDialog.setPositiveButton(context.getResources().getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { diff --git a/app/src/main/java/com/jens/automation2/Trigger.java b/app/src/main/java/com/jens/automation2/Trigger.java index 2f12e428..1db9c206 100644 --- a/app/src/main/java/com/jens/automation2/Trigger.java +++ b/app/src/main/java/com/jens/automation2/Trigger.java @@ -1933,49 +1933,42 @@ public class Trigger returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.variableCheckStringDeleted), triggerParameter2)); break; case calendarEvent: + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarEvent)); + + returnString.append(" ("); + if(triggerParameter) returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.eventIsCurrentlyHappening)); else returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.eventIsCurrentlyNotHappening)); + returnString.append( ", "); + String[] conditions = triggerParameter2.split(triggerParameter2Split, -1); - if( - !StringUtils.isEmpty(conditions[1]) - || - !StringUtils.isEmpty(conditions[3]) - || - !StringUtils.isEmpty(conditions[5]) - || - !StringUtils.isEmpty(conditions[7]) - || - !StringUtils.isEmpty(conditions[8])) - { - returnString.append(" ("); + if (!StringUtils.isEmpty(conditions[1])) + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.title) + " " + conditions[0] + " " + conditions[1] + ", "); + if (!StringUtils.isEmpty(conditions[3])) + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.location) + " " + conditions[2] + " " + conditions[3] + ", "); + if (!StringUtils.isEmpty(conditions[5])) + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarDescription) + " " + conditions[4] + " " + conditions[5] + ", "); - if (!StringUtils.isEmpty(conditions[1])) - returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.title) + " " + conditions[0] + " " + conditions[1] + ", "); - if (!StringUtils.isEmpty(conditions[3])) - returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.location) + " " + conditions[2] + " " + conditions[3] + ", "); - if (!StringUtils.isEmpty(conditions[5])) - returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendarDescription) + " " + conditions[4] + " " + conditions[5] + ", "); + if(Boolean.parseBoolean(conditions[6])) + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventTrue) + ", "); + else + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventFalse) + ", "); - if(Boolean.parseBoolean(conditions[6])) - returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventTrue) + ", "); - else - returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.allDayEventFalse) + ", "); + if (!StringUtils.isEmpty(conditions[7])) + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.availabilities) + " " + conditions[7] + ", "); - if (!StringUtils.isEmpty(conditions[7])) - returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.availabilities) + " " + conditions[7] + ", "); + if (!StringUtils.isEmpty(conditions[8])) + returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendars) + " " + conditions[8]); - if (!StringUtils.isEmpty(conditions[8])) - returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.calendars) + " " + conditions[8]); + if (returnString.toString().endsWith(", ")) + returnString.delete(returnString.length() - 2, returnString.length()); - if (returnString.toString().endsWith(", ")) - returnString.delete(returnString.length() - 2, returnString.length()); + returnString.append(")"); - returnString.append(")"); - } break; default: returnString.append("error"); diff --git a/app/src/main/java/com/jens/automation2/receivers/CalendarReceiver.java b/app/src/main/java/com/jens/automation2/receivers/CalendarReceiver.java index 1ad92d05..28244ca3 100644 --- a/app/src/main/java/com/jens/automation2/receivers/CalendarReceiver.java +++ b/app/src/main/java/com/jens/automation2/receivers/CalendarReceiver.java @@ -17,6 +17,8 @@ import com.jens.automation2.Trigger; import java.util.ArrayList; import java.util.Calendar; import java.util.List; +import java.util.Timer; +import java.util.TimerTask; public class CalendarReceiver extends BroadcastReceiver implements AutomationListenerInterface { @@ -32,6 +34,10 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis static List calendarsCache = null; static List calendarEventsCache = null; + static Timer timer = null; + static TimerTask timerTask = null; + static Calendar nextWakeup = null; + public static CalendarReceiver getInstance() { if(calendarReceiverInstance == null) @@ -45,15 +51,23 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis { if(intent.getAction().equalsIgnoreCase(Intent.ACTION_PROVIDER_CHANGED)) { + Miscellaneous.logEvent("i", "CalendarReceiver", "Received " + intent.getAction(), 5); + calendarsCache = null; calendarEventsCache = null; - ArrayList ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent); - for(int i = 0; i < ruleCandidates.size(); i++) - { - if(ruleCandidates.get(i).getsGreenLight(context)) - ruleCandidates.get(i).activate(AutomationService.getInstance(), false); - } + checkForRules(context); + armOrRearmTimer(); + } + } + + private static void checkForRules(Context context) + { + ArrayList ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.calendarEvent); + for(int i = 0; i < ruleCandidates.size(); i++) + { + if(ruleCandidates.get(i).getsGreenLight(context)) + ruleCandidates.get(i).activate(AutomationService.getInstance(), false); } } @@ -242,11 +256,79 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis if(cursor != null) cursor.close(); + } return calendarEventsCache; } + private static void armOrRearmTimer() + { + timerTask = new TimerTask() + { + @Override + public void run() + { + checkForRules(Miscellaneous.getAnyContext()); + + // Set next timer + + calculateNextWakeup(); + armOrRearmTimer(); + } + }; + + if(timer != null) + { + timer.cancel(); + timer.purge(); + } + timer = new Timer(); + + if(nextWakeup == null) + { + readCalendarEvents(Miscellaneous.getAnyContext(), false); + calculateNextWakeup(); + } + + // If it's now filled, go on + if(nextWakeup != null) + timer.schedule(timerTask, nextWakeup.getTimeInMillis()); + } + + private static void calculateNextWakeup() + { + Calendar now = Calendar.getInstance(); + if (nextWakeup != null && nextWakeup.getTimeInMillis() < now.getTimeInMillis()) + nextWakeup = null; + + List events = readCalendarEvents(Miscellaneous.getAnyContext(), false); + if (events.size() > 0) + { + for (CalendarEvent event : events) + { + if (event.isCurrentlyActive()) + { + if (nextWakeup == null || event.end.getTimeInMillis() < nextWakeup.getTimeInMillis()) + { + nextWakeup = event.end; + Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Choosing end of event " + event.title + " as next wakeup.", 5); + } + } + else + { + if (nextWakeup == null || event.start.getTimeInMillis() < nextWakeup.getTimeInMillis()) + { + nextWakeup = event.start; + Miscellaneous.logEvent("i", "calculateNextWakeupForCalendar()", "Choosing start of event " + event.title + " as next wakeup.", 5); + } + } + } + } + //else + // we expect to be called byOnReceive() when new items exist + } + public static void startCalendarReceiver(final AutomationService automationServiceRef) { if (!calendarReceiverActive) @@ -260,25 +342,15 @@ public class CalendarReceiver extends BroadcastReceiver implements AutomationLis { calendarIntentFilter = new IntentFilter(); calendarIntentFilter.addAction(Intent.ACTION_PROVIDER_CHANGED); + calendarIntentFilter.addDataScheme("content"); + calendarIntentFilter.addDataAuthority("com.android.calendar", null); } calendarIntent = automationServiceRef.registerReceiver(calendarReceiverInstance, calendarIntentFilter); calendarReceiverActive = true; - } - } - public static void stopScreenStateReceiver() - { - if (calendarReceiverActive) - { - if (calendarReceiverInstance != null) - { - automationServiceRef.unregisterReceiver(calendarReceiverInstance); - calendarReceiverInstance = null; - } - - calendarReceiverActive = false; + armOrRearmTimer(); } } } \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ear.png b/app/src/main/res/drawable-hdpi/ear.png index 916b101fc261c628e574f486e8e120380a2337e3..36cd243f4d00a66a27a5d929b709ca3a12b1ee6a 100644 GIT binary patch delta 2237 zcmV;u2txOW5}y)~B#|*Z5(#ifS#tmY4#NNd4#NS*Z>VIEY9W6xF!XYv000PYNklbacswNygOdUdz^Tg*fU;c z?dh5BE-&LO50`Up$04!`@!+oE;VAK)nkv=tUCzDb*F@xh!Sni_MCp0)Q$6C1wo7@a zRjM<6a!}0TWBY%18VRe>HEIhZl5f8#Uhg%jO>{^&-zUN1fYheCq||*y%Kg{nAisg7 z_U|_WR--E%`gtk${h@?}4+h0#=fxCO#rRvmrkDy)OiQ>lEMEVgQW@(Ide-rM8Ud@( z1r7=sDT9z;`i?})qY`aBkYIH}Dyh3t9{x+b;hW;ad!m2G(_-?=Vm24VA8L`(y=(Gx zH^3J5eOK(jpCH`vO)zYAE6NrS)jVCF7Jnb3=dsV<2g-B*${oIrpnrNtOeB5zZ& zO+U)oH}8LHNHMf(lburPZIb7Q``FHYM$)hvlY~EcM{|ln_>i31*ewYrJ0zIu6tglO zlSA)7=$P7$l4DF+3VkiI_VqjPoRpZIhvJX6A>>-IrTv_wVKpX&Xk}V*ZReDXXrW&d zE>Rt87q9P6@exwd(vXs7(jcI?rliE=c(UDkUNV2@J`uAqqXZSZewA=}3R~OHOA=ON z5}@0cx-Lt(`!@;UDH=LnMobl6QF@G@N5#AMyHrqp0+i`+wkHm&TJ9w=T)T4WZK(`g z*N_TO*7LV6$dj;wBkboU1*X(%y!I&@LWz3kam1iBP4q zWb=RXAg=@#p=lm}|2{rL*rAg7gUt|x9XP^%Zc?xslfYhn6;)_JqK6~MC1Z*RwwJ_^ zq|6+`>4tbcze{zrHC~&0C?+h5i4aodb(Hl*S^oS@eBLHz`+EqJ=&Q=k5VL zakw!FBZQPd0_(z!SxFW<{$HOJ3P5>{hU*yC@Vm4-@|B&|2}L@^G|@_3@d*mPp*+-eotb|yXzkN~arA-`TKl`Mx8k2;n zpc0W3VtWbyu1SQ-Qy94=>*qg}?4>WXdNDkhtZNhPTEz_Y%aN|Z`Ve|2d-+sMCcr!s zt!d_u|3P8t_vYrxAH5=6ofYPIDt zT>OkYI`x*UeEXhcuY4{3$Y1dqdQJJUl+c-1@52VgT~XQXCw)$(FG3os!|=lEg`}n!bO7xsA7f*+W>ahko!jiDrz3HK7%~- zjpiEFLC8%^%IvLJ+Px9Cown8J0#EC^Qbn_NuVd7EHe?Sj^Tg&g-ID&g=A$e ze<`_}XW}xCwS|sLTCLcBx$d&9Mpp>g3o&fiL6acn6y_RSnyQy=L5Om!vm5-IKJ%e^ znXW--71}SVm$AP(^b6S1eohjw8eKtu^GAyIRWLE*GfwyXp&L?zSLE9-Xy~vvVi*N; zy{dfaU6p}mY-c|sDOi7vuAmy`sKaKmlNABRXj?HBRy`yCu;l{+P zqX~FcHPwUd>}MnetI-9X9z>Ax<8c*IPXRHwbhtL9-k?1aXTKafK(jkZY8;5LTlL z?6V{jRK3tB9y(YJ^MhS%W8Z(<1*}F_&@h3=g!8>xb}8@m ziG@$L$R(` ze8l!(wQ+gnRalL#@C=QldJVg0cm>0UVdW3D#7`*n779CvJkE71_uKF_`(CbLHM+#^ z7D<`bFd=^te7`0se62KmZDbg&PN?1GE5LujYIKQbdx1XiQ>QSekN_rO9XF5|cnot; zFw=|W_B|Q_tI;){hMqp+vt08pA@miJy%L*7gbx zIr_U9hE=_o!4muT8U?GdkvQ~rAmBzNTo^*j&@UbQ`S_Z~LtgtEv*9kgmKUoW00000 LNkvXXu0mjfxPU(N delta 2241 zcmV;y2tN0p5{MFzBnkm@Qb$4nuFf3kks&{S8gxZibW?9;ba!ELWdKlNX>N2bPDNB8 zb~7$DE-^7j^FlWO00>}7L_t(&L*-gqZ&YOz9gGi}7+-xb@x{O8izb+0OiXw&8pVJ@ zj6lLAawiB>pg>D$ODVn3E2URj3eyYi^fuQsmvhe7cBZ!(wrlOvsZa{yLru=uq4bh~c66(~!oh$I^SR6v}^_r**-5)&O2lbXRb zEhdR8HZIO^t5{7}B-vRlYq^Ctg0o$p|33pJ8x2VUfY`lv#0_?cJM&oV(Jo2$+?7P@ zO|e>UND9^CKI;_|35uB>lvGQ(#P3~}m3jNM;P@JtTrw;%P{d`Gj6IYjK!{X-o|JIK z35nF4muTHZiPT<@>8nR&%?llCaa5POK^M(%-V8RzjeFsE*1sGJ@#b5A7IQ3=Xb zNFl%W5;(pD#vSREaODXF!yRl=!R3|itP-p7iljg(ceq7CGvfdtHm0C>;8-$SaZ*Aj zeh@R+rvSxj&x;f6_BSvr`*`g+N!0xz4k|^dV}-<|Q5ErL_`O4{dzU1CiSA>gO*{Sd z9<4Ir4Pdx-WZ##PY`&_LveDKfw@%5jliUEucNLS3KpP%ZDP>%2NGpSFdA%BpH7O3f zi$&i80O@C3bSZ7wTw_NRz!*HuvxDE@Je zUfTeMAcY1%r|V+XUy^ixM}@aG{6vfs6XSwXi3zmzAqoEU1>Ua|Gy7Q0V6^(IEN9{h zj_)dFk%kQ$QF;IX71t?TZrlThz+lsvuG^AsuMmg+W~j+qm!4f;gL|M`&0Rk(b7cp` zCBRbyl5T_N>AB}mV3uU1?M6Z&*152HnPg9c&b5;2y4ek8TuU zP)Gsfg>}wkzl?)UT&Lcq=Z-{BHTl&Q|5Z$(P>=;y20IO%EJ2#+h10E**=t860j*#K zxKCQ4K@GZTf}|pibtXRHRSm(xJ;E@A%uy!PFAmm4Zl9K1eA<7&kpHWz%Mep^B7(we zb{PMTiHpt?ZM!9Z6DNO^sWW@EdyyU#>r7Xbb}>W$QuH-g@4)X&o!jSuiHkbpj`sNz z7=n|VPyG!Hz;VaB#hnAa?5MWxIC9e1q1_VPyHi4^_CQaLN~{JzQEX}a9IT@lho8!9 z`4OcNvsM%plOAaCFEFIkJoSW@pGg`UWHjLB3;|Ld3Q8t_*oloFlc)Q3%E+%@%hZMa zl4`r@ts$in&m@jyo^Ho$aLmz~vy$p>_AfB38Wm#tlH`;J1VqK8EubiZZ+k!3v%GS;9Atd2JqRqt$1$TQPqXQ?~CbCcm~S4zmzx z!vsx$s43JMY?`i@vA{t)*4YjI9Y6N1R++8=wW1iHv&xvSmQvBus2H|w{pO2~wwSVu zNgD5eak`gkxh@%0MWpJKQis`yG_nU8)cLZyk{ERs0JJYdcnnBOP%tRWoYM7Y_49y;cCLJ&Z8&QIk+gvRr zL8V1zC0=yB@F*6NvJT2QwWHZ102E)gXX+4jCJn$CED-@x4{C6xlrN0~w->b_$M($4 zBR%uDghMHwNIL!A(TYy;U;sJ(REkl5gh?U#7NqL6?0jh*(H6m3TUpw0xei8|Y`e7g zdc?vbTWE>8U(R*ejR+##F8vHs^y?lg@qHxV#ujPlNE-~iSsle8c$#yT)^hJ)j$+GJ zO+8{f7=5`5Z3d_$fLTS5^afRk1`Lm&4{4RUU+x{Duv%#BVDdQEO}1CQa#me`lECl@ zsrea#g2^3dLLhj4O;C7RX?WU58etT{*Le!?ItmqEFNuoLlY<3Y5BTY5sVM}2BCO*E z0)vX72HAZL|DQ+Air?~zW9cD2+clqr&{If#UIw8N6rv~-z<;WilJGH`H@Uj#N(PUa zak$N@DLywtTIFJ)w*sXkfl;6=Fp5~R=3wA3!5eHrWN6ag-= diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index bfa12ed1..ca3363a7 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -765,7 +765,7 @@ Llamar al número de teléfono Llamar al número de teléfono Aquí puede ingresar un número de teléfono al que se llamará sin más indicaciones. Puede usar esto para realizar configuraciones como realizar ajustes en el enrutamiento de llamadas, etc. Por favor, busque los códigos necesarios para esto por su cuenta. - Terminar llamda de teléfono + Terminar llamada de teléfono Terminar llamda de teléfono La configuración y/o las reglas hacen referencia a funciones que no se pueden proporcionar en la versión de Google Play. Entre otras cosas que incluye todo lo relacionado con llamadas telefónicas y mensajes de texto. Si la variable %1$s no está establecida diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4d3ca63b..b67e2d78 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -918,9 +918,9 @@ tentative out of office working elsewhere - Select no item if any will do. + If you select no item, any one will be ok. Calendars - It may be that only the first 3 types are actually working becaue the other types are not part of Google Calendar. + It may be that only the first 3 types are actually working because the other types are not part of Google Calendar. any calender availabilities In this trigger calendars with IDs %1$s have been previously configured, but have been deleted since. With the next save those will be removed from this trigger. Until then this trigger/condition will never be met. @@ -928,4 +928,7 @@ All day event event is an all day event event is not an all day event + The permission to read your calendar will be required for a calendar trigger. It will already be required to populate the calendar fields in this window. + It appears like no calendars have been set up on your device. You can save this trigger, but it will never return true. + There was an error reading the calendars on your device. \ No newline at end of file