Intent Filters & Receiving

yttrium

Active Member
Licensed User
Longtime User
I've looked up how to receive content from an app when it wants to share something. This usually involves "Intent Filters". For my app, I want it to be able to accept pictures, and then launch the app and save the picture to memory when it's launched (via the share).

How do I go about doing this? Explanations I've seen involve adding something resembling the following to my Manifest file:

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

My app doesn't show up in the stock Gallery's share function with this. How can I make it work, and how can I reference what to do when the app is launched this way? There's nice documentation on this for Android, but not for Basic4Android.
 

yttrium

Active Member
Licensed User
Longtime User
AddActivityText needs two parameters. What do I use for the first and how do I access it?
 
Upvote 0

yttrium

Active Member
Licensed User
Longtime User
What would be the normal convention for handling this? Should I add a new activity? If not, what's the default activity name?
 
Upvote 0

yttrium

Active Member
Licensed User
Longtime User
Its cleaner to use a new activity although possible to use the main one. The default activity is called Main.

So how would I go about implementing this? Like so?

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>)

And what sub from there would I use to declare what happens?
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
So how would I go about implementing this? Like so?

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>)
Yes, so now this intent filter will wake up your activity Main whenever someone uses the 'Send' action on an image.

And what sub from there would I use to declare what happens?
This is trickier. You use the Activity_Resume sub but you need to check the starting intent.

Something like:
B4X:
Sub Activity_Resume
   Dim In As Intent 
   In = Activity.GetStartingIntent 
   
   If In.ExtrasToString.Contains("no extras") Then
               'No Data
   Else
      ParseIntent(In)
   End If
End Sub
 
Upvote 0

yttrium

Active Member
Licensed User
Longtime User
Yes, so now this intent filter will wake up your activity Main whenever someone uses the 'Send' action on an image.


This is trickier. You use the Activity_Resume sub but you need to check the starting intent.

Something like:
B4X:
Sub Activity_Resume
   Dim In As Intent 
   In = Activity.GetStartingIntent 
   
   If In.ExtrasToString.Contains("no extras") Then
               'No Data
   Else
      ParseIntent(In)
   End If
End Sub

So if the intent filter was a bitmap, how would I import the intent's data and save it as a new bitmap?
 
Upvote 0

yttrium

Active Member
Licensed User
Longtime User
Upvote 0

yttrium

Active Member
Licensed User
Longtime User
Also, in this:

B4X:
Sub Activity_Resume
    Dim In As Intent 
    In = Activity.GetStartingIntent 
    
    If In.ExtrasToString.Contains("no extras") Then
               'No Data
    Else
        ParseIntent(In)
    End If
End Sub

"ParseIntent" isn't valid. Was that just a filler?

Try to do:

To figure out what is sent back in return and which extra is which.

And what does that do?
 
Last edited:
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
"ParseIntent" isn't valid. Was that just a filler?
And what does that do?
Yes it was just a filler. It depends on what your intent does.
An intent contains extra information in various fields.
We use PutExtra and GetExtra to get an set this values in the intent (and HasExtra to check if an extra exists).
I suggest you have a look here: Basic4android - Core

So depending on what the other app is send you back just look in the extras (easiest way is that I have told above ExtrasToString), and then perform your actions dpending on what you want to do with it.
 
Upvote 0

yttrium

Active Member
Licensed User
Longtime User
Yes it was just a filler. It depends on what your intent does.
An intent contains extra information in various fields.
We use PutExtra and GetExtra to get an set this values in the intent (and HasExtra to check if an extra exists).
I suggest you have a look here: Basic4android - Core

So depending on what the other app is send you back just look in the extras (easiest way is that I have told above ExtrasToString), and then perform your actions dpending on what you want to do with it.

Sorry, I pretty much opened this thread because I couldn't find that page.

What kind of data is contained in extras and why is it necessary?
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
Sorry, I pretty much opened this thread because I couldn't find that page.

