Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly is intent.resolveActivity(getPackageManager()) doing?

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.

like image 648
Yip Jung Hon Avatar asked Apr 14 '19 15:04

Yip Jung Hon


2 Answers

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")
like image 89
Sofien Rahmouni Avatar answered Oct 02 '22 05:10

Sofien Rahmouni


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.

like image 38
CommonsWare Avatar answered Oct 02 '22 03:10

CommonsWare