1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.chrome.browser.share;
7 import android.app.Activity;
8 import android.app.AlertDialog;
9 import android.content.ComponentName;
10 import android.content.Context;
11 import android.content.Intent;
12 import android.content.SharedPreferences;
13 import android.content.pm.ActivityInfo;
14 import android.content.pm.ApplicationInfo;
15 import android.content.pm.PackageManager;
16 import android.content.pm.PackageManager.NameNotFoundException;
17 import android.content.pm.ResolveInfo;
18 import android.graphics.Bitmap;
19 import android.graphics.drawable.Drawable;
20 import android.preference.PreferenceManager;
21 import android.view.MenuItem;
22 import android.view.View;
23 import android.widget.AdapterView;
24 import android.widget.AdapterView.OnItemClickListener;
26 import org.chromium.chrome.R;
28 import java.util.Collections;
29 import java.util.List;
32 * A helper class that helps to start an intent to share titles and URLs.
34 public class ShareHelper {
36 private static final String PACKAGE_NAME_KEY = "last_shared_package_name";
37 private static final String CLASS_NAME_KEY = "last_shared_class_name";
40 * Intent extra for sharing screenshots via the Share intent.
42 * Copied from {@link android.provider.Browser} as it is marked as {@literal @hide}.
44 private static final String EXTRA_SHARE_SCREENSHOT = "share_screenshot";
46 private ShareHelper() {}
49 * Creates and shows a share intent picker dialog or starts a share intent directly with the
50 * activity that was most recently used to share based on shareDirectly value.
52 * @param shareDirectly Whether it should share directly with the activity that was most
53 * recently used to share.
54 * @param activity Activity that is used to access package manager.
55 * @param title Title of the page to be shared.
56 * @param url URL of the page to be shared.
57 * @param screenshot Screenshot of the page to be shared.
59 public static void share(boolean shareDirectly, Activity activity, String title, String url,
62 shareWithLastUsed(activity, title, url, screenshot);
64 showShareDialog(activity, title, url, screenshot);
69 * Creates and shows a share intent picker dialog.
71 * @param activity Activity that is used to access package manager.
72 * @param title Title of the page to be shared.
73 * @param url URL of the page to be shared.
74 * @param screenshot Screenshot of the page to be shared.
76 private static void showShareDialog(final Activity activity, final String title,
77 final String url, final Bitmap screenshot) {
78 Intent intent = getShareIntent(title, url, screenshot);
79 PackageManager manager = activity.getPackageManager();
80 List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent, 0);
81 assert resolveInfoList.size() > 0;
82 if (resolveInfoList.size() == 0) return;
83 Collections.sort(resolveInfoList, new ResolveInfo.DisplayNameComparator(manager));
85 final ShareDialogAdapter adapter =
86 new ShareDialogAdapter(activity, manager, resolveInfoList);
87 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
88 builder.setTitle(activity.getString(R.string.share_link_chooser_title));
89 builder.setAdapter(adapter, null);
91 final AlertDialog dialog = builder.create();
93 dialog.getListView().setOnItemClickListener(new OnItemClickListener() {
95 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
96 ResolveInfo info = adapter.getItem(position);
97 ActivityInfo ai = info.activityInfo;
98 ComponentName component =
99 new ComponentName(ai.applicationInfo.packageName, ai.name);
100 setLastShareComponentName(activity, component);
101 Intent intent = getDirectShareIntentForComponent(title, url, screenshot, component);
102 activity.startActivity(intent);
109 * Starts a share intent with the activity that was most recently used to share.
110 * If there is no most recently used activity, it does nothing.
111 * @param activity Activity that is used to start the share intent.
112 * @param title Title of the page to be shared.
113 * @param url URL of the page to be shared.
114 * @param screenshot Screenshot of the page to be shared.
116 private static void shareWithLastUsed(
117 Activity activity, String title, String url, Bitmap screenshot) {
118 ComponentName component = getLastShareComponentName(activity);
119 if (component == null) return;
120 Intent intent = getDirectShareIntentForComponent(title, url, screenshot, component);
121 activity.startActivity(intent);
125 * Set the icon and the title for the menu item used for direct share.
127 * @param activity Activity that is used to access the package manager.
128 * @param item The menu item that is used for direct share
130 public static void configureDirectShareMenuItem(Activity activity, MenuItem item) {
131 Drawable directShareIcon = null;
132 CharSequence directShareTitle = null;
134 ComponentName component = getLastShareComponentName(activity);
135 if (component != null) {
137 directShareIcon = activity.getPackageManager().getActivityIcon(component);
138 ApplicationInfo ai = activity.getPackageManager().getApplicationInfo(
139 component.getPackageName(), 0);
140 directShareTitle = activity.getPackageManager().getApplicationLabel(ai);
141 } catch (NameNotFoundException exception) {
142 // Use the default null values.
146 item.setIcon(directShareIcon);
147 if (directShareTitle != null) {
148 item.setTitle(activity.getString(R.string.accessibility_menu_share_via,
153 private static Intent getShareIntent(String title, String url, Bitmap screenshot) {
154 Intent intent = new Intent(Intent.ACTION_SEND);
155 intent.setType("text/plain");
156 intent.putExtra(Intent.EXTRA_SUBJECT, title);
157 intent.putExtra(Intent.EXTRA_TEXT, url);
158 if (screenshot != null) intent.putExtra(EXTRA_SHARE_SCREENSHOT, screenshot);
162 private static Intent getDirectShareIntentForComponent(String title, String url,
163 Bitmap screenshot, ComponentName component) {
164 Intent intent = getShareIntent(title, url, screenshot);
165 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
166 | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
167 intent.setComponent(component);
171 private static ComponentName getLastShareComponentName(Context context) {
172 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
173 String packageName = preferences.getString(PACKAGE_NAME_KEY, null);
174 String className = preferences.getString(CLASS_NAME_KEY, null);
175 if (packageName == null || className == null) return null;
176 return new ComponentName(packageName, className);
179 private static void setLastShareComponentName(Context context, ComponentName component) {
180 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
181 SharedPreferences.Editor editor = preferences.edit();
182 editor.putString(PACKAGE_NAME_KEY, component.getPackageName());
183 editor.putString(CLASS_NAME_KEY, component.getClassName());