Android Question [solved]How to retrieve multiple images via ACTION_SEND_MULTIPLE

KMatle

Expert
Licensed User
Longtime User
I can retrieve a single image shared by another app to mine but I did not find an example retrieving multiple images. Manifest:

B4X:
AddActivityText(Main,
<intent-filter>
    <action android:name="android.intent.action.SEND" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.SEND_MULTIPLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="image/*" />
</intent-filter>)

which works but here I got stuck ("ACTION_SEND_MULTIPLE" isn't a member of...)

B4X:
Sub Activity_Resume
    If IsRelevantIntent(Activity.GetStartingIntent) Then
        Dim in As JavaObject = Activity.GetStartingIntent
        Dim uri As String = in.RunMethod("getParcelableExtra", Array("android.intent.extra.STREAM"))
        Try
            Log("Loading bitmap from: " & uri)
            Dim bmp As Bitmap = LoadBitmapSample("ContentDir", uri, 100%x, 100%y)
            Activity.SetBackgroundImage(bmp)
        Catch
            Log(LastException)
        End Try
    End If
End Sub

Private Sub IsRelevantIntent(in As Intent) As Boolean
    Log(in.Action)
    If in.IsInitialized And in <> OldIntent And (in.Action = in.ACTION_SEND Or in.Action = in.ACTION_SEND_MULTIPLE) Then
        OldIntent = in
        Return True
    End If
    Return False
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 

DonManfred

Expert
Licensed User
Longtime User
Can you please post a log of the content(data) of the startingintent?
Maybe you just not get a android.intent.extra.STREAM but instead you got something other.
I saw a code in the past. I´m pretty sure that it works. Maybe i did wrote the code :D
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
B4X:
Sub Activity_Resume
   
    If IsRelevantIntent(Activity.GetStartingIntent) Then
        Dim starting As Intent = Activity.GetStartingIntent
        Log(starting)
        Log(starting.Action)
        'Log(starting.GetData)
        Log(starting.ExtrasToString)
        'Bundle[{android.intent.extra.STREAM=[content://b4a.example.provider/name/B4A.png, content://b4a.example.provider/name/B4i.png, content://b4a.example.provider/name/B4J.png, content://b4a.example.provider/name/B4R.png]}]
        Dim inte As JavaObject = Activity.GetStartingIntent
        Log("Parcel")
        Log(inte.RunMethod("getParcelableExtra", Array("android.intent.extra.STREAM")))
        Log("Parcel")
        'Log(uri)
       
        If starting.Action = "android.intent.action.SEND_MULTIPLE" Then
            Log("Multiple")
            Dim intents As List = inte.RunMethod("getParcelableArrayListExtra", Array("android.intent.extra.STREAM"))
            Log(intents)
            If intents.Size > 0 Then
                For i = 0 To intents.Size-1
                    Dim fle As String = intents.Get(i)
                    Log("File: "&fle)
                Next
            End If
            Log("Multiple")
       
        Else
            If starting.GetData.StartsWith("content") Then
                Dim starting As Intent = Activity.GetStartingIntent
                Dim uri As String = starting.GetData
           
                Try
                    Log("Loading bitmap from ContentUri: " & uri)
                    Dim bmp As Bitmap = LoadBitmapSample("ContentDir", uri, 100%x, 100%y)
                    Activity.SetBackgroundImage(bmp)
                Catch
                    Log(LastException)
                End Try
            Else
                Dim in As JavaObject = Activity.GetStartingIntent
                Dim uri As String = in.RunMethod("getParcelableExtra", Array("android.intent.extra.STREAM"))
                Log(uri)
                'Try
                Log("Loading bitmap from: " & uri)
                'Dim bmp As Bitmap = LoadBitmapSample("ContentDir", uri, 100%x, 100%y)
                'Activity.SetBackgroundImage(bmp)
                'Catch
                'Log(LastException)
                'End Try
            End If

        End If
       

    End If
End Sub

** Activity (main) Pause, UserClosed = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = true **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
(Intent) Intent { act=android.intent.action.SEND_MULTIPLE typ=image/jpeg flg=0x3020001 cmp=b4a.example.sharedimage/.main launchParam=MultiScreenLaunchParams { mDisplayId=0 mBaseDisplayId=0 mFlags=0 } clip={image/jpeg U:content://b4a.example.provider/name/B4A.png ...} (has extras) }
android.intent.action.SEND_MULTIPLE
Bundle[{android.intent.extra.STREAM=[content://b4a.example.provider/name/B4A.png, content://b4a.example.provider/name/B4i.png, content://b4a.example.provider/name/B4J.png, content://b4a.example.provider/name/B4R.png]}]
Parcel
null
Parcel
Multiple
(ArrayList) [content://b4a.example.provider/name/B4A.png, content://b4a.example.provider/name/B4i.png, content://b4a.example.provider/name/B4J.png, content://b4a.example.provider/name/B4R.png]
File: content://b4a.example.provider/name/B4A.png
File: content://b4a.example.provider/name/B4i.png
File: content://b4a.example.provider/name/B4J.png
File: content://b4a.example.provider/name/B4R.png
Multiple
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **

My Manifest

B4X:
AddManifestText(
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="26"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
AddActivityText(Main,
<intent-filter>
   <action android:name="android.intent.action.SEND" />
   <category android:name="android.intent.category.DEFAULT" />
   <data android:mimeType="image/*" />
</intent-filter>)
AddActivityText(Main,
<intent-filter>
   <action android:name="android.intent.action.SEND_MULTIPLE" />
   <category android:name="android.intent.category.DEFAULT" />
   <data android:mimeType="image/*" />
</intent-filter>)


AddActivityText(Main,
<intent-filter>
  <action android:name="android.intent.action.PICK" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
  <action android:name="android.intent.action.GET_CONTENT" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.OPENABLE" />
  <data android:mimeType="image/*" />
</intent-filter>
)
'End of default text.
AddApplicationText(
  <provider
  android:name="android.support.v4.content.FileProvider"
  android:authorities="$PACKAGE$.provider"
  android:exported="false"
  android:grantUriPermissions="true">
  <meta-data
  android:name="android.support.FILE_PROVIDER_PATHS"
  android:resource="@xml/provider_paths"/>
  </provider>
)
CreateResource(xml, provider_paths,
   <external-files-path name="name" path="shared" />
)
 
Upvote 0

KMatle

Expert
Licensed User
Longtime User
Thanks @DonManfred :)

Another solution (it works with 1-n images) but I don't know if the code is elegant as I get everything from Extras searching for "content://".

Manifest

B4X:
AddActivityText(Main,
<intent-filter>
    <action android:name="android.intent.action.SEND" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.SEND_MULTIPLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="image/*" />
</intent-filter>)

Code

B4X:
Sub Activity_Resume
    Dim ImageList As List
    ImageList=GetImages(Activity.GetStartingIntent)
    If ImageList.Size>0 Then
        
        Dim uri As String = ImageList.Get(0) 'Just the first image
        Try
            Log("Loading bitmap from: " & uri)
            Dim bmp As Bitmap = LoadBitmapSample("ContentDir", uri, 100%x, 100%y)
            Activity.SetBackgroundImage(bmp)
        Catch
            Log(LastException)
        End Try
    End If
End Sub

Private Sub GetImages(in As Intent) As List
    Log(in.Action)
    Log(in.GetData)
    Log(in.ExtrasToString)
    Dim ImageList As List
    ImageList.Initialize
    If in.IsInitialized And in <> OldIntent Then
        If in.Action = "android.intent.action.SEND" Or in.Action= "android.intent.action.SEND_MULTIPLE" Then
           ImageList= GetImagePathsFromExtras(in.ExtrasToString)     
        End If
        OldIntent = in
    End If
    Return ImageList
End Sub

Sub GetImagePathsFromExtras (Extras As String) As List
    Log(Extras)
    Dim ImageList As List
    ImageList.Initialize
    If Extras.StartsWith("Bundle") Then
        'Bundle[{makeup=false, KEY_ITEM_ORIENTATION_LIST=[0, 0], food=false, KEY_ITEM_MIME_TYPE_LIST=[image/*, image/*], KEY_MEDIA_SET_PATH=/local/camera, android.intent.extra.STREAM=[content://media/external/images/media/13930, content://media/external/images/media/13935]}]
        Dim pos As Int = Extras.IndexOf("content://")
        If pos >=0 Then
           Extras=Extras.SubString2(pos-1,Extras.Length) 'Not that elegant, but it works
           Extras=Extras.Replace("}","")
           Extras=Extras.Replace("[","")
           Extras=Extras.Replace("]","")
           Extras=Extras.Replace(" ","")
           Extras=Extras.Replace("=","")           
           Log(Extras)
            Dim Images() As String
            Images = Regex.Split(",", Extras)
            ImageList.Initialize2(Images)
            Log(ImageList)
        End If
    
    End If
    Return ImageList
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
if the code is elegant as I get everything from Extras searching for "content://".
i personally find my verson more elegant
B4X:
  If starting.Action = "android.intent.action.SEND_MULTIPLE" Then
            Log("Multiple")
            Dim intents As List = inte.RunMethod("getParcelableArrayListExtra", Array("android.intent.extra.STREAM"))
            'Log(intents)
            If intents.Size > 0 Then
                For i = 0 To intents.Size-1
                    Dim fle As String = intents.Get(i)
                    Log("File: "&fle)
                Next
            End If
            Log("Multiple")
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Did not knew about this
me too. But i tried to convert the sending part

For Each image As String In images
Dim u As Uri = CreateFileProviderUri(Starter.strSharedFolder, image)
Uris.Add(u)
Next

Dim jo As JavaObject = i
jo.RunMethod(
"putParcelableArrayListExtra", Array As Object("android.intent.extra.STREAM", Uris))
i.Flags =
1

putParcelableArrayListExtra works. I just try to change it to use
getParcelableArrayListExtra instead to get the list back. And it worked
 
Last edited:
Upvote 0
Top