Эх сурвалжийг харах

Merge pull request #9677 from nextcloud/fix/send-multiple-files

Fix sending multiple files
Álvaro Brey 3 жил өмнө
parent
commit
010942f0a2

+ 0 - 0
screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialog.png → screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialogDifferentTypes_Screenshot.png


BIN
screenshots/gplay/debug/com.owncloud.android.ui.dialog.SendFilesDialogTest_showDialog_Screenshot.png


+ 56 - 12
src/androidTest/java/com/owncloud/android/ui/dialog/SendFilesDialogTest.kt

@@ -22,43 +22,87 @@
 package com.owncloud.android.ui.dialog
 
 import androidx.fragment.app.FragmentManager
+import androidx.recyclerview.widget.RecyclerView
 import androidx.test.espresso.intent.rule.IntentsTestRule
 import androidx.test.platform.app.InstrumentationRegistry
 import com.nextcloud.client.TestActivity
 import com.owncloud.android.AbstractIT
+import com.owncloud.android.R
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.utils.ScreenshotTest
+import org.junit.Assert
 import org.junit.Rule
 import org.junit.Test
 
 class SendFilesDialogTest : AbstractIT() {
+    companion object {
+        private val FILES_SAME_TYPE = setOf(
+            OCFile("/1.jpg").apply {
+                mimeType = "image/jpg"
+            },
+            OCFile("/2.jpg").apply {
+                mimeType = "image/jpg"
+            }
+        )
+        private val FILES_MIXED_TYPE = setOf(
+            OCFile("/1.jpg").apply {
+                mimeType = "image/jpg"
+            },
+            OCFile("/2.pdf").apply {
+                mimeType = "application/pdf"
+            },
+            OCFile("/3.png").apply {
+                mimeType = "image/png"
+            }
+        )
+    }
+
     @get:Rule
     val testActivityRule = IntentsTestRule(TestActivity::class.java, true, false)
 
-    @Test
-    @ScreenshotTest
-    fun showDialog() {
+    private fun showDialog(files: Set<OCFile>): SendFilesDialog {
         val activity = testActivityRule.launchActivity(null)
 
         val fm: FragmentManager = activity.supportFragmentManager
         val ft = fm.beginTransaction()
         ft.addToBackStack(null)
 
-        val files = setOf(
-            OCFile("/1.jpg").apply {
-                mimeType = "image/jpg"
-            },
-            OCFile("/2.jpg").apply {
-                mimeType = "image/jpg"
-            }
-        )
-
         val sut = SendFilesDialog.newInstance(files)
         sut.show(ft, "TAG_SEND_SHARE_DIALOG")
 
         InstrumentationRegistry.getInstrumentation().waitForIdleSync()
         shortSleep()
 
+        return sut
+    }
+
+    @Test
+    fun showDialog() {
+        val sut = showDialog(FILES_SAME_TYPE)
+        val recyclerview: RecyclerView = sut.requireDialog().findViewById(R.id.send_button_recycler_view)
+        Assert.assertNotNull("Adapter is null", recyclerview.adapter)
+        Assert.assertNotEquals("Send button list is empty", 0, recyclerview.adapter!!.itemCount)
+    }
+
+    @Test
+    @ScreenshotTest
+    fun showDialog_Screenshot() {
+        val sut = showDialog(FILES_SAME_TYPE)
+        sut.requireDialog().window?.decorView.let { screenshot(it) }
+    }
+
+    @Test
+    fun showDialogDifferentTypes() {
+        val sut = showDialog(FILES_MIXED_TYPE)
+        val recyclerview: RecyclerView = sut.requireDialog().findViewById(R.id.send_button_recycler_view)
+        Assert.assertNotNull("Adapter is null", recyclerview.adapter)
+        Assert.assertNotEquals("Send button list is empty", 0, recyclerview.adapter!!.itemCount)
+    }
+
+    @Test
+    @ScreenshotTest
+    fun showDialogDifferentTypes_Screenshot() {
+        val sut = showDialog(FILES_MIXED_TYPE)
         sut.requireDialog().window?.decorView.let { screenshot(it) }
     }
 }

+ 7 - 5
src/main/java/com/nextcloud/client/utils/IntentUtil.kt

@@ -30,6 +30,7 @@ object IntentUtil {
     @JvmStatic
     public fun createSendIntent(context: Context, file: OCFile): Intent =
         createBaseSendFileIntent().apply {
+            action = Intent.ACTION_SEND
             type = file.mimeType
             putExtra(Intent.EXTRA_STREAM, file.getExposedFileUri(context))
         }
@@ -37,20 +38,21 @@ object IntentUtil {
     @JvmStatic
     public fun createSendIntent(context: Context, files: Array<OCFile>): Intent =
         createBaseSendFileIntent().apply {
+            action = Intent.ACTION_SEND_MULTIPLE
             type = getUniqueMimetype(files)
-            putExtra(Intent.EXTRA_STREAM, getExposedFileUris(context, files))
+            putParcelableArrayListExtra(Intent.EXTRA_STREAM, getExposedFileUris(context, files))
         }
 
     private fun createBaseSendFileIntent(): Intent =
-        Intent(Intent.ACTION_SEND).apply {
+        Intent().apply {
             addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
         }
 
     private fun getUniqueMimetype(files: Array<OCFile>): String? = when {
-        files.distinctBy { it.mimeType }.size > 1 -> null
+        files.distinctBy { it.mimeType }.size > 1 -> "*/*"
         else -> files[0].mimeType
     }
 
-    private fun getExposedFileUris(context: Context, files: Array<OCFile>): Array<Uri> =
-        files.map { it.getExposedFileUri(context) }.toTypedArray()
+    private fun getExposedFileUris(context: Context, files: Array<OCFile>): ArrayList<Uri> =
+        ArrayList(files.map { it.getExposedFileUri(context) })
 }

+ 10 - 3
src/main/java/com/owncloud/android/ui/dialog/SendFilesDialog.java

@@ -9,6 +9,7 @@ import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Toast;
 
 import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
 import com.nextcloud.client.utils.IntentUtil;
@@ -82,8 +83,14 @@ public class SendFilesDialog extends BottomSheetDialogFragment {
 
         // populate send apps
         Intent sendIntent = IntentUtil.createSendIntent(requireContext(), files);
+        List<ResolveInfo> matches = requireActivity().getPackageManager().queryIntentActivities(sendIntent, 0);
+        if (matches.isEmpty()) {
+            Toast.makeText(getContext(), R.string.no_send_app, Toast.LENGTH_SHORT).show();
+            dismiss();
+            return null;
+        }
 
-        List<SendButtonData> sendButtonDataList = setupSendButtonData(sendIntent);
+        List<SendButtonData> sendButtonDataList = setupSendButtonData(matches);
 
         SendButtonAdapter.ClickListener clickListener = setupSendButtonClickListener(sendIntent);
 
@@ -108,11 +115,11 @@ public class SendFilesDialog extends BottomSheetDialogFragment {
     }
 
     @NonNull
-    private List<SendButtonData> setupSendButtonData(Intent sendIntent) {
+    private List<SendButtonData> setupSendButtonData(List<ResolveInfo> matches) {
         Drawable icon;
         SendButtonData sendButtonData;
         CharSequence label;
-        List<ResolveInfo> matches = requireActivity().getPackageManager().queryIntentActivities(sendIntent, 0);
+
         List<SendButtonData> sendButtonDataList = new ArrayList<>(matches.size());
         for (ResolveInfo match : matches) {
             icon = match.loadIcon(requireActivity().getPackageManager());

+ 1 - 0
src/main/res/values/strings.xml

@@ -1006,4 +1006,5 @@
     <string name="file_list_empty_unified_search_no_results">No results found for your query</string>
     <string name="file_list_empty_gallery">Found no images or videos</string>
     <string name="error_creating_file_from_template">Error creating file from template</string>
+    <string name="no_send_app">No app available for sending the selected files</string>
 </resources>