Какова цель CATEGORY_ALTERNATIVE? - PullRequest
       16

Какова цель CATEGORY_ALTERNATIVE?

0 голосов
/ 25 февраля 2020

Я читал документацию по CATEGORY_ALTERNATIVE и мне интересно, что именно подразумевается под "альтернативным действием для данных, которые пользователь просматривает в настоящее время".

Может кто-то предоставил больше примеров того, как эта категория используется?

Я нашел только некоторую информацию о создании Меню , а также некоторую цитату "Когда система предлагает пользователю выбор действий для выполнения задание, система перечисляет действия с фильтрами этой категории ". Но опять же, во втором случае - как это работает, если нам нужно включить CATEGORY_DEFAULT для того, чтобы действие получало неявные намерения.

1 Ответ

1 голос
/ 01 марта 2020

Предположим, вы используете приложение для обмена сообщениями, и друг прислал вам интересную ссылку. Тогда есть несколько вещей, которые вы можете сделать с ним:

  • открыть его в браузере
  • поделиться им с другим человеком
  • возможно сохранить его в приложении заметок
  • ...

Если вы воспользуетесь ссылкой как «данные, которые вы просматриваете в настоящее время», было бы хорошо, если бы мессенджер предложил вам выбрать соответствующее действие из пакета. альтернативных действий, которые в настоящее время доступны на вашем устройстве.

С Intent.CATEGORY_ALTERNATIVE и Menu.addIntentOptions(), платформа имеет способ для приложения, которое является первоначальным «владельцем» некоторого типа данных, предлагать пользователю доступ к дальнейшим действиям. Эти действия могут быть реализованы любым приложением, которое работает на устройстве и которое объявило о своей способности обрабатывать этот указанный тип данных c с помощью записи в Manifest.xml, более конкретно в теге <intent-filter>.

Давайте рассмотрим очень простой - если не очень реалистичный c - пример:

Мое приложение имеет значение String, которое оно отображает для пользователей. Альтернативными действиями могут быть

  • парсинг String на основе некоторого регулярного выражения
  • сортировка букв String
  • , преобразующих String, например, в прописные буквы
  • ...

Мое приложение будет иметь Activity или Fragment переопределение onCreateOptionsMenu() следующим образом (фрагмент кода для 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)
}

Activity s, которые могут обрабатывать данные String, объявят IntentFilter как дочерний тег своего тега в 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>

или

<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>

Тогда мое приложение покажет следующее всплывающее меню, когда пользователь нажмет на значок переполнения ...

popup menu with

. .. и среда выполнения перейдет непосредственно к выбранному Activity. Там текст можно получить следующим образом:

 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);
}

Обратите внимание, что точный код для извлечения данных зависит от типа данных, как и в случае с «обычными» Intent s без <category> пометить вообще или с помощью <category android:name="android.intent.category.DEFAULT" /> в <intent-filter>.

как это работает, если нам нужно включить CATEGORY_DEFAULT для того, чтобы действие получало неявные намерения

Вам нужно <category android:name="android.intent.category.DEFAULT"/> в <intent-filter> из Activity, если вы хотите, чтобы оно появилось в диалоге выбора. Кстати, Activity может иметь несколько <intent-filter> тегов

Давайте изменим пример: мое приложение также имеет "SHARE" Button. При щелчке выполняется следующий фрагмент кода:

 /**
 * 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);
    }
}

Во время выполнения пользователю будет показан диалог выбора. Каждый Activity с <intent-filter> с <category android:name="android.intent.category.DEFAULT"/> будет отображаться с названием приложения и значком запуска приложения. (Хотя можно иметь два Activity с CATEGORY_DEFAULT в одном приложении, очевидно, что это выглядит не очень хорошо - возможно, можно настроить текст и / или значок, но это определенно выходит за рамки этого вопроса)

Если я закомментирую ACTION_SEND, тогда диалог выбора будет иметь заголовок «Выполнить действие, используя», тогда как если я установлю ACTION_SEND, заголовок будет «Поделиться с».

как система [...] принимает решение об обработке многих приложений с «альтернативной» категорией, особенно без знания имени действия

Мое приложение настраивает Intent, устанавливая (или опуская) действие, категории, а также тип данных. Время выполнения всегда выбирает Activity s, которые соответствуют всем требованиям моего Intent. Это означает, что другой Activity может предложить обрабатывать тип данных "text / *" вместо просто "text / plain", но если он предлагает только "image / *", то он не будет показан пользователю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...