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 * <pre> 4343d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * // In Activity#onCreateOptionsMenu 4443d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * public boolean onCreateOptionsMenu(Menu menu) { 4543d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * // Get the menu item. 4643d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * MenuItem menuItem = menu.findItem(R.id.my_menu_item); 4743d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * // Get the provider and hold onto it to set/change the share intent. 4843d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider(); 4943d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * // Set history different from the default before getting the action 5043d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * // view since a call to {@link MenuItem#getActionView() MenuItem.getActionView()} calls 5143d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * // {@link ActionProvider#onCreateActionView()} which uses the backing file name. Omit this 5243d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * // line if using the default share history file is desired. 5343d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * mShareActionProvider.setShareHistoryFileName("custom_share_history.xml"); 5443d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * . . . 5543d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * } 5651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * 5743d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * // Somewhere in the application. 5843d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * public void doShare(Intent shareIntent) { 5943d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * // When you want to share set the share intent. 6043d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * mShareActionProvider.setShareIntent(shareIntent); 6143d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * }</pre> 6251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <p> 6351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <strong>Note:</strong> While the sample snippet demonstrates how to use this provider 6451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * in the context of a menu item, the use of the provider is not limited to menu items. 6551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * </p> 6651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * 6751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * @see ActionProvider 6851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */ 6951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganovpublic class ShareActionProvider extends ActionProvider { 7051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 7151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov /** 728c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * Listener for the event of selecting a share target. 738c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov */ 748c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov public interface OnShareTargetSelectedListener { 758c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov 768c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov /** 778c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * Called when a share target has been selected. The client can 78b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov * decide whether to perform some action before the sharing is 79b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov * actually performed. 808c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * <p> 818c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * <strong>Note:</strong> Modifying the intent is not permitted and 828c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * any changes to the latter will be ignored. 838c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * </p> 84b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov * <p> 85b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov * <strong>Note:</strong> You should <strong>not</strong> handle the 86b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov * intent here. This callback aims to notify the client that a 87b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov * sharing is being performed, so the client can update the UI 88b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov * if necessary. 89b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov * </p> 908c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * 918c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * @param source The source of the notification. 928c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * @param intent The intent for launching the chosen share target. 93b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov * @return The return result is ignored. Always return false for consistency. 948c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov */ 958c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov public boolean onShareTargetSelected(ShareActionProvider source, Intent intent); 968c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov } 978c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov 988c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov /** 9976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * The default for the maximal number of activities shown in the sub-menu. 10076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov */ 10176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov private static final int DEFAULT_INITIAL_ACTIVITY_COUNT = 4; 10276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 10376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov /** 10476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * The the maximum number activities shown in the sub-menu. 10576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov */ 10676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov private int mMaxShownActivityCount = DEFAULT_INITIAL_ACTIVITY_COUNT; 10776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 10876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov /** 10976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * Listener for handling menu item clicks. 11076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov */ 11176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov private final ShareMenuItemOnMenuItemClickListener mOnMenuItemClickListener = 11276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov new ShareMenuItemOnMenuItemClickListener(); 11376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 11476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov /** 11551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * The default name for storing share history. 11651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */ 11751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov public static final String DEFAULT_SHARE_HISTORY_FILE_NAME = "share_history.xml"; 11851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 11976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov /** 12076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * Context for accessing resources. 12176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov */ 12251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private final Context mContext; 12376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 12476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov /** 12576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * The name of the file with share history data. 12676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov */ 12751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov private String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME; 12851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 1298c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov private OnShareTargetSelectedListener mOnShareTargetSelectedListener; 1308c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov 1318c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov private OnChooseActivityListener mOnChooseActivityListener; 1328c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov 13351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov /** 13451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Creates a new instance. 13551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * 13651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * @param context Context for accessing resources. 13751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */ 13851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov public ShareActionProvider(Context context) { 13951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov super(context); 14051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov mContext = context; 14151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 14251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 14351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov /** 1448c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * Sets a listener to be notified when a share target has been selected. 1458c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * The listener can optionally decide to handle the selection and 1468c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * not rely on the default behavior which is to launch the activity. 1478c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * <p> 1488c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * <strong>Note:</strong> If you choose the backing share history file 1498c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * you will still be notified in this callback. 1508c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * </p> 1518c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * @param listener The listener. 1528c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov */ 1538c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov public void setOnShareTargetSelectedListener(OnShareTargetSelectedListener listener) { 1548c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov mOnShareTargetSelectedListener = listener; 1558c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov setActivityChooserPolicyIfNeeded(); 1568c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov } 1578c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov 1588c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov /** 15951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * {@inheritDoc} 16051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */ 16151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov @Override 16251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov public View onCreateActionView() { 16376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov // Create the view and set its data model. 16451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); 16551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov ActivityChooserView activityChooserView = new ActivityChooserView(mContext); 16651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov activityChooserView.setActivityChooserModel(dataModel); 16776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 16876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov // Lookup and set the expand action icon. 16951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov TypedValue outTypedValue = new TypedValue(); 17051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true); 17151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId); 17251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov activityChooserView.setExpandActivityOverflowButtonDrawable(drawable); 173823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell activityChooserView.setProvider(this); 17476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 17570853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov // Set content description. 17670853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov activityChooserView.setDefaultActionButtonContentDescription( 17770853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov R.string.shareactionprovider_share_with_application); 17870853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov activityChooserView.setExpandActivityOverflowButtonContentDescription( 17970853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov R.string.shareactionprovider_share_with); 18070853772bd119339244a4fc8e020ad78495228beSvetoslav Ganov 18151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov return activityChooserView; 18251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 18351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 18476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov /** 18576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * {@inheritDoc} 18676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov */ 18751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov @Override 188961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell public boolean hasSubMenu() { 189961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell return true; 190961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell } 191961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell 19276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov /** 19376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * {@inheritDoc} 19476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov */ 195961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell @Override 196961dd11895ce72e59bca124ef5bea4e4c1183099Adam Powell public void onPrepareSubMenu(SubMenu subMenu) { 19776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov // Clear since the order of items may change. 19876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov subMenu.clear(); 19976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 20076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); 20176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov PackageManager packageManager = mContext.getPackageManager(); 20276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 20376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov final int expandedActivityCount = dataModel.getActivityCount(); 20476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov final int collapsedActivityCount = Math.min(expandedActivityCount, mMaxShownActivityCount); 20576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 20676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov // Populate the sub-menu with a sub set of the activities. 20776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov for (int i = 0; i < collapsedActivityCount; i++) { 20876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov ResolveInfo activity = dataModel.getActivity(i); 20976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov subMenu.add(0, i, i, activity.loadLabel(packageManager)) 21076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov .setIcon(activity.loadIcon(packageManager)) 21176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov .setOnMenuItemClickListener(mOnMenuItemClickListener); 21276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov } 21376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 214414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov if (collapsedActivityCount < expandedActivityCount) { 215414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov // Add a sub-menu for showing all activities as a list item. 216414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov SubMenu expandedSubMenu = subMenu.addSubMenu(Menu.NONE, collapsedActivityCount, 217414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov collapsedActivityCount, 218414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov mContext.getString(R.string.activity_chooser_view_see_all)); 219414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov for (int i = 0; i < expandedActivityCount; i++) { 220414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov ResolveInfo activity = dataModel.getActivity(i); 221414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov expandedSubMenu.add(0, i, i, activity.loadLabel(packageManager)) 222414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov .setIcon(activity.loadIcon(packageManager)) 223414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov .setOnMenuItemClickListener(mOnMenuItemClickListener); 224414051b8b1e31b69ca622d68f391245f1989500bSvetoslav Ganov } 22576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov } 22651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 22751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 22851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov /** 22951ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Sets the file name of a file for persisting the share history which 23051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * history will be used for ordering share targets. This file will be used 23151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * for all view created by {@link #onCreateActionView()}. Defaults to 23251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * {@link #DEFAULT_SHARE_HISTORY_FILE_NAME}. Set to <code>null</code> 23351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * if share history should not be persisted between sessions. 23451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <p> 23551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <strong>Note:</strong> The history file name can be set any time, however 23651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * only the action views created by {@link #onCreateActionView()} after setting 237775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * the file name will be backed by the provided file. Therefore, if you want to 238775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * use different history files for sharing specific types of content, every time 239775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * you change the history file {@link #setShareHistoryFileName(String)} you must 240775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * call {@link android.app.Activity#invalidateOptionsMenu()} to recreate the 241775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * action view. You should <strong>not</strong> call 242775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * {@link android.app.Activity#invalidateOptionsMenu()} from 24343d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * {@link android.app.Activity#onCreateOptionsMenu(Menu)}. 24443d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * </p> 24543d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * <pre> 246775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * private void doShare(Intent intent) { 247775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * if (IMAGE.equals(intent.getMimeType())) { 248775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * mShareActionProvider.setHistoryFileName(SHARE_IMAGE_HISTORY_FILE_NAME); 249775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * } else if (TEXT.equals(intent.getMimeType())) { 250775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * mShareActionProvider.setHistoryFileName(SHARE_TEXT_HISTORY_FILE_NAME); 251775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * } 252775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * mShareActionProvider.setIntent(intent); 253775bcac6bcdd04b6bffd23b5de0da4588a749337Svetoslav Ganov * invalidateOptionsMenu(); 25443d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * }</pre> 25551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * @param shareHistoryFile The share history file name. 25651ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */ 25751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov public void setShareHistoryFileName(String shareHistoryFile) { 25851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov mShareHistoryFileName = shareHistoryFile; 2598c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov setActivityChooserPolicyIfNeeded(); 26051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 26151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov 26251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov /** 26351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * Sets an intent with information about the share action. Here is a 26451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * sample for constructing a share intent: 26551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * <pre> 26643d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * Intent shareIntent = new Intent(Intent.ACTION_SEND); 26743d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * shareIntent.setType("image/*"); 26843d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * Uri uri = Uri.fromFile(new File(getFilesDir(), "foo.jpg")); 26943d5abbf0343a1761814ce1743e40a6688a72e4ckmccormick * shareIntent.putExtra(Intent.EXTRA_STREAM, uri.toString());</pre> 27051ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * 27151ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * @param shareIntent The share intent. 27251ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * 27351ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * @see Intent#ACTION_SEND 27451ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov * @see Intent#ACTION_SEND_MULTIPLE 27551ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov */ 27676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov public void setShareIntent(Intent shareIntent) { 27776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, 27876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov mShareHistoryFileName); 27976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov dataModel.setIntent(shareIntent); 28076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov } 28176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov 28276559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov /** 28376559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov * Reusable listener for handling share item clicks. 28476559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov */ 28576559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov private class ShareMenuItemOnMenuItemClickListener implements OnMenuItemClickListener { 28676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov @Override 28776559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov public boolean onMenuItemClick(MenuItem item) { 28876559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, 28976559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov mShareHistoryFileName); 29076559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov final int itemId = item.getItemId(); 29176559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov Intent launchIntent = dataModel.chooseActivity(itemId); 2928c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov if (launchIntent != null) { 293314419ccb9daa215c5148f59e5b60c696ef51385Adam Powell launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 2948c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov mContext.startActivity(launchIntent); 2958c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov } 29676559a65ad9d644f10beacf8895ceb217fdd0aebSvetoslav Ganov return true; 29751ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 29851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov } 2998c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov 3008c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov /** 3018c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * Set the activity chooser policy of the model backed by the current 3028c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * share history file if needed which is if there is a registered callback. 3038c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov */ 3048c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov private void setActivityChooserPolicyIfNeeded() { 3058c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov if (mOnShareTargetSelectedListener == null) { 3068c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov return; 3078c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov } 3088c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov if (mOnChooseActivityListener == null) { 3098c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov mOnChooseActivityListener = new ShareAcitivityChooserModelPolicy(); 3108c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov } 3118c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mShareHistoryFileName); 3128c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov dataModel.setOnChooseActivityListener(mOnChooseActivityListener); 3138c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov } 3148c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov 3158c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov /** 3168c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov * Policy that delegates to the {@link OnShareTargetSelectedListener}, if such. 3178c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov */ 3188c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov private class ShareAcitivityChooserModelPolicy implements OnChooseActivityListener { 3198c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov @Override 3208c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov public boolean onChooseActivity(ActivityChooserModel host, Intent intent) { 3218c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov if (mOnShareTargetSelectedListener != null) { 322b33eacdb791e569ebb429b55d7ab098973e19764Svetoslav Ganov mOnShareTargetSelectedListener.onShareTargetSelected( 3238c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov ShareActionProvider.this, intent); 3248c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov } 3258c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov return false; 3268c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov } 3278c6c79f0909ceabeb8abe1013648c31c7582b7adSvetoslav Ganov } 32851ac0e94a83cfccb5105aa14df1077729a5b4cccSvetoslav Ganov} 329