ShareActionProvider.java revision 70853772bd119339244a4fc8e020ad78495228be
151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov/*
251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Copyright (C) 2011 The Android Open Source Project
351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *
451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License");
551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * you may not use this file except in compliance with the License.
651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * You may obtain a copy of the License at
751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *
851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      http://www.apache.org/licenses/LICENSE-2.0
951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *
1051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Unless required by applicable law or agreed to in writing, software
1151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS,
1251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * See the License for the specific language governing permissions and
1451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * limitations under the License.
1551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */
1651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
1751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovpackage android.widget;
1851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
1951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.Context;
2051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.content.Intent;
2176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.content.pm.PackageManager;
2276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.content.pm.ResolveInfo;
2351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.graphics.drawable.Drawable;
2451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.util.TypedValue;
2551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.view.ActionProvider;
2676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.view.Menu;
2751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.view.MenuItem;
2876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport android.view.MenuItem.OnMenuItemClickListener;
29961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powellimport android.view.SubMenu;
3051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovimport android.view.View;
318c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganovimport android.widget.ActivityChooserModel.OnChooseActivityListener;
3251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
3376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganovimport com.android.internal.R;
3476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
3551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov/**
3651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * This is a provider for a share action. It is responsible for creating views
3776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * that enable data sharing and also to show a sub menu with sharing activities
3876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * if the hosting item is placed on the overflow menu.
3951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <p>
4051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Here is how to use the action provider with custom backing file in a {@link MenuItem}:
4151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </p>
4251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <p>
4351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <pre>
4451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <code>
4551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *  // In Activity#onCreateOptionsMenu
4651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *  public boolean onCreateOptionsMenu(Menu menu) {
4751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      // Get the menu item.
4851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      MenuItem menuItem = menu.findItem(R.id.my_menu_item);
4951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      // Get the provider and hold onto it to set/change the share intent.
5051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();
5151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      // Set history different from the default before getting the action
5251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      // view since a call to {@link MenuItem#getActionView() MenuItem.getActionView()} calls
5351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      // {@link ActionProvider#onCreateActionView()} which uses the backing file name. Omit this
5451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      // line if using the default share history file is desired.
5551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");
5651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      . . .
5751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *  }
5851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *
5951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *  // Somewhere in the application.
6051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *  public void doShare(Intent shareIntent) {
6151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *      // When you want to share set the share intent.
6276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov *      mShareActionProvider.setShareIntent(shareIntent);
6351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *  }
6451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </pre>
6551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </code>
6651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </p>
6751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <p>
6851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <strong>Note:</strong> While the sample snippet demonstrates how to use this provider
6951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * in the context of a menu item, the use of the provider is not limited to menu items.
7051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </p>
7151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov *
7251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * @see ActionProvider
7351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */
7451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovpublic class ShareActionProvider extends ActionProvider {
7551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
7651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
778c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * Listener for the event of selecting a share target.
788c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     */
798c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    public interface OnShareTargetSelectedListener {
808c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov
818c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        /**
828c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         * Called when a share target has been selected. The client can
838c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         * decide whether to handle the intent or rely on the default
848c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         * behavior which is launching it.
858c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         * <p>
868c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         * <strong>Note:</strong> Modifying the intent is not permitted and
878c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         *     any changes to the latter will be ignored.
888c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         * </p>
898c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         *
908c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         * @param source The source of the notification.
918c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         * @param intent The intent for launching the chosen share target.
928c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         * @return Whether the client has handled the intent.
938c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov         */
948c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        public boolean onShareTargetSelected(ShareActionProvider source, Intent intent);
958c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    }
968c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov
978c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    /**
9876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * The default for the maximal number of activities shown in the sub-menu.
9976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     */
10076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    private static final int DEFAULT_INITIAL_ACTIVITY_COUNT = 4;
10176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
10276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    /**
10376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * The the maximum number activities shown in the sub-menu.
10476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     */
10576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    private int mMaxShownActivityCount = DEFAULT_INITIAL_ACTIVITY_COUNT;
10676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
10776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    /**
10876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * Listener for handling menu item clicks.
10976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     */
11076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    private final ShareMenuItemOnMenuItemClickListener mOnMenuItemClickListener =
11176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        new ShareMenuItemOnMenuItemClickListener();
11276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
11376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    /**
11451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * The default name for storing share history.
11551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
11651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml";
11751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
11876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    /**
11976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * Context for accessing resources.
12076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     */
12151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private final Context mContext;
12276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
12376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    /**
12476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * The name of the file with share history data.
12576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     */
12651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    private String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME;
12751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
1288c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    private OnShareTargetSelectedListener mOnShareTargetSelectedListener;
1298c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov
1308c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    private OnChooseActivityListener mOnChooseActivityListener;
1318c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov
13251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
13351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Creates a new instance.
13451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
13551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param context Context for accessing resources.
13651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
13751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public ShareActionProvider(Context context) {
13851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        super(context);
13951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mContext = context;
14051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
14151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
14251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
1438c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * Sets a listener to be notified when a share target has been selected.
1448c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * The listener can optionally decide to handle the selection and
1458c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * not rely on the default behavior which is to launch the activity.
1468c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * <p>
1478c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * <strong>Note:</strong> If you choose the backing share history file
1488c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     *     you will still be notified in this callback.
1498c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * </p>
1508c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * @param listener The listener.
1518c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     */
1528c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    public void setOnShareTargetSelectedListener(OnShareTargetSelectedListener listener) {
1538c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        mOnShareTargetSelectedListener = listener;
1548c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        setActivityChooserPolicyIfNeeded();
1558c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    }
1568c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov
1578c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    /**
15851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * {@inheritDoc}
15951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
16051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
16151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public View onCreateActionView() {
16276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        // Create the view and set its data model.
16351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName);
16451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        ActivityChooserView activityChooserView = new ActivityChooserView(mContext);
16551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        activityChooserView.setActivityChooserModel(dataModel);
16676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
16776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        // Lookup and set the expand action icon.
16851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        TypedValue outTypedValue = new TypedValue();
16951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true);
17051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId);
17151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        activityChooserView.setExpandActivityOverflowButtonDrawable(drawable);
172823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell        activityChooserView.setProvider(this);
17376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
17470853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov        // Set content description.
17570853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov        activityChooserView.setDefaultActionButtonContentDescription(
17670853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov                R.string.shareactionprovider_share_with_application);
17770853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov        activityChooserView.setExpandActivityOverflowButtonContentDescription(
17870853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov                R.string.shareactionprovider_share_with);
17970853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov
18051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        return activityChooserView;
18151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
18251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
18376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    /**
18476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * {@inheritDoc}
18576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     */
18651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    @Override
187961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell    public boolean hasSubMenu() {
188961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell        return true;
189961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell    }
190961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell
19176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    /**
19276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * {@inheritDoc}
19376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     */
194961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell    @Override
195961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell    public void onPrepareSubMenu(SubMenu subMenu) {
19676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        // Clear since the order of items may change.
19776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        subMenu.clear();
19876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
19976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName);
20076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        PackageManager packageManager = mContext.getPackageManager();
20176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
20276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        final int expandedActivityCount = dataModel.getActivityCount();
20376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        final int collapsedActivityCount = Math.min(expandedActivityCount, mMaxShownActivityCount);
20476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
20576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        // Populate the sub-menu with a sub set of the activities.
20676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        for (int i = 0; i < collapsedActivityCount; i++) {
20776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            ResolveInfo activity = dataModel.getActivity(i);
20876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            subMenu.add(0, i, i, activity.loadLabel(packageManager))
20976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                .setIcon(activity.loadIcon(packageManager))
21076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                .setOnMenuItemClickListener(mOnMenuItemClickListener);
21176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        }
21276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
213414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov        if (collapsedActivityCount < expandedActivityCount) {
214414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov            // Add a sub-menu for showing all activities as a list item.
215414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov            SubMenu expandedSubMenu = subMenu.addSubMenu(Menu.NONE, collapsedActivityCount,
216414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov                    collapsedActivityCount,
217414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov                    mContext.getString(R.string.activity_chooser_view_see_all));
218414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov            for (int i = 0; i < expandedActivityCount; i++) {
219414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov                ResolveInfo activity = dataModel.getActivity(i);
220414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov                expandedSubMenu.add(0, i, i, activity.loadLabel(packageManager))
221414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov                    .setIcon(activity.loadIcon(packageManager))
222414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov                    .setOnMenuItemClickListener(mOnMenuItemClickListener);
223414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov            }
22476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        }
22551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
22651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
22751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
22851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Sets the file name of a file for persisting the share history which
22951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * history will be used for ordering share targets. This file will be used
23051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * for all view created by {@link #onCreateActionView()}. Defaults to
23151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * {@link #DEFAULT_SHARE_HISTORY_FILE_NAME}. Set to <code>null</code>
23251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * if share history should not be persisted between sessions.
23351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * <p>
23451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * <strong>Note:</strong> The history file name can be set any time, however
23551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * only the action views created by {@link #onCreateActionView()} after setting
23651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * the file name will be backed by the provided file.
23751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * <p>
23851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
23951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param shareHistoryFile The share history file name.
24051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
24151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    public void setShareHistoryFileName(String shareHistoryFile) {
24251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        mShareHistoryFileName = shareHistoryFile;
2438c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        setActivityChooserPolicyIfNeeded();
24451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
24551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov
24651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    /**
24751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * Sets an intent with information about the share action. Here is a
24851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * sample for constructing a share intent:
24951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * <p>
25051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * <pre>
25151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * <code>
25251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *  Intent shareIntent = new Intent(Intent.ACTION_SEND);
25351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *  shareIntent.setType("image/*");
25451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *  Uri uri = Uri.fromFile(new File(getFilesDir(), "foo.jpg"));
25551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *  shareIntent.putExtra(Intent.EXTRA_STREAM, uri.toString());
25651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * </pre>
25751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * </code>
25851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * </p>
25951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
26051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @param shareIntent The share intent.
26151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     *
26251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @see Intent#ACTION_SEND
26351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     * @see Intent#ACTION_SEND_MULTIPLE
26451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov     */
26576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    public void setShareIntent(Intent shareIntent) {
26676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        ActivityChooserModel dataModel = ActivityChooserModel.get(mContext,
26776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            mShareHistoryFileName);
26876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        dataModel.setIntent(shareIntent);
26976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    }
27076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov
27176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    /**
27276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     * Reusable listener for handling share item clicks.
27376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov     */
27476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov    private class ShareMenuItemOnMenuItemClickListener implements OnMenuItemClickListener {
27576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        @Override
27676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov        public boolean onMenuItemClick(MenuItem item) {
27776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            ActivityChooserModel dataModel = ActivityChooserModel.get(mContext,
27876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov                    mShareHistoryFileName);
27976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            final int itemId = item.getItemId();
28076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            Intent launchIntent = dataModel.chooseActivity(itemId);
2818c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            if (launchIntent != null) {
2828c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                mContext.startActivity(launchIntent);
2838c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            }
28476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov            return true;
28551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov        }
28651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov    }
2878c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov
2888c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    /**
2898c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * Set the activity chooser policy of the model backed by the current
2908c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * share history file if needed which is if there is a registered callback.
2918c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     */
2928c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    private void setActivityChooserPolicyIfNeeded() {
2938c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        if (mOnShareTargetSelectedListener == null) {
2948c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            return;
2958c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        }
2968c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        if (mOnChooseActivityListener == null) {
2978c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            mOnChooseActivityListener = new ShareAcitivityChooserModelPolicy();
2988c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        }
2998c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName);
3008c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        dataModel.setOnChooseActivityListener(mOnChooseActivityListener);
3018c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    }
3028c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov
3038c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    /**
3048c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     * Policy that delegates to the {@link OnShareTargetSelectedListener}, if such.
3058c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov     */
3068c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    private class ShareAcitivityChooserModelPolicy implements OnChooseActivityListener {
3078c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        @Override
3088c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        public boolean onChooseActivity(ActivityChooserModel host, Intent intent) {
3098c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            if (mOnShareTargetSelectedListener != null) {
3108c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                return mOnShareTargetSelectedListener.onShareTargetSelected(
3118c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov                        ShareActionProvider.this, intent);
3128c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            }
3138c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov            return false;
3148c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov        }
3158c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov    }
31651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov}
317