diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListAdapter.kt b/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListAdapter.kt index db46585b5dcd..8377feb9211c 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListAdapter.kt @@ -126,6 +126,12 @@ class BackupListAdapter( notifyItemInserted(calendarFiles.lastIndex) } + @SuppressLint("NotifyDataSetChanged") + fun reloadCalendars() { + cachedAndroidCalendars = AndroidCalendar.loadAll(context.contentResolver) + notifyDataSetChanged() + } + @SuppressLint("NotifyDataSetChanged") fun replaceVcards(vCards: List) { contacts.clear() diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListFragment.java index 20148300aa88..d5d86af88d7c 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupListFragment.java @@ -58,6 +58,8 @@ import javax.inject.Inject; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.recyclerview.widget.LinearLayoutManager; @@ -218,6 +220,10 @@ public View onCreateView(@NonNull final LayoutInflater inflater, ViewGroup conta } } + if (listAdapter.hasCalendarEntry()) { + checkAndAskForCalendarReadPermission(); + } + binding.restoreSelected.setOnClickListener(v -> { if (checkAndAskForCalendarWritePermission()) { importCalendar(); @@ -408,58 +414,72 @@ private void closeFragment() { } } + // region permission check result listener + private final ActivityResultLauncher contactsWritePermissionLauncher = + registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> { + if (isGranted) { + importContacts(selectedAccount); + } else { + showPermissionErrorMessage(); + } + }); + + private final ActivityResultLauncher calendarReadPermissionLauncher = + registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> { + if (isGranted) { + listAdapter.reloadCalendars(); + } + }); + + private final ActivityResultLauncher calendarWritePermissionLauncher = + registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> { + if (isGranted) { + importCalendar(); + } else { + showPermissionErrorMessage(); + } + }); + // endregion + + // region permission checks private boolean checkAndAskForContactsWritePermission() { - // check permissions - if (!PermissionUtil.checkSelfPermission(getContext(), Manifest.permission.WRITE_CONTACTS)) { - requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS}, - PermissionUtil.PERMISSIONS_WRITE_CONTACTS); + final var context = getContext(); + if (context == null) { return false; - } else { - return true; } - } - private boolean checkAndAskForCalendarWritePermission() { - // check permissions - if (!PermissionUtil.checkSelfPermission(getContext(), Manifest.permission.WRITE_CALENDAR)) { - requestPermissions(new String[]{Manifest.permission.WRITE_CALENDAR}, - PermissionUtil.PERMISSIONS_WRITE_CALENDAR); + if (!PermissionUtil.checkSelfPermission(context, Manifest.permission.WRITE_CONTACTS)) { + contactsWritePermissionLauncher.launch(Manifest.permission.WRITE_CONTACTS); return false; - } else { - return true; } + + return true; } - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - - if (requestCode == PermissionUtil.PERMISSIONS_WRITE_CONTACTS) { - for (int index = 0; index < permissions.length; index++) { - if (Manifest.permission.WRITE_CONTACTS.equalsIgnoreCase(permissions[index])) { - if (grantResults[index] >= 0) { - importContacts(selectedAccount); - } else { - showPermissionErrorMessage(); - } - break; - } - } + private void checkAndAskForCalendarReadPermission() { + final var context = getContext(); + if (context == null) { + return; } - if (requestCode == PermissionUtil.PERMISSIONS_WRITE_CALENDAR) { - for (int index = 0; index < permissions.length; index++) { - if (Manifest.permission.WRITE_CALENDAR.equalsIgnoreCase(permissions[index])) { - if (grantResults[index] >= 0) { - importContacts(selectedAccount); - } else { - showPermissionErrorMessage(); - } - break; - } - } + if (!PermissionUtil.checkSelfPermission(context, Manifest.permission.READ_CALENDAR)) { + calendarReadPermissionLauncher.launch(Manifest.permission.READ_CALENDAR); + } + } + + private boolean checkAndAskForCalendarWritePermission() { + final var context = getContext(); + if (context == null) { + return false; + } + + if (!PermissionUtil.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR)) { + calendarWritePermissionLauncher.launch(Manifest.permission.WRITE_CALENDAR); + return false; } + return true; } + // endregion private void showPermissionErrorMessage() { DisplayUtils.showSnackMessage(this, R.string.contactlist_no_permission); diff --git a/app/src/main/java/third_parties/sufficientlysecure/AndroidCalendar.java b/app/src/main/java/third_parties/sufficientlysecure/AndroidCalendar.java index 098421035cb3..040ef87f3534 100644 --- a/app/src/main/java/third_parties/sufficientlysecure/AndroidCalendar.java +++ b/app/src/main/java/third_parties/sufficientlysecure/AndroidCalendar.java @@ -112,9 +112,14 @@ private static String getString(Cursor cur, String dbName) { } private static boolean missing(ContentResolver resolver, Uri uri) { - // Determine if a provider is missing + // Determine if a provider is missing or inaccessible. + // acquireContentProviderClient throws SecurityException when the calendar + // permission has not been granted, so treat that as missing too. try (ContentProviderClient provider = resolver.acquireContentProviderClient(uri)) { return provider == null; + } catch (SecurityException e) { + Log_OC.w(TAG, "Calendar provider is not accessible: " + e.getMessage()); + return true; } }