27

The new ShareActionProvider available in Android 4.0 (or in earlier versions if you're using ActionBarSherlock) has a feature where the last used item is displayed in the action bar. Is there anyway to turn this off?

Quentamia
  • 3,244
  • 3
  • 33
  • 42

8 Answers8

21

For me, the best solution for avoid the history icon is don't use ShareActionProvider, instead of it, create it as any other action:

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

at the menu/activity_actions.xml put a item with the ic_action_share icon...

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

Inflate the menu normally...

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

Create a method with an ACTION_SEND intent

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

And finally call to this method from onOptionsItemSelected

more info ->Sending Simple Data to Other Apps

Nissar
  • 2,360
  • 2
  • 13
  • 12
13

Start the share activity by yourself:

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

Then the ShareActionProvider will not add the chosen activity to the share history.

svenmeier
  • 5,681
  • 17
  • 22
  • 8
    I'm not sure how this works for others. When using the v7 compat library, it will still crash with `java.lang.IllegalStateException: No preceding call to #readHistoricalData`. Furthermore, the documentation clearly states this for `onShareTargetSelected`: "Note: You should not handle the intent here. This callback aims to notify the client that a sharing is being performed, so the client can update the UI if necessary. The return result is ignored. Always return false for consistency." – Felix Nov 04 '13 at 12:11
  • Remember to clean the data of your application in the device for testing. – Julio Rodrigues Nov 13 '13 at 21:02
  • @Felix's comment is valid. Docs say this shouldn't be done. I end up with 2 intents fired. – loeschg Sep 03 '14 at 21:00
4

I created my own version of the ShareActionProvider (and supporting classes), you can copy them into your project (https://gist.github.com/saulpower/10557956). This not only adds the ability to turn off history, but also to filter the apps you would like to share with (if you know the package name).

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);
}
saulpower
  • 1,258
  • 1
  • 10
  • 13
3

There is no API to do this. However, the class is really simple and you could very easily create your own version of ShareActionProvider that did not keep a history. You would just have to determine the sort order of the possible targets using some other means of ordering (e.g., alphabetically).

Jake Wharton
  • 75,598
  • 23
  • 223
  • 230
  • 6
    The thing is, I want to keep the history, but ONLY in the dropdown menu. Adding the extra icon is annoying and it doesn't fit in the bar anymore. – phreakhead May 22 '13 at 23:03
  • 2
    @phreakhead Take a look at my answer - http://stackoverflow.com/a/17290249/1446466 . It will help your need. – Sean Jun 25 '13 at 06:09
1

Point of clarification: It's not the "last used", it's "most often used", across a sliding window period of time.

If you prefer not to use history, then before creating your views, call

yourShareActionProvider.setShareHistoryFileName(null);

Description of this method, from the official docs (emphasis mine):

Sets the file name of a file for persisting the share history which history will be used for ordering share targets. This file will be used for all view created by onCreateActionView(). Defaults to DEFAULT_SHARE_HISTORY_FILE_NAME. Set to null if share history should not be persisted between sessions.

EDIT: I should clarify — The "most often used" item won't show up if there's no history, so this is currently the only way of removing that button.

Alexander Lucas
  • 22,171
  • 3
  • 46
  • 43
  • Can you be more specific, in what you mean by "didn't work" ? – Alexander Lucas May 25 '12 at 19:58
  • I got the same behavior. The sharing was still working..which shouldn't be possible. – Quentamia May 25 '12 at 20:43
  • When I call setShareHistoryFileName(null), the share action doesn't do anything any longer :( – svenmeier Jun 01 '12 at 15:37
  • 24
    When I set the filename null on a Nexus 7 running 4.2.1, the default action button correctly disappears. However, attempting to choose an action from the share menu yields a crash with `java.lang.IllegalStateException: No preceding call to #readHistoricalData`. – dokkaebi Dec 18 '12 at 02:48
  • 1
    This causes a crash on my system – bodagetta Jul 07 '15 at 00:52
  • Causes crash after selecting a share app: FATAL EXCEPTION: main java.lang.IllegalStateException: No preceding call to #readHistoricalData at android.support.v7.internal.widget.ActivityChooserModel (Samsung Galaxy Nexus 4.3) – Devrim Jul 09 '15 at 23:17
0

Although It's been 2 years ago today but I'd like to share my experience as I made a custom ShareActionProvider class and add this line chooserView.getDataModel().setHistoryMaxSize(0); inside onCreateActionView() which did all the magic for me ! .. I tested it on Lollipop device and on API 16 emulator device and it works perfectly. here is my custom class :

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

}
-1

add the code like this:

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

}
Seven
  • 177
  • 1
  • 5
-1
    getSupportMenuInflater().inflate(R.menu.share_action_provider, menu);

    // Set file with share history to the provider and set the share intent.
    MenuItem actionItem = menu.findItem(R.id.menu_item_share_action_provider_action_bar);
    ShareActionProvider actionProvider = (ShareActionProvider) actionItem.getActionProvider();
    ***actionProvider.setShareHistoryFileName(null);
    OnShareTargetSelectedListener listener = new OnShareTargetSelectedListener() {
        public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
            startActivity(intent);
            return true;
        }
    };
    actionProvider.setOnShareTargetSelectedListener(listener);***
jiangws88
  • 69
  • 1
  • 2