SendFilesDialog.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package com.owncloud.android.ui.dialog;
  2. import android.content.ComponentName;
  3. import android.content.Intent;
  4. import android.content.pm.ResolveInfo;
  5. import android.graphics.drawable.Drawable;
  6. import android.net.Uri;
  7. import android.os.Bundle;
  8. import android.view.LayoutInflater;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
  12. import com.owncloud.android.R;
  13. import com.owncloud.android.datamodel.OCFile;
  14. import com.owncloud.android.ui.adapter.SendButtonAdapter;
  15. import com.owncloud.android.ui.components.SendButtonData;
  16. import java.util.ArrayList;
  17. import java.util.List;
  18. import java.util.Set;
  19. import androidx.annotation.NonNull;
  20. import androidx.annotation.Nullable;
  21. import androidx.recyclerview.widget.GridLayoutManager;
  22. import androidx.recyclerview.widget.RecyclerView;
  23. /*
  24. * Nextcloud Android client application
  25. *
  26. * @author Tobias Kaminsky
  27. * Copyright (C) 2020 Tobias Kaminsky
  28. * Copyright (C) 2020 Nextcloud GmbH.
  29. *
  30. * This program is free software: you can redistribute it and/or modify
  31. * it under the terms of the GNU Affero General Public License as published by
  32. * the Free Software Foundation, either version 3 of the License, or
  33. * at your option) any later version.
  34. *
  35. * This program is distributed in the hope that it will be useful,
  36. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  37. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  38. * GNU Affero General Public License for more details.
  39. *
  40. * You should have received a copy of the GNU Affero General Public License
  41. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  42. */
  43. public class SendFilesDialog extends BottomSheetDialogFragment {
  44. private static final String KEY_OCFILES = "KEY_OCFILES";
  45. private OCFile[] files;
  46. public static SendFilesDialog newInstance(Set<OCFile> files) {
  47. SendFilesDialog dialogFragment = new SendFilesDialog();
  48. Bundle args = new Bundle();
  49. args.putParcelableArray(KEY_OCFILES, files.toArray(new OCFile[0]));
  50. dialogFragment.setArguments(args);
  51. return dialogFragment;
  52. }
  53. @Override
  54. public void onCreate(@Nullable Bundle savedInstanceState) {
  55. super.onCreate(savedInstanceState);
  56. // keep the state of the fragment on configuration changes
  57. setRetainInstance(true);
  58. files = (OCFile[]) requireArguments().getParcelableArray(KEY_OCFILES);
  59. }
  60. @Nullable
  61. @Override
  62. public View onCreateView(@NonNull LayoutInflater inflater,
  63. @Nullable ViewGroup container,
  64. @Nullable Bundle savedInstanceState) {
  65. View view = inflater.inflate(R.layout.send_files_fragment, container, false);
  66. // populate send apps
  67. Intent sendIntent = createSendIntent();
  68. List<SendButtonData> sendButtonDataList = setupSendButtonData(sendIntent);
  69. SendButtonAdapter.ClickListener clickListener = setupSendButtonClickListener(sendIntent);
  70. RecyclerView sendButtonsView = view.findViewById(R.id.send_button_recycler_view);
  71. sendButtonsView.setHasFixedSize(true);
  72. sendButtonsView.setLayoutManager(new GridLayoutManager(getActivity(), 4));
  73. sendButtonsView.setAdapter(new SendButtonAdapter(sendButtonDataList, clickListener));
  74. return view;
  75. }
  76. @NonNull
  77. private SendButtonAdapter.ClickListener setupSendButtonClickListener(Intent sendIntent) {
  78. return sendButtonDataData -> {
  79. String packageName = sendButtonDataData.getPackageName();
  80. String activityName = sendButtonDataData.getActivityName();
  81. sendIntent.setComponent(new ComponentName(packageName, activityName));
  82. requireActivity().startActivity(Intent.createChooser(sendIntent, getString(R.string.send)));
  83. dismiss();
  84. };
  85. }
  86. @NonNull
  87. private List<SendButtonData> setupSendButtonData(Intent sendIntent) {
  88. List<SendButtonData> sendButtonDataList = new ArrayList<>();
  89. Drawable icon;
  90. SendButtonData sendButtonData;
  91. CharSequence label;
  92. for (ResolveInfo match : requireActivity().getPackageManager().queryIntentActivities(sendIntent, 0)) {
  93. icon = match.loadIcon(requireActivity().getPackageManager());
  94. label = match.loadLabel(requireActivity().getPackageManager());
  95. sendButtonData = new SendButtonData(icon, label,
  96. match.activityInfo.packageName,
  97. match.activityInfo.name);
  98. sendButtonDataList.add(sendButtonData);
  99. }
  100. return sendButtonDataList;
  101. }
  102. @NonNull
  103. private Intent createSendIntent() {
  104. Intent sendIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
  105. sendIntent.setType(getUniqueMimetype());
  106. sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, getExposedFileUris());
  107. sendIntent.putExtra(Intent.ACTION_SEND, true);
  108. return sendIntent;
  109. }
  110. @Nullable
  111. private String getUniqueMimetype() {
  112. String mimetype = files[0].getMimeType();
  113. for (OCFile file : files) {
  114. if (!mimetype.equals(file.getMimeType())) {
  115. return null;
  116. }
  117. }
  118. return mimetype;
  119. }
  120. private ArrayList<Uri> getExposedFileUris() {
  121. ArrayList<Uri> uris = new ArrayList<>();
  122. for (OCFile file : files) {
  123. uris.add(file.getExposedFileUri(requireContext()));
  124. }
  125. return uris;
  126. }
  127. }