Устройства с Android + MIUI и setCustomSelectionActionModeCallback

Я пытаюсь создать меню пользовательского выбора, но он не работает на устройстве с rom MIUI и Android 6. Результатом является общее меню с элементами "копировать" и "выбирать все". На других устройствах и симуляторах под чистым Android он работает отлично. Код

       textViewTop.setCustomSelectionActionModeCallback(new android.view.ActionMode.Callback() {
        @Override
        public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {

            Log.d(LOG_TAG, "onCreateActionMode");

            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            Log.d(LOG_TAG, "onPrepareActionMode");
            menu.clear();

            int quote_quick = R.drawable.ic_desktop_mac_black_24dp;
            int quote_add = R.drawable.ic_computer_black_24dp;
            int copy = R.drawable.ic_devices_other_black_24dp;

            menu.add(Menu.NONE, QUOTE_START, 3, "").setIcon(quote_quick).setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
            menu.add(Menu.NONE, QUOTE_ADD, 2, "").setIcon(quote_add).setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
            menu.add(Menu.NONE, CUSTOM_COPY, 1, "").setIcon(copy).setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {

        }
    });

Ответ 1

Просто некоторые мысли. Что делать, если вы берете пункт меню onCreateOptionsMenu и меняете его.

Как это:

public boolean onCreateOptionsMenu(final Menu menu) {
  getSupportMenuInflater().inflate(R.menu.main, menu);
  new Handler().post( -> {
      final View menuItemView = findViewById(R.id.menu_action_item);
      ...
  }
}

Ответ 2

Поэтому я решил обходное решение, но это имеет смысл только в том случае, если вам абсолютно необходимо, чтобы он работал на устройствах MIUI. Это обычно немного неудобно:

Я заметил, что приложение Wikipedia имеет пользовательские действия, работающие на устройстве Xiaomi, и, просмотрев код, который я обнаружил, он отлично работает, когда тексты выбраны в WebView. В основном вы можете использовать WebView и переопределять onActionModeStarted в своей деятельности

Acivity:

String html = "<!DOCTYPE html>\n" +
        "<html>\n" +
        "<head>\n" +
        "</head>\n" +
        "<body>\n" +
        "\n" +
        "<h1>WebView text</h1>\n" +
        "\n" +
        "</body>\n" +
        "</html>\n";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    WebView webView = findViewById(R.id.web_view);
    webView.setWebViewClient(new WebViewClient());
    webView.loadData(html, "text/html", "UTF-8");
}

@Override
public void onActionModeStarted(ActionMode mode) {
    super.onActionModeStarted(mode);
        Menu menu = mode.getMenu();
        menu.clear();
        mode.getMenuInflater().inflate(R.menu.menu_text_select, menu);
}

Меню:

<item android:id="@+id/id1"
      android:title="miui"
      app:showAsAction="ifRoom" />

<item android:id="@+id/id2"
      android:title="has"
      app:showAsAction="ifRoom" />

<item android:id="@+id/id3"
      android:title="bugs"
      app:showAsAction="ifRoom" />

<item android:id="@+id/id4"
    android:title="D:"
    app:showAsAction="ifRoom" />

Результат: result

Ответ 3

Согласно https://developer.android.com/guide/topics/ui/menus#CAB, вам нужно создать меню в onCreateActionMode.

Я сделал это так (в котлин):

    val actionModeCallbackA = object : ActionMode.Callback {
    override fun onActionItemClicked(mode: ActionMode?, p1: MenuItem?): Boolean {
        Log.wtf("ACTION MODE", "onActionItemClicked")
        actionModeB = startActionMode(actionModeCallbackB)
        return true
    }

    override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
        Log.wtf("ACTION MODE", "onCreateActionMode")
        val inflater = mode?.getMenuInflater()
        inflater?.inflate(R.menu.context_menu, menu)
        return true
    }

    override fun onPrepareActionMode(p0: ActionMode?, p1: Menu?): Boolean {
        Log.wtf("ACTION MODE", "onPrepareActionMode")
        return false
    }

    override fun onDestroyActionMode(p0: ActionMode?) {
        Log.wtf("ACTION MODE", "onDestroyActionMode")
            actionModeA = null
    }
}