I'm going through the the Android Developer Tutorials and I encountered a line of code that I do not understand.
This is the line of code (found on 4th page of the Android Developer tutorials.)
Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
I have a couple of questions.
1) Intent.ACTION_VIEW
documentation says that it simply displays data to the user. I understand that the app it chooses will depend on the type of data to be displayed. For instance, in this case, the webpage is being parsed as a uri data type. But what kind of implicit intent is being created here? In the backend, can I think of Android as going through all the classes in my phone and seeing which one has the intent filter that can possibly handle the data and creating the intent structure to start this class that it found?
2) What happens if it finds multiple classes that can handle this? Does it simply choose the default or ask the user to choose what app it wants to run in on? When I ran the code on my phone, it simply started the Samsung Internet App by default.
3) This is actually my main question. If the intent has already been linked to a class to start, why bother with intent.resolveActivity(getPackageManager())
at all? Its documentation specifies how it handles the class if a class is returned. So alright, a class is returned. But also this class that it returns is not 'incorporated' in my intent
at any line of my code, which makes me think that Intent.ACTION_VIEW
has somehow already handled it for me.
This is going to a leap, but would I be sort-of correct in saying that Intent.ACTION_VIEW
runs intent.resolveActivity(getPackageManager())
or another function that does similar and somehow incorporates the class it returns into my intent?
4) Also, out of curiosity, what is inside the package manager class? I read here that it is like a directory of application data. Would I be correct in saying that? What kind of data does it keep about the application and how can I go about accessing them. The documentation doesn't seem to help much.
By the way this method can return null on Android 11 and higher caused by new restrictions addedd : https://developer.android.com/about/versions/11/privacy/package-visibility So to resolve this issue we must add a queries under manifest :
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
</queries>
Don't forget to update the gradle plugin in case the queries items is not found :
classpath("com.android.tools.build:gradle:3.5.4")
But what kind of implicit intent is being created here?
Um... an ACTION_VIEW
Intent
, to view the requested URL.
can I think of Android as going through all the classes in my phone and seeing which one has the intent filter that can possibly handle the data and creating the intent structure to start this class that it found?
Activities are registered in the manifest. The OS basically has a database of all registered activities and their <intent-filter>
details, and it uses that database to find candidates for any given implicit Intent
.
Does it simply choose the default or ask the user to choose what app it wants to run in on?
That depends on a variety of factors, including:
Whether the user chose a default handler for that sort of Intent
(e.g., chose a default Web browser)
Whether you wrap the Intent
using Intent.createChooser()
to force a chooser
Whether an app has registered an app link for the URL
If the intent has already been linked to a class to start, why bother with intent.resolveActivity(getPackageManager()) at all?
Because there may be zero activities to handle the Intent
. Even for something as common as a Web browser, the specific user might not have access to a browser app (secondary user profiles, etc.). If you try starting an activity, and there is no match, you get an ActivityNotFoundException
, so this check is trying to avoid such an exception.
but would I be sort-of correct in saying that Intent.ACTION_VIEW runs intent.resolveActivity(getPackageManager()) or another function that does similar and somehow incorporates the class it returns into my intent?
Not really. It would be more correct to say that resolveActivity()
queries the database that I mentioned to see what would handle the Intent
, if anything.
what is inside the package manager class?
A little bit of Java code. It is mostly an IPC gateway to a core OS process, serving to query the database of installed apps, their capabilities, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With