What Is the Purpose of "Android.Intent.Category.Default"

What is the purpose of android.intent.category.DEFAULT?

Categories are used for implicit Intents. So, If your Activity can be started by an implicit Intent when no other specific category is assigned to activity, activity's Intent filter should include this category. (even if you have other categories in the Intent filter). If you are sure that your activity must be called with any other Category, don't use the Default.

Setting Category to Default doesn't mean that this Activity will be used by default when your app launches. The Activity just says to system that " Oh I could be started, even if the starter Intent's category is set to Nothing at all ! "

What are different between android.intent.category.DEFAULT and android.intent.category.PREFERENCE?

The purpose of using an intent filter is for implicit intents. If your Activity is initiated by an implicit intent where no specific category is assigned to it, its Intent filter should include the category mentioned in the manifest file.

It seems that both Code A and Code B can work well.

That is correct. The same code and functionality can be replicated by the an Activity "X" even by defining it as different intent activity filters and categories in the Manifest file. Like i've mentioned above, the purpose of an intent filter is in using implicit intent. If you defined it as a Preference Category intent in the manifest, Activity X would be called when you initiate an implicit intent of Preference type.

What are different between android.intent.category.DEFAULT and android.intent.category.PREFERENCE

android.intent.category.DEFAULT is the default category for an implicit intent (AS in it does not have any specific role) whereas an activity defined as android.intent.category.PREFERENCE would be called when an implicit intent where you need to call a Preference Activity/Fragment/Panel.

What exactly is the purpose of CATEGORY_ALTERNATIVE

Suppose you're using some messenger app and a friend sent you an interesting link. Then there are several things you could do with it:

  • open it in a browser
  • share it with another person
  • maybe save it in some notes app
  • ...

If you take the link as "data you are currently viewing" then it would be nice if the messenger offered you an option to select the appropriate action from a bundle of alternative actions which are currently available on your device.

With Intent.CATEGORY_ALTERNATIVE and Menu.addIntentOptions(), the framework has a way for the app which is the initital "owner" of some type of data to offer the user access to further actions. These actions can be implemented by any app which is running on the device and which announced its capability of handling this specific data type by an entry in the Manifest.xml, more specifically in the <intent-filter> tag.

Let's consider a very simple - if not very realistic - example:

My app has some String value which it displays to the users. Alternative actions could be

  • parsing the String based on some regex
  • sorting the letters of the String
  • transforming the String, e.g. to upper case letters
  • ...

My app will have its Activity or Fragment override onCreateOptionsMenu() as follows (code snippet for a Fragment)

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.home_menu, menu);

// Create an Intent that describes the requirements to fulfill, to be included
// in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_TEXT, "Lorem ipsum");
intent.setType("text/plain");
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

// Search and populate the menu with acceptable offering applications.
menu.addIntentOptions(
R.id.intent_group, // Menu group to which new items will be added
0, // Unique item ID (none)
0, // Order for the items (none)
this.getActivity().getComponentName(), // The current activity name
null, // Specific items to place first (none)
intent, // Intent created above that describes our requirements
0, // Additional flags to control items (none)
null); // Array of MenuItems that correlate to specific items (none)
}

The Activitys which are able to handle the given String will declare an IntentFilter as child tag of their tag in the Manifest.xml:

<activity android:name=".ToUpperCaseActivity">
<intent-filter android:label="@string/label_action_text_to_uppercase">
<action android:name="de.ddvsidedown.alternativeoptionsapp.action.ALL_CAPS" />
<category android:name="android.intent.category.ALTERNATIVE" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>

or

<activity android:name=".SortActivity">
<intent-filter android:label="@string/label_action_sort_text">
<action android:name="de.ddvsidedown.alternativeoptionsapp.action.SORT" />
<category android:name="android.intent.category.ALTERNATIVE" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>

Then my app will show the following popup menu when the user taps the overflow icon...

popup menu with "Text to upper case" and "Sort text"

... and the runtime will navigate directly to the chosen Activity. There, the text can be retrieved as follows:

 if(getIntent().hasExtra(Intent.EXTRA_TEXT)) {

char[] ca = getIntent().getCharSequenceExtra(Intent.EXTRA_TEXT).toString().toCharArray();
Arrays.sort(ca);
String message = buildString(ca);
Log.d(TAG, "onCreate: " + message);
TextView textView = findViewById(R.id.tvResult);
textView.setText(message);
}

Please note that the exact code for retrieving the data depends on the data type, just like with "normal" Intents with no <category> tag at all or with <category android:name="android.intent.category.DEFAULT" /> in the <intent-filter> .

how does this work if we need to include CATEGORY_DEFAULT in order for an activity to receive implicit intents

You need <category android:name="android.intent.category.DEFAULT"/> in the <intent-filter> of an Activity if you want it to appear in a chooser dialog. By the way, an Activity can have multiple <intent-filter> tags

Let's modify the example: my app also has "SHARE" Button. If it is clicked, the following piece of code is executed:

 /**
* Will only work with <category android:name="android.intent.category.DEFAULT" />
*/
private void shareText() {
// Create the text message with a string
Intent sendIntent = new Intent();
//sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "Lorem ipsum");
sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivity(sendIntent);
}
}

The runtime will show a chooser dialog to the user. Each Activity with an <intent-filter> with <category android:name="android.intent.category.DEFAULT"/> will be shown with the app title and the app's launcher icon. (While it is possible to have two Activitys with CATEGORY_DEFAULT in the same app, it is clear that this does not look good - it may be possible to tweak the text and/ or icon but that's definitely out of the scope of this question)

If I comment out the ACTION_SEND then the chooser dialog has the title "Complete action using" whereas if I set ACTION_SEND, the title is "Share with".

how [does] the system decide[...] about handling many apps with 'alternative' category especially without knowing the action name

My app configures its Intent by setting (or omitting) the action, the categories as well as the data type. The runtime always chooses Activitys which match all requirements of my Intent. This means, the other Activity may offer to handle data type "text/*" instead of just "text/plain" but if it only offers "image/*" then it won't be shown to the user.

What is the meaning of android.intent.action.MAIN?

android.intent.action.MAIN means that this activity is the entry point of the application, i.e. when you launch the application, this activity is created.

From the docs

ACTION_MAIN with category CATEGORY_HOME -- Launch the home screen.

Also,from here

Activity Action Start as a main entry point, does not expect to
receive data.

android.intent.category.DEFAULT is mainly used for implicit intents. If your activity wishes to be started by an implicit intent it should include this catetory in its filter.
If your Activity might be started by an implicit Intent when no specific category is assigned to it, its Intent filter should include this category.

android.intent.category.LAUNCHER

category -- Gives additional information about the action to execute.

CATEGORY_LAUNCHER means it should appear in the Launcher as a top-level application

See the docs..

  1. http://developer.android.com/reference/android/content/Intent.html
  2. http://developer.android.com/guide/topics/manifest/action-element.html

intent filter category android.intent.category.default Default Activity not found

you can use this,

 <activity android:name=".MainActivity"
android:launchMode="singleInstance"
android:stateNotNeeded="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</activity>

How does the category.DEFAULT intent filter work?

I figured it out :-)

AndroidManifest:

 <intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="file" android:pathPattern=".*mp3" android:mimeType="audio/mpeg" />
</intent-filter>

MainActivity:

    @Override
protected void onCreate(Bundle savedInstanceState)
{

if (Intent.ACTION_VIEW.equals(getIntent().getAction()))
{
File file = new File(getIntent().getData().getPath());

// do what you want with the file...
}


Related Topics



Leave a reply



Submit