package com.jens.automation2; import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.provider.CalendarContract; import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.jens.automation2.receivers.CalendarReceiver; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.List; public class ActivityManageTriggerCalendar extends Activity { CheckBox chkCalendarEventActive, chkCalendarAvailabilityBusy, chkCalendarAvailabilityFree, chkCalendarAvailabilityTentative, chkCalendarAvailabilityOutOfOffice, chkCalendarAvailabilityWorkingElsewhere, chkCalendarAllDayEvent, calendarEvaluateAllDayEvent; Spinner spinnerCalendarTitleDirection, spinnerCalendarLocationDirection, spinnerCalendarDescriptionDirection; EditText etCalendarTitle, etCalendarLocation, etCalendarDescription; LinearLayout llCalendarSelection; Button bSaveTriggerCalendar; List checkboxesCalendars = new ArrayList<>(); final static String separator = ","; TextView tvMissingCalendarHint; private static String[] directions; ArrayAdapter directionSpinnerAdapter; public static int requestCodePermissionReadCalendar = 815; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Miscellaneous.setDisplayLanguage(this); setContentView(R.layout.activity_manage_trigger_calendar); chkCalendarEventActive = (CheckBox) findViewById(R.id.chkCalendarEventActive); spinnerCalendarTitleDirection = (Spinner)findViewById(R.id.spinnerCalendarTitleDirection); spinnerCalendarLocationDirection = (Spinner)findViewById(R.id.spinnerCalendarLocationDirection); spinnerCalendarDescriptionDirection = (Spinner)findViewById(R.id.spinnerCalendarDescriptionDirection); chkCalendarAllDayEvent = (CheckBox)findViewById(R.id.chkCalendarAllDayEvent); chkCalendarAvailabilityBusy = (CheckBox)findViewById(R.id.chkCalendarAvailabilityBusy); chkCalendarAvailabilityFree = (CheckBox)findViewById(R.id.chkCalendarAvailabilityFree); chkCalendarAvailabilityTentative = (CheckBox)findViewById(R.id.chkCalendarAvailabilityTentative); chkCalendarAvailabilityOutOfOffice = (CheckBox)findViewById(R.id.chkCalendarAvailabilityOutOfOffice); chkCalendarAvailabilityWorkingElsewhere = (CheckBox)findViewById(R.id.chkCalendarAvailabilityWorkingElsewhere); calendarEvaluateAllDayEvent = (CheckBox)findViewById(R.id.calendarEvaluateAllDayEvent); tvMissingCalendarHint = (TextView) findViewById(R.id.tvMissingCalendarHint); llCalendarSelection = (LinearLayout)findViewById(R.id.llCalendarSelection); etCalendarTitle = (EditText)findViewById(R.id.etCalendarTitle); etCalendarLocation = (EditText)findViewById(R.id.etCalendarLocation); etCalendarDescription = (EditText)findViewById(R.id.etCalendarDescription); bSaveTriggerCalendar = (Button)findViewById(R.id.bSaveTriggerCalendar); directions = new String[] { getResources().getString(R.string.directionStringEquals), getResources().getString(R.string.directionStringContains), getResources().getString(R.string.directionStringDoesNotContain), getResources().getString(R.string.directionStringStartsWith), getResources().getString(R.string.directionStringEndsWith), getResources().getString(R.string.directionStringNotEquals) }; directionSpinnerAdapter = new ArrayAdapter<>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageTriggerCalendar.directions); spinnerCalendarTitleDirection.setAdapter(directionSpinnerAdapter); spinnerCalendarLocationDirection.setAdapter(directionSpinnerAdapter); spinnerCalendarDescriptionDirection.setAdapter(directionSpinnerAdapter); directionSpinnerAdapter.notifyDataSetChanged(); calendarEvaluateAllDayEvent.setChecked(false); chkCalendarAllDayEvent.setEnabled(false); calendarEvaluateAllDayEvent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { chkCalendarAllDayEvent.setEnabled(checked); } }); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 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() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { if(checked) chkCalendarEventActive.setText(R.string.eventIsCurrentlyHappening); else chkCalendarEventActive.setText(R.string.eventIsCurrentlyNotHappening); } }); chkCalendarAllDayEvent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { if(checked) chkCalendarAllDayEvent.setText(getResources().getString(R.string.allDayEventTrue)); else chkCalendarAllDayEvent.setText(getResources().getString(R.string.allDayEventFalse)); } }); bSaveTriggerCalendar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String titleDir = Trigger.getMatchCode(spinnerCalendarTitleDirection.getSelectedItem().toString()); String title = etCalendarTitle.getText().toString(); String descriptionDir = Trigger.getMatchCode(spinnerCalendarDescriptionDirection.getSelectedItem().toString()); String description = etCalendarDescription.getText().toString(); String locationDir = Trigger.getMatchCode(spinnerCalendarLocationDirection.getSelectedItem().toString()); String location = etCalendarLocation.getText().toString(); List availabilityList = new ArrayList<>(); if(chkCalendarAvailabilityBusy.isChecked()) availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_BUSY)); if(chkCalendarAvailabilityFree.isChecked()) availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_FREE)); if(chkCalendarAvailabilityTentative.isChecked()) availabilityList.add(String.valueOf(CalendarContract.Events.AVAILABILITY_TENTATIVE)); if(chkCalendarAvailabilityOutOfOffice.isChecked()) availabilityList.add(String.valueOf(CalendarReceiver.AVAILABILITY_OUT_OF_OFFICE)); if(chkCalendarAvailabilityWorkingElsewhere.isChecked()) availabilityList.add(String.valueOf(CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE)); List selectedCalendarsList = new ArrayList<>(); for(CheckBox calCheckbox : checkboxesCalendars) { if(calCheckbox.isChecked()) selectedCalendarsList.add((CalendarReceiver.AndroidCalendar) calCheckbox.getTag()); } List selectedCalendarsIdArray = new ArrayList<>(); for(CalendarReceiver.AndroidCalendar cal : selectedCalendarsList) selectedCalendarsIdArray.add(String.valueOf(cal.calendarId)); String returnString = titleDir + Trigger.triggerParameter2Split + title + Trigger.triggerParameter2Split + descriptionDir + Trigger.triggerParameter2Split + description + Trigger.triggerParameter2Split + locationDir + Trigger.triggerParameter2Split + location + Trigger.triggerParameter2Split + String.valueOf(calendarEvaluateAllDayEvent.isChecked()) + Trigger.triggerParameter2Split + String.valueOf(chkCalendarAllDayEvent.isChecked()) + Trigger.triggerParameter2Split + Miscellaneous.explode(separator, availabilityList.toArray(new String[availabilityList.size()])) + Trigger.triggerParameter2Split + Miscellaneous.explode(separator, selectedCalendarsIdArray.toArray(new String[selectedCalendarsIdArray.size()])); Intent data = new Intent(); data.putExtra(ActivityManageRule.intentNameTriggerParameter1, chkCalendarEventActive.isChecked()); data.putExtra(ActivityManageRule.intentNameTriggerParameter2, returnString); ActivityManageTriggerCalendar.this.setResult(RESULT_OK, data); finish(); } }); Intent inputIntent = getIntent(); if(inputIntent.hasExtra(ActivityManageRule.intentNameTriggerParameter1)) 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) { try { if (data.hasExtra(ActivityManageRule.intentNameTriggerParameter1)) chkCalendarEventActive.setChecked(data.getBooleanExtra(ActivityManageRule.intentNameTriggerParameter1, true)); if (data.hasExtra(ActivityManageRule.intentNameTriggerParameter2)) { String input[] = data.getStringExtra(ActivityManageRule.intentNameTriggerParameter2).split(Trigger.triggerParameter2Split, -1); /* 0 = titleDir 1 = title 2 = descriptionDir 3 = description 4 = locationDir 5 = location 6 = evaluate all day event 7 = all day event 8 = availability list 9 = calendars list */ for (int i = 0; i < directions.length; i++) { if (Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[0])) spinnerCalendarTitleDirection.setSelection(i); if (Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[2])) spinnerCalendarDescriptionDirection.setSelection(i); if (Trigger.getMatchCode(directions[i]).equalsIgnoreCase(input[4])) spinnerCalendarLocationDirection.setSelection(i); } etCalendarTitle.setText(input[1]); etCalendarDescription.setText(input[3]); etCalendarLocation.setText(input[5]); calendarEvaluateAllDayEvent.setChecked(Boolean.parseBoolean(input[6])); chkCalendarAllDayEvent.setChecked(Boolean.parseBoolean(input[7])); String[] availabilities = null; if (!StringUtils.isEmpty(input[8])) availabilities = input[8].split(separator); if (availabilities != null) { for (String avail : availabilities) { if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_BUSY) chkCalendarAvailabilityBusy.setChecked(true); else if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_FREE) chkCalendarAvailabilityFree.setChecked(true); else if (Integer.parseInt(avail) == CalendarContract.Events.AVAILABILITY_TENTATIVE) chkCalendarAvailabilityTentative.setChecked(true); else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_OUT_OF_OFFICE) chkCalendarAvailabilityOutOfOffice.setChecked(true); else if (Integer.parseInt(avail) == CalendarReceiver.AVAILABILITY_WORKING_ELSEWHERE) chkCalendarAvailabilityWorkingElsewhere.setChecked(true); } } String[] calendars = null; if (!StringUtils.isEmpty(input[9])) calendars = input[9].split(separator); if (calendars != null) { List usedCalendarIDs = new ArrayList<>(); List unusedCalendarIDs = new ArrayList<>(); for (CheckBox checkbox : checkboxesCalendars) { int id = ((CalendarReceiver.AndroidCalendar) checkbox.getTag()).calendarId; for (String calId : calendars) { if (calId.equals(String.valueOf(id))) { usedCalendarIDs.add(String.valueOf(id)); checkbox.setChecked(true); break; } } } for (String calId : calendars) { if (!Miscellaneous.arraySearch((ArrayList) usedCalendarIDs, calId, false, true)) unusedCalendarIDs.add(calId); } if (unusedCalendarIDs.size() > 0) { /* A calendar has been configured that has been deleted since. We cannot resolve it. It will be removed with the next save, but we should inform this user of these circumstances. */ tvMissingCalendarHint.setText(String.format(getResources().getString(R.string.calendarsMissingHint), Miscellaneous.explode(", ", (ArrayList) unusedCalendarIDs))); } } } } catch (Exception e) { Miscellaneous.logEvent("e", "ActivityManagerTriggerCalender", "Error loading values into GUI: " + Log.getStackTraceString(e), 1); Toast.makeText(ActivityManageTriggerCalendar.this, getResources().getString(R.string.errorLoadingValues), Toast.LENGTH_SHORT).show(); } } @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(); } } } }