What kind of data is contained in extras and why is it necessary?
It can be anything.
It is used as the primary mechanism for inter-activity or inter-app communication. You use the extras in the intent to pass data to another app that can do some actions based on the data.
The same thing you are trying to do here, you are trying to get information back from the gallery, so the gallery apps needs to find a way to tell you which image was selected, it does this by setting a field in the intent so you can use that image. What you want to do with the image, I do not know.
I suggest you read up about intents more in general in the google android developers site: Intent | Android Developers
 
Upvote 0

yttrium

Active Member
Licensed User
Longtime User
It can be anything.
It is used as the primary mechanism for inter-activity or inter-app communication. You use the extras in the intent to pass data to another app that can do some actions based on the data.
The same thing you are trying to do here, you are trying to get information back from the gallery, so the gallery apps needs to find a way to tell you which image was selected, it does this by setting a field in the intent so you can use that image. What you want to do with the image, I do not know.
I suggest you read up about intents more in general in the google android developers site: Intent | Android Developers

Let's say I want to set an ImageView's background image to the shared bitmap referenced in the intent. What would all of the code needed for that be? I'm still a little confused on how to obtain a bitmap from the intent filter.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
Let's say I want to set an ImageView's background image to the shared bitmap referenced in the intent. What would all of the code needed for that be? I'm still a little confused on how to obtain a bitmap from the intent filter.

To be honest, I dont know my self, but if we go step by step we can find out.
First you need to post what this line returns:
B4X:
Log(In.ExtrasToString)

Then we will need to convert the Uri to a Filepath (maybe using this: http://www.b4x.com/forum/basic4andr...73-uri-content-media-real-file.html#post76176 ).

From the Filepath, we can use LoadBitmap to load the image in a Imageview.
 
Upvote 0

yttrium

Active Member
Licensed User
Longtime User
For some reason, I continue to get the following error whenever I open the app, and hitting YES to ignore and continue yields no results (image not imported).

B4X:
Error occurred:
An error has occured in sub:
main_getpathfromcontentresult
(java line: 408)
java.lang.RuntimeException:
Object should first be initialized (Cursor).
Continue?

My code is as follows:

B4X:
Sub Activity_Resume
   Dim In As Intent 
    In = Activity.GetStartingIntent 
    
    If In.ExtrasToString.Contains("no extras") Then
               'No Data
    Else
       Preview.SetBackgroundImage(LoadBitmap("", GetPathFromContentResult(In.ExtrasToString)))
    End If
       pager.GotoPage(CurrentPage, False)
End Sub

Sub GetPathFromContentResult(UriString As String) As String
    If UriString.StartsWith("/") Then Return UriString
    Dim Proj() As String
    Proj = Array As String("_data")
    Dim Cursor1 As Cursor
    Dim r As Reflector
    Dim Uri As Object
    Uri = r.RunStaticMethod("android.net.Uri", "parse", _
        Array As Object(UriString), _
        Array As String("java.lang.String"))
    r.Target = r.GetContext
    r.Target = r.RunMethod("getContentResolver")
    Cursor1 = r.RunMethod4("query", _
    Array As Object(Uri, Proj, Null, Null, Null), _
    Array As String("android.net.Uri", _
        "[Ljava.lang.String;", "java.lang.String", _
        "[Ljava.lang.String;", "java.lang.String"))
    
    Cursor1.Position = 0
    Dim res As String
    res = Cursor1.GetString("_data")
    Cursor1.Close
    Return res
End Sub

Of importance to note is that when I don't launch with an intent filter, and I instead launch normally and use the ContentChooser to load an image:

B4X:
Sub Globals
    Dim cc As ContentChooser
End Sub

Sub Loadbtn_Click
   cc.Show("Image/*", "")
End Sub

Sub CC_Result (Success As Boolean, Dir As String, FileName As String)
   Image3.Initialize3(LoadBitmap("", GetPathFromContentResult(FileName)))
   Preview.SetBackgroundImage(Image3)
End Sub

The image loads perfectly.

Any ideas?
 
Last edited:
Upvote 0
Top