Android Tutorial intent for beginner - messages between apps

Part 1

1- Intent is exactly a Specific Message between Android Apps.
Building this message is simple in B4A:
B4X:
dim intent1 as intent

2- Any message (ie: intent) has a specific purpose to tell target app to do it, like SEND, CALL etc...
So you initialize the intent with thats purposes ACTION
B4X:
intent1.initialize(intent1.ACTION_*,"")
Actions are string parameters, You can set action parameter with intent object action property, or if you want more actions: In your Android SDK directory, under /platforms/android-x/data (x being the API level), you will get many text files, just explore them.

3- Now you have the option to specify the target app you want to talk with it by intent setPackage method, or you can omit it if you want the client to pick up which app
B4X:
intent1.setpackage("com.example.app") 'target app package name


4- As we said intent is a message, so you should determine the message mime type as the following:
B4X:
intent1.setType("*/*") 'mime types ex: text/plain
see the common mime types list

5- Allmost of messages has content, you want to deliver it to target app, so use intent putextra method, you should determine the content data type (different than message type as above).
B4X:
intent1.PutExtra("android.intent.extra.*","your message content data")
For common list of message content data types (called intent extra) read this.

6- Finally: Run & send the message:
B4X:
StartActivity(intent1)

see you in Part 2 ...

Bye
 

Hamied Abou Hulaikah

Well-Known Member
Licensed User
Part 2

Intent (specific/intentional message between android apps) is not sent directly from your app to another app, It sent to android os which handle it & make decision for delivering it to another app.
So, Android os can modify your message or adding extra parameters/actions to your message to be deliverable.

In previous part we simply exploring top most intent methods/properties , In fact there are more properties & methods intent has.

Let's exploring more of them now because we'll want them a lot in next tutorial parts.

1- When you miss important part of message (intent), Android OS evaluates the most suitable property/method for it, simply Android OS try to fill the blank you missed; It will fill it automatically & send your message, or pick a list of choices for user to select/fill manually , or if Android OS can't evaluate missed info: simply your app will CRASH!
Example 1: intent says: Hey Android: show me the contact people number 100 in the list, note we don't specify the target app by setPackage, we let this on android to decide which target app or android requests the user to select the appropirate app.
B4X:
    Dim intent1 As Intent
    intent1.Initialize("android.intent.action.VIEW","content://contacts/people/100")
    StartActivity(intent1)
Example 2: We going more specific, so result more percise. intent says: Hey Android send "Hello Hamied!" text message to phone number "967772332333" using whatsapp app.
B4X:
    Dim sendIntent As Intent
    sendIntent.Initialize(sendIntent.ACTION_MAIN,"")
    sendIntent.PutExtra("jid","967772332333@s.whatsapp.net")
    sendIntent.Action=sendIntent.ACTION_SEND
    sendIntent.SetPackage("com.whatsapp")
    sendIntent.SetType("text/plain")
    sendIntent.PutExtra("android.intent.extra.TEXT","Hello Hamied!")
    StartActivity(sendIntent)
Example 3: This code will crash! because Android can't evaluate it, you will get this error: android.content.ActivityNotFoundException: No Activity found to handle Intent.
B4X:
    Dim intent1 As Intent
    intent1.Initialize("android.intent.action.MAIN","content://contacts/people/100")
    StartActivity(intent1)


2- Another important things: some message requires user permission, so if you don't add the appropriate manifest declaration of permission & runtime request permisssion from user, your app will be CRASH.
Example: This code will crash because we don't set the appropirate user permission, error: java.lang.SecurityException: Permission Denial: starting Intent "requires android.permission.CALL_PHONE"
B4X:
    Dim intent1 As Intent
    intent1.Initialize("android.intent.action.CALL","tel:967772332333")
    StartActivity(intent1)
If you set the correct permission, code will run.

3- Any Android device contains a lot of apps, so Android categorized/grouped them according thier functionality/purpose, this will help our intent message coding, for example if you want android to browse a website, You are targeting the browsers apps. This help & ease the situation for android os.
intent has addCategory method to tell Android about targeted apps group.
You can explore all the intent categories in Android SDK directory, under /platforms/android-x(x being the API level)/data/categories.txt
Example: This will work "apps category is browsers":
B4X:
    Dim intent1 As Intent
    intent1.Initialize("android.intent.action.VIEW","https://b4x.com")
    intent1.AddCategory("android.intent.category.BROWSABLE")
    StartActivity(intent1)
Example: This will not work "apps category is calculator":
B4X:
    Dim intent1 As Intent
    intent1.Initialize("android.intent.action.VIEW","https://b4x.com")
    intent1.AddCategory("android.intent.category.CALCULATOR")
    StartActivity(intent1)


4- The Android OS evalutes your missing info in selecting most appropirate app, but many times you want Android to force user to select the app, in this case we should add intent1.WrapAsIntentChooser method:
B4X:
    Dim intent1 As Intent
    intent1.Initialize("android.intent.action.SEND", "")
    intent1.SetType("text/*")
    intent1.PutExtra("android.intent.extra.TEXT", "this is the message")
    intent1.WrapAsIntentChooser("Choose")
    StartActivity(intent1)

See you in Part 3 ...
 
Last edited:

Hamied Abou Hulaikah

Well-Known Member
Licensed User
Part 3

According to intent action purpose: Intent message content is text based or non-text based.
For example: These are some of intent putextra parameters that are text-based purposes:
android.intent.EXTRA_BCC
android.intent.EXTRA_CC
android.intent.EXTRA_EMAIL
android.intent.EXTRA_PHONE_NUMBER
android.intent.EXTRA_SUBJECT
android.intent.EXTRA_TEXT
android.intent.EXTRA_TITLE
Example of non-text message content: Sharing files or objects with other apps, the commonly intent putextra parameter is android.intent.EXTRA_STREAM.

Generally notice: in sending intent, you should specify your message mime type to avoid crash.

This is a basic example of sending text intent message:
B4X:
Dim in As Intent
in.Initialize(in.ACTION_SEND, "")
in.PutExtra("android.intent.extra.TEXT", "This is my text to send.")
in.SetType("text/plain")
in.WrapAsIntentChooser("Share Via")
StartActivity(in)

This is a basic example of sharing image "non-text based message":
B4X:
Dim FileToSend As String = "Message.txt"
    File.WriteString(Starter.Provider.SharedFolder, FileToSend, "jaklsdjalksdjalskdjasld")
    Dim in As Intent
    in.Initialize(in.ACTION_SEND, "")
    in.SetType("text/plain")
    in.PutExtra("android.intent.extra.STREAM", Starter.Provider.GetFileUri(FileToSend))
    in.Flags = 1 'FLAG_GRANT_READ_URI_PERMISSION
    StartActivity(in)

As you see we used fileprovider to fill the path of image.
We can use classic path using file:/// , but in recent & coming versions of android it is a mistake, Android forces us to use fileprovider because of many reasons, the most ones:
- securing your app files and information you want to share
- creating temporary read/write grant permission without user consent or involvement
- the created uri will be content:// instead of file:///
- it creates shared path/access to desired file.
- it gives you flexibility of sharing: uri or streaming.
AND OF COURSE:
- b4a fileprovider class/library shortening & easing the using of it in few lines.

Notice: We set flags property to 1 "i.e: FLAG_GRANT_READ_URI_PERMISSION". Explanation: When you send intent containing data/stream, that is mean you want to grant target intent-receiving app to read your data, so you should grant it to read. Anyway there are many flags
here But you can ignore them, only use the important ones.

So you must train yourself in using fileprovider class/library, it is important for a lot of things including intent sharing, You should make it as basic fundamental of your b4a programming.

Read about usage of Fileprovider class/library here.
 
Last edited:

Hamied Abou Hulaikah

Well-Known Member
Licensed User
Part 4

Now we are familiar with intent usage, the most thing you are thinking is: How can we found the available intents for any android app?
First method you know about it: googling :)
Second method is exploring any apk manifest xml file: But if you unzip apk file you will get encrypted manifest.xml file! to solve it don't unzip it, You should use apktool decompiler .. it is easy of use, or use JADX.
When you got decrypted manifest.xml, just searching about intent-filter tags , almost intent methods/properties their :)
I attached an example of decompiled whatsapp apk manifest xml file, you will find a plenty of intents declaration.
In each one you will find the action parameter & other parameters.
It is easy .. ENJOY coding

(Note: For advanced coders only: Because this is a simple series of understanding intent, we mentioned discovering static/permanent intents,I omitted exploring dynamic intents .. we need this series simple)

See you in Part 5 ...
 

Attachments

  • whatsappAndroidManifest.xml
    89.1 KB · Views: 226
Last edited:

Hamied Abou Hulaikah

Well-Known Member
Licensed User
Part 5

You understand how to send simple intent "message" to another apps, Now how can our app receiving intent "message" from other apps?

It is simple as sending intent.

There are two type of intents declaration: Static and dynamic intents

I'll explain static one as the following example will receive any text shared from other apps:

1- Declare your intent in manifest editor as this example:

B4X:
AddActivityText(Main,

<intent-filter>

        <action android:name="android.intent.action.SEND" />

        <category android:name="android.intent.category.DEFAULT" />

        <data android:mimeType="text/plain" />

    </intent-filter>

)

You can change Main activity to yours.

2- Handle the incoming intent as the following example:

B4X:
Sub Activity_Resume
    If Activity.GetStartingIntent.Action="android.intent.action.SEND" Then
        dim  receivedtext as string = Activity.GetStartingIntent.GetExtra("android.intent.extra.TEXT")
    End If
End Sub

Done!
 
Last edited:

Hamied Abou Hulaikah

Well-Known Member
Licensed User
Part 6

Executing send intent is done by startactivity(intent) method, this method is one-way direction, that is means you send command action to another app but you don't listen to its response result (callback).

In this part we'll learn how to send intent then wait/listen for result.

It is easy ... Just replace the startactivity(intent) method with startactivityforresult(intent) method.

But this method is not exposed directly as startactivity for b4a developers.
We need to implement it , it is not hard ..

1- Select Javaobject library from libraries tab
2- Declare global object variable for listening purpose:

B4X:
Sub Process_Globals    
    Private ion As Object 'listener object for us
End Sub

3- Add the startactivityforresult method ... Just copy the following code.

B4X:
Sub StartActivityForResult(i As Intent)
    Dim jo As JavaObject = GetBA
    ion = jo.CreateEvent("anywheresoftware.b4a.IOnActivityResult", "ion", Null)
    jo.RunMethod("startActivityForResult", Array As Object(ion, i))
End Sub

Sub GetBA As Object
    Dim jo As JavaObject
    Dim cls As String = Me
    cls = cls.SubString("class ".Length)
    jo.InitializeStatic(cls)
    Return jo.GetField("processBA")
End Sub

4- You will listen to result with ion object variable event

B4X:
Sub ion_Event (MethodName As String, Args() As Object) As Object
    'Args(0) is resultCode: -1 is ok
    'Args(1) is the returning intent / result data
    If -1=Args(0) Then
        Dim i As Intent=Args(1)
        Log(i.ExtrasToString) ' this is the results
    End If
    Return Null
End Sub

5- Finally send intent message as we did before, but with startActivityForResult command.


Let's take a little example:
Get the media file path of ringtone using ringtone picker:

B4X:
    Dim i As Intent
    i.Initialize("android.intent.action.RINGTONE_PICKER", "")
    i.PutExtra("android.intent.extra.ringtone.TYPE", 1)
    StartActivityForResult(i)

Best Regards
 

toby

Active Member
Licensed User
Longtime User
Great tutorials! I have some questions.

How to use intent to
1. start the File Manager (any file manager. Show a list if there are two or more) and open up the specified folder as the current folder in the File Manager.
2. allow user to pick a folder in File Manager so that he/she can copy a list of files to a new location in either Internal storage or SD Card.

TIA
 

Hamied Abou Hulaikah

Well-Known Member
Licensed User
How to use intent to
1. start the File Manager (any file manager. Show a list if there are two or more) and open up the specified folder as the current folder in the File Manager.
2. allow user to pick a folder in File Manager so that he/she can copy a list of files to a new location in either Internal storage or SD Card.
Intent is request message to another app that has the ability to do your features above, Have your phone containing app that performs this tasks? share us/link here to extract its manifest file to see its available intents.
 

toby

Active Member
Licensed User
Longtime User
Have your phone containing app that performs this tasks?

Thank you very much for quick response and for your help!

Every phone comes with a file manager and different phone manufacturers use different packet names. So I would like to open the default one, whatever it is. How can I do that?

TIA
 
Top