Activity exported=false listed in activity chooser
Asked Answered
M

1

5

I have two similar applications (one free, one paid).

An activity is defined with exported="false"

    <activity
        android:name=".MyActivity"
        android:exported="false"
        android:noHistory="true" >
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="vnd.android.cursor.item/vnd.mine" />
        </intent-filter>
    </activity>

When I call startActivity with the appropriate implicit intent from the free app, the activity picker appears.

I don't understand why the activity from the paid app appears, since it is exported="false"

I suppose I can add an intent filter based on the URL, but my question is: why does the activity from the other app appear when the doc reads

Whether or not the activity can be launched by components of other applications

Map answered 15/12, 2012 at 13:42 Comment(0)
M
7

I don't understand why the activity from the paid app appears, since it is exported="false"

Because you have a matching <intent-filter>. Since you do not need the <intent-filter> for a non-exported activity, simply delete it and use an explicit Intent when starting this activity.

why does the activity from the other app appear when the doc reads...

I had the same question and was told that this was expected behavior and the bug is in our app for having a useless <intent-filter>. Quoting Dianne Hackborn:

I would generally consider this a bug in the app -- if you have an activity that you aren't allowing other apps to launch, why the heck are you publishing an intent filter that they will match to try to launch? The security of the activity (whether it is not exported or requires a permission) is not part of intent matching. ...this scenario (publishing an activity that matches intents other applications will use but then restricting it to not be launchable by other applications) is not useful if not outright broken.

Maihem answered 15/12, 2012 at 14:4 Comment(7)
Once again you give an excellent answer, even though I am not really happy with it. I can reply to this dear Dianne Hackborn: I want the code in the library project to be generic, it defines an AbstractActivity ; the free app defines and activity .MyActivity, the paid an activity .MyProActivty, both with the same intent filter. I would generally consider a bug in a framework when inheritance cannot be done.Map
Workaround: have a method in the abstract class that returns the class or explicit intent. (in my particular case, I really don't want to do that)Map
@rds: "I want the code in the library project to be generic" -- that's not really the role of the <intent-filter>. It can be used that way, with exported activities, but that was not its original purpose. It is supposed to be an advertisement to the OS and third parties of functionality you are willing to let them use.Maihem
will you be kind enough to accept a small chat session, so that I can better ask your adviceMap
@rds: Since I offer office hours chats to my subscribers, I try to avoid private SO chats. My apologies for my restrictive policy. BTW, another possible workaround would be for you to add a private category to your <intent-filter> and use it (instead of DEFAULT) in the Intent. With distinct pro-vs.-free categories, you should be able to avoid the chooser. That doesn't prevent somebody else from creating their own activity with that same category, though, which is part of the <intent-filter>-as-public-API model.Maihem
Thanks, I understand. In the question, I mentioned using the data to refine the filter, but the category would work similarly (in my case I already use the category for something else)Map
@rds: Bear in mind that you can have several categories per Intent and <intent-filter>. The filter must match every category in the Intent, IIRC.Maihem

© 2022 - 2024 — McMap. All rights reserved.