diff --git a/app/src/gplay/res/drawable/ic_contact_book.xml b/app/src/gplay/res/drawable/ic_contact_book.xml
new file mode 100644
index 000000000000..03331e98ba93
--- /dev/null
+++ b/app/src/gplay/res/drawable/ic_contact_book.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java
index cde91289f708..f299a1470eab 100644
--- a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java
+++ b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java
@@ -7,7 +7,7 @@
*
* Copyright (C) 2018 Andy Scherzinger
* Copyright (C) 2020 Chris Narkiewicz
- * Copyright (C) 2020 TSI-mc
+ * Copyright (C) 2023 TSI-mc
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -25,11 +25,17 @@
package com.owncloud.android.ui.fragment;
+import android.Manifest;
import android.accounts.AccountManager;
+import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.Bundle;
+import android.provider.ContactsContract;
import android.text.InputType;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -46,6 +52,7 @@
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.shares.OCShare;
import com.owncloud.android.lib.resources.shares.ShareType;
import com.owncloud.android.lib.resources.status.NextcloudVersion;
@@ -61,6 +68,7 @@
import com.owncloud.android.ui.helpers.FileOperationsHelper;
import com.owncloud.android.utils.ClipboardUtil;
import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.PermissionUtil;
import com.owncloud.android.utils.theme.ViewThemeUtils;
import java.util.ArrayList;
@@ -68,6 +76,8 @@
import javax.inject.Inject;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -167,6 +177,8 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
file.isEncrypted()));
binding.sharesList.setLayoutManager(new LinearLayoutManager(getContext()));
+ binding.pickContactEmailBtn.setOnClickListener(v -> checkContactPermission());
+
setupView();
return view;
@@ -208,6 +220,7 @@ private void setupView() {
} else {
binding.searchView.setQueryHint(getResources().getString(R.string.reshare_not_allowed));
binding.searchView.setInputType(InputType.TYPE_NULL);
+ binding.pickContactEmailBtn.setVisibility(View.GONE);
disableSearchView(binding.searchView);
}
}
@@ -460,6 +473,52 @@ public void refreshSharesFromDB() {
adapter.addShares(publicShares);
}
+ private void checkContactPermission() {
+ if (PermissionUtil.checkSelfPermission(requireActivity(), Manifest.permission.READ_CONTACTS)) {
+ pickContactEmail();
+ } else {
+ requestContactPermissionLauncher.launch(Manifest.permission.READ_CONTACTS);
+ }
+ }
+
+ private void pickContactEmail() {
+ Intent intent = new Intent(Intent.ACTION_PICK);
+ intent.setDataAndType(ContactsContract.Contacts.CONTENT_URI, ContactsContract.CommonDataKinds.Email.CONTENT_TYPE);
+ onContactSelectionResultLauncher.launch(intent);
+ }
+
+ private void handleContactResult(@NonNull Uri contactUri) {
+ // Define the projection to get all email addresses.
+ String[] projection = {ContactsContract.CommonDataKinds.Email.ADDRESS};
+
+ Cursor cursor = fileActivity.getContentResolver().query(contactUri, projection, null, null, null);
+
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ // The contact has only one email address, use it.
+ int columnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS);
+ if (columnIndex != -1) {
+ // Use the email address as needed.
+ // email variable contains the selected contact's email address.
+ String email = cursor.getString(columnIndex);
+ binding.searchView.post(() -> {
+ binding.searchView.setQuery(email, false);
+ binding.searchView.requestFocus();
+ });
+ } else {
+ DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+ Log_OC.e(FileDetailSharingFragment.class.getSimpleName(), "Failed to pick email address.");
+ }
+ } else {
+ DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+ Log_OC.e(FileDetailSharingFragment.class.getSimpleName(), "Failed to pick email address as no Email found.");
+ }
+ cursor.close();
+ } else {
+ DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+ Log_OC.e(FileDetailSharingFragment.class.getSimpleName(), "Failed to pick email address as Cursor is null.");
+ }
+ }
private boolean containsNoNewPublicShare(List shares) {
for (OCShare share : shares) {
@@ -546,6 +605,38 @@ public void onQuickPermissionChanged(OCShare share, int permission) {
fileOperationsHelper.setPermissionsToShare(share, permission);
}
+ //launcher for contact permission
+ private final ActivityResultLauncher requestContactPermissionLauncher =
+ registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
+ if (isGranted) {
+ pickContactEmail();
+ } else {
+ DisplayUtils.showSnackMessage(binding.getRoot(), R.string.contact_no_permission);
+ }
+ });
+
+ //launcher to handle contact selection
+ private final ActivityResultLauncher onContactSelectionResultLauncher =
+ registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
+ result -> {
+ if (result.getResultCode() == Activity.RESULT_OK) {
+ Intent intent = result.getData();
+ if (intent == null) {
+ DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+ return;
+ }
+
+ Uri contactUri = intent.getData();
+ if (contactUri == null) {
+ DisplayUtils.showSnackMessage(binding.getRoot(), R.string.email_pick_failed);
+ return;
+ }
+
+ handleContactResult(contactUri);
+
+ }
+ });
+
public interface OnEditShareListener {
void editExistingShare(OCShare share, int screenTypePermission, boolean isReshareShown,
boolean isExpiryDateShown);
diff --git a/app/src/main/res/layout/file_details_sharing_fragment.xml b/app/src/main/res/layout/file_details_sharing_fragment.xml
index bd9e093bf740..b129d3dff6de 100644
--- a/app/src/main/res/layout/file_details_sharing_fragment.xml
+++ b/app/src/main/res/layout/file_details_sharing_fragment.xml
@@ -1,7 +1,10 @@