Как отключить историю общего доступа при использовании ShareActionProvider?

Новый ShareActionProvider, доступный в Android 4.0 (или в более ранних версиях, если вы используете ActionBarSherlock), имеет функцию, в которой последний использованный элемент отображается на панели действий. Есть ли способ отключить это?


person Quentamia    schedule 22.05.2012    source источник


Ответы (7)


Для этого нет API. Однако класс действительно прост, и вы можете очень легко создать свою собственную версию ShareActionProvider, не сохраняющую историю. Вам просто нужно будет определить порядок сортировки возможных целей, используя некоторые другие способы упорядочения (например, в алфавитном порядке).

person Jake Wharton    schedule 22.05.2012
comment
Дело в том, что я хочу сохранить историю, но ТОЛЬКО в выпадающем меню. Добавление дополнительного значка раздражает, и он больше не помещается на панели. - person phreakhead; 23.05.2013
comment
@phreakhead Взгляните на мой ответ - stackoverflow.com/a/17290249/1446466. Это поможет вам. - person Sean; 25.06.2013

Для меня лучшее решение, позволяющее избежать значка истории, — не использовать ShareActionProvider, вместо этого создайте его как любое другое действие:

 <item 
    android:id="@+id/menu_action_share"
    android:showAsAction="ifRoom" 
    android:icon="@drawable/ic_action_share"
    android:title="@string/share"/>   

в меню/activity_actions.xml поместите элемент со значком ic_action_share...

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_actions, menu);
    return super.onCreateOptionsMenu(menu);
 }

Раздувать меню нормально...

private void actionShare(){
     Intent i = new Intent(Intent.ACTION_SEND);
     i.setType("text/plain");
     i.putExtra(Intent.EXTRA_SUBJECT, "my string");
     i.putExtra(Intent.EXTRA_TEXT, "another string");
     startActivity(i); 
     //Or like above will always display the chooser
     //startActivity(Intent.createChooser(i, getResources().getText(R.string.share))); 
 }

Создайте метод с намерением ACTION_SEND

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_item_share:
            actionShare();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

И, наконец, вызовите этот метод из onOptionsItemSelected.

подробнее ->Отправка простых данных в другие приложения

person Nissar    schedule 09.03.2014
comment
Это даже лучше, чем традиционный ActionProvider. - person Tsuharesu; 05.06.2015
comment
Это лучше, чем родное ShareActionProvider, потому что оно отображает не историю, а все приложения, которыми можно поделиться. - person TruMan1; 03.07.2015

Запустите активность самостоятельно:

shareActionProvider.setShareIntent(intent);
shareActionProvider.setOnShareTargetSelectedListener(this);

@Override
public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
    // start activity ourself to prevent search history
    context.startActivity(intent);
    return true;
}

Тогда ShareActionProvider не добавит выбранное действие в историю общего доступа.

person svenmeier    schedule 01.06.2012
comment
Я не уверен, как это работает для других. При использовании библиотеки совместимости v7 он по-прежнему будет падать с ошибкой java.lang.IllegalStateException: No preceding call to #readHistoricalData. Кроме того, в документации это четко указано для onShareTargetSelected: Примечание. Здесь не следует обрабатывать намерение. Этот обратный вызов предназначен для уведомления клиента о том, что выполняется совместное использование, чтобы клиент мог при необходимости обновить пользовательский интерфейс. Возвращаемый результат игнорируется. Всегда возвращайте false для согласованности. - person Felix; 04.11.2013
comment
Не забудьте очистить данные вашего приложения в устройстве для тестирования. - person Julio Rodrigues; 14.11.2013
comment
Комментарий @Felix действителен. Врачи говорят, что этого делать нельзя. В итоге у меня сработало 2 намерения. - person loeschg; 04.09.2014

Я создал собственную версию ShareActionProvider (и поддерживающих классов), вы можете скопировать их в свой проект (https://gist.github.com/saulpower/10557956). Это не только добавляет возможность отключить историю, но и фильтровать приложения, с которыми вы хотели бы поделиться (если вы знаете имя пакета).

private final String[] INTENT_FILTER = new String[] {
        "com.twitter.android",
        "com.facebook.katana"
};

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.journal_entry_menu, menu);

    // Set up ShareActionProvider's default share intent
    MenuItem shareItem = menu.findItem(R.id.action_share);

    if (shareItem instanceof SupportMenuItem) {
        mShareActionProvider = new ShareActionProvider(this);
        mShareActionProvider.setShareIntent(ShareUtils.share(mJournalEntry));
        mShareActionProvider.setIntentFilter(Arrays.asList(INTENT_FILTER));
        mShareActionProvider.setShowHistory(false);
        ((SupportMenuItem) shareItem).setSupportActionProvider(mShareActionProvider);
    }

    return super.onCreateOptionsMenu(menu);
}
person saulpower    schedule 12.04.2014

Пояснение: это не «последний использованный», а «наиболее часто используемый» период времени в скользящем окне.

Если вы предпочитаете не использовать историю, то перед созданием своих представлений вызовите

yourShareActionProvider.setShareHistoryFileName(null);

Описание этого метода из официальных документов. (выделено мной):

Устанавливает имя файла для сохранения истории общего доступа, история которого будет использоваться для упорядочивания целей общего доступа. Этот файл будет использоваться для всех представлений, созданных с помощью onCreateActionView(). По умолчанию DEFAULT_SHARE_HISTORY_FILE_NAME. Установите значение null, если история общего доступа не должна сохраняться между сеансами.

РЕДАКТИРОВАТЬ: я должен уточнить. Элемент «наиболее часто используемый» не будет отображаться, если нет истории, поэтому в настоящее время это единственный способ удалить эту кнопку.

person Alexander Lucas    schedule 22.05.2012
comment
Можете ли вы быть более конкретным, что вы подразумеваете под не сработало? - person Alexander Lucas; 25.05.2012
comment
У меня такое же поведение. Обмен все еще работал ... что не должно быть возможно. - person Quentamia; 26.05.2012
comment
Когда я вызываю setShareHistoryFileName(null), действие общего доступа больше ничего не делает :( - person svenmeier; 01.06.2012
comment
Когда я устанавливаю нулевое имя файла на Nexus 7 под управлением 4.2.1, кнопка действия по умолчанию правильно исчезает. Однако попытка выбрать действие в меню общего доступа приводит к сбою с java.lang.IllegalStateException: No preceding call to #readHistoricalData. - person dokkaebi; 18.12.2012
comment
Это вызывает сбой в моей системе - person bodagetta; 07.07.2015
comment
Вызывает сбой после выбора общего приложения: НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: main java.lang.IllegalStateException: нет предшествующего вызова #readHistoricalData в android.support.v7.internal.widget.ActivityChooserModel (Samsung Galaxy Nexus 4.3) - person Devrim; 10.07.2015

Хотя сегодня прошло 2 года, я хотел бы поделиться своим опытом, когда я создал собственный класс ShareActionProvider и добавил эту строку chooserView.getDataModel().setHistoryMaxSize(0); внутри onCreateActionView(), которая сделала всю магию для меня! .. Я протестировал его на устройстве Lollipop и на устройстве эмулятора API 16, и он отлично работает. вот мой пользовательский класс:

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.internal.widget.ActivityChooserView;
import android.support.v7.widget.ShareActionProvider;
import android.view.View;


public class MyShareActionProvider extends ShareActionProvider {
    /**
     * Creates a new instance.
     *
     * @param context Context for accessing resources.
     */
    public MyShareActionProvider(Context context) {
        super(context);
    }

    @Override
    public View onCreateActionView() {
        ActivityChooserView chooserView = (ActivityChooserView) super.onCreateActionView();
        Drawable icon;
        if (Build.VERSION.SDK_INT >= 21) {
            icon = getContext().getDrawable(R.drawable.share_icon);
        }else{
            icon = getContext().getResources().getDrawable(R.drawable.share_icon);
        }
        chooserView.setExpandActivityOverflowButtonDrawable(icon);
        chooserView.getDataModel().setHistoryMaxSize(0);
        return chooserView;
    }

}
person Yasser Khayyal    schedule 20.04.2016
comment
Красиво, но в androidx метод setHistoryMaxSize() недоступен... :( - person l33t; 27.01.2020
comment
@ l33t Вы правы .. Я обнаружил это еще раньше, поскольку библиотека appcompat v.23 - person Yasser Khayyal; 06.05.2020

добавьте такой код:

    private void addShareSelectedListener() {
    if (null == mShareActionProvider) return;
    OnShareTargetSelectedListener listener = new OnShareTargetSelectedListener() {
        public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
            mContex.startActivity(intent);
            return true;
        }
    };

//Set to null if share history should not be persisted between sessions.
    mShareActionProvider.setShareHistoryFileName(null);
    mShareActionProvider.setOnShareTargetSelectedListener(listener);

}
person Seven    schedule 26.11.2012