1ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell/*
2ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * Copyright (C) 2011 The Android Open Source Project
3ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell *
4ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * you may not use this file except in compliance with the License.
6ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * You may obtain a copy of the License at
7ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell *
8ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell *
10ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * Unless required by applicable law or agreed to in writing, software
11ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * See the License for the specific language governing permissions and
14ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * limitations under the License.
15ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell */
16ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
17ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellpackage android.support.v4.app;
18ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
19ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.app.Activity;
20ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.content.ComponentName;
21ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.content.Intent;
22ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.content.pm.PackageManager;
23ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.content.pm.PackageManager.NameNotFoundException;
24ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.graphics.drawable.Drawable;
25ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.net.Uri;
26ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.os.Build;
2737c1509886a7897163f70f4645c08ddf0b41632dAdam Powellimport android.support.v4.content.IntentCompat;
28ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.support.v4.view.MenuItemCompat;
2937c1509886a7897163f70f4645c08ddf0b41632dAdam Powellimport android.text.Html;
3037c1509886a7897163f70f4645c08ddf0b41632dAdam Powellimport android.text.Spanned;
31ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.util.Log;
32ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.view.Menu;
33ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport android.view.MenuItem;
34ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
35ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellimport java.util.ArrayList;
36ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
37ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell/**
38ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * Extra helper functionality for sharing data between activities.
39ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell *
40ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * ShareCompat provides functionality to extend the {@link Intent#ACTION_SEND}/
41ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * {@link Intent#ACTION_SEND_MULTIPLE} protocol and support retrieving more info
42ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * about the activity that invoked a social sharing action.
43ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell *
44ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * {@link IntentBuilder} provides helper functions for constructing a sharing
45ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * intent that always includes data about the calling activity and app.
46ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * This lets the called activity provide attribution for the app that shared
47ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * content. Constructing an intent this way can be done in a method-chaining style.
48ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * To obtain an IntentBuilder with info about your calling activity, use the static
49ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * method {@link IntentBuilder#from(Activity)}.
50ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell *
51ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * {@link IntentReader} provides helper functions for parsing the defined extras
52ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * within an {@link Intent#ACTION_SEND} or {@link Intent#ACTION_SEND_MULTIPLE} intent
53ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * used to launch an activity. You can also obtain a Drawable for the caller's
54ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * application icon and the application's localized label (the app's human-readable name).
55ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * Social apps that enable sharing content are encouraged to use this information
56ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell * to call out the app that the content was shared from.
57ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell */
58ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powellpublic class ShareCompat {
59ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    /**
60ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Intent extra that stores the name of the calling package for an ACTION_SEND intent.
61ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * When an activity is started using startActivityForResult this is redundant info.
62ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * (It is also provided by {@link Activity#getCallingPackage()}.)
63ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
64ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Instead of using this constant directly, consider using {@link #getCallingPackage(Activity)}
65ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * or {@link IntentReader#getCallingPackage()}.
66ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     */
67ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    public static final String EXTRA_CALLING_PACKAGE =
68ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            "android.support.v4.app.EXTRA_CALLING_PACKAGE";
69ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
70ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    /**
71ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Intent extra that stores the {@link ComponentName} of the calling activity for
72ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * an ACTION_SEND intent.
73ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     */
74ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    public static final String EXTRA_CALLING_ACTIVITY =
75ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
76ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
77ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    /**
78ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Compatibility shims for sharing operations
79ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     */
80ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    interface ShareCompatImpl {
81ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        void configureMenuItem(MenuItem item, IntentBuilder shareIntent);
8237c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        String escapeHtml(CharSequence text);
83ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
84ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
85ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    static class ShareCompatImplBase implements ShareCompatImpl {
86ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public void configureMenuItem(MenuItem item, IntentBuilder shareIntent) {
87ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            item.setIntent(shareIntent.createChooserIntent());
88ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
8937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell
9037c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        public String escapeHtml(CharSequence text) {
9137c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            StringBuilder out = new StringBuilder();
9237c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            withinStyle(out, text, 0, text.length());
9337c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            return out.toString();
9437c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        }
9537c1509886a7897163f70f4645c08ddf0b41632dAdam Powell
9637c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        private static void withinStyle(StringBuilder out, CharSequence text,
9737c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                int start, int end) {
9837c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            for (int i = start; i < end; i++) {
9937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                char c = text.charAt(i);
10037c1509886a7897163f70f4645c08ddf0b41632dAdam Powell
10137c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                if (c == '<') {
10237c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    out.append("&lt;");
10337c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                } else if (c == '>') {
10437c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    out.append("&gt;");
10537c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                } else if (c == '&') {
10637c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    out.append("&amp;");
10737c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                } else if (c > 0x7E || c < ' ') {
10837c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    out.append("&#" + ((int) c) + ";");
10937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                } else if (c == ' ') {
11037c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    while (i + 1 < end && text.charAt(i + 1) == ' ') {
11137c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                        out.append("&nbsp;");
11237c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                        i++;
11337c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    }
11437c1509886a7897163f70f4645c08ddf0b41632dAdam Powell
11537c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    out.append(' ');
11637c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                } else {
11737c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    out.append(c);
11837c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                }
11937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            }
12037c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        }
121ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
122ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
12337c1509886a7897163f70f4645c08ddf0b41632dAdam Powell    static class ShareCompatImplICS extends ShareCompatImplBase {
124ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public void configureMenuItem(MenuItem item, IntentBuilder shareIntent) {
125ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            ShareCompatICS.configureMenuItem(item, shareIntent.getActivity(),
126ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                    shareIntent.getIntent());
12766957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell            if (shouldAddChooserIntent(item)) {
12866957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell                item.setIntent(shareIntent.createChooserIntent());
12966957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell            }
13066957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell        }
13166957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell
13266957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell        boolean shouldAddChooserIntent(MenuItem item) {
13366957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell            return !item.hasSubMenu();
134ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
135ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
136ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
13737c1509886a7897163f70f4645c08ddf0b41632dAdam Powell    static class ShareCompatImplJB extends ShareCompatImplICS {
13837c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        public String escapeHtml(CharSequence html) {
13937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            return ShareCompatJB.escapeHtml(html);
14037c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        }
14166957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell
14266957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell        @Override
14366957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell        boolean shouldAddChooserIntent(MenuItem item) {
14466957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell            return false;
14566957a1e997dde850701ee96a3aa7b7c1444d67fAdam Powell        }
14637c1509886a7897163f70f4645c08ddf0b41632dAdam Powell    }
14737c1509886a7897163f70f4645c08ddf0b41632dAdam Powell
148ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    private static ShareCompatImpl IMPL;
149ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
150ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    static {
15137c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        if (Build.VERSION.SDK_INT >= 16) {
15237c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            IMPL = new ShareCompatImplJB();
15337c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        } else if (Build.VERSION.SDK_INT >= 14) {
154ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            IMPL = new ShareCompatImplICS();
155ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        } else {
156ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            IMPL = new ShareCompatImplBase();
157ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
158ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
159ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
160ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    /**
161ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Retrieve the name of the package that launched calledActivity from a share intent.
162ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Apps that provide social sharing functionality can use this to provide attribution
163ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * for the app that shared the content.
164ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
165ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <p><em>Note:</em> This data may have been provided voluntarily by the calling
166ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * application. As such it should not be trusted for accuracy in the context of
167ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * security or verification.</p>
168ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
169ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @param calledActivity Current activity that was launched to share content
170ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @return Name of the calling package
171ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     */
172ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    public static String getCallingPackage(Activity calledActivity) {
173ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        String result = calledActivity.getCallingPackage();
174ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        if (result == null) {
175ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            result = calledActivity.getIntent().getStringExtra(EXTRA_CALLING_PACKAGE);
176ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
177ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        return result;
178ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
179ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
180ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    /**
181ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Retrieve the ComponentName of the activity that launched calledActivity from a share intent.
182ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Apps that provide social sharing functionality can use this to provide attribution
183ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * for the app that shared the content.
184ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
185ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <p><em>Note:</em> This data may have been provided voluntarily by the calling
186ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * application. As such it should not be trusted for accuracy in the context of
187ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * security or verification.</p>
188ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
189ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @param calledActivity Current activity that was launched to share content
190ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @return ComponentName of the calling activity
191ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     */
192ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    public static ComponentName getCallingActivity(Activity calledActivity) {
193ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        ComponentName result = calledActivity.getCallingActivity();
194ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        if (result == null) {
195ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            result = calledActivity.getIntent().getParcelableExtra(EXTRA_CALLING_ACTIVITY);
196ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
197ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        return result;
198ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
199ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
200ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    /**
201ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Configure a {@link MenuItem} to act as a sharing action.
202ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
203ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <p>If the app is running on API level 14 or higher (Android 4.0/Ice Cream Sandwich)
204ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * this method will configure a ShareActionProvider to provide a more robust UI
205ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * for selecting the target of the share. History will be tracked for each calling
206ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * activity in a file named with the prefix ".sharecompat_" in the application's
207ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * private data directory. If the application wishes to set this MenuItem to show
208ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * as an action in the Action Bar it should use
209ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * {@link MenuItemCompat#setShowAsAction(MenuItem, int)} to request that behavior
210ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * in addition to calling this method.</p>
211ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
212ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <p>If the app is running on an older platform version this method will configure
213ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * a standard activity chooser dialog for the menu item.</p>
214ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
215ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <p>During the calling activity's lifecycle, if data within the share intent must
216ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * change the app should change that state in one of several ways:</p>
217ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <ul>
218ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <li>Call {@link ActivityCompat#invalidateOptionsMenu(Activity)}. If the app is running
219ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * on API level 11 or above and uses the Action Bar its menu will be recreated and rebuilt.
220ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * If not, the activity will receive a call to {@link Activity#onPrepareOptionsMenu(Menu)}
221ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * the next time the user presses the menu key to open the options menu panel. The activity
222ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * can then call configureMenuItem again with a new or altered IntentBuilder to reconfigure
223ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * the share menu item.</li>
224ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <li>Keep a reference to the MenuItem object for the share item once it has been created
225ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * and call configureMenuItem to update the associated sharing intent as needed.</li>
226ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * </ul>
227ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
228ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @param item MenuItem to configure for sharing
229ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @param shareIntent IntentBuilder with data about the content to share
230ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     */
231ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    public static void configureMenuItem(MenuItem item, IntentBuilder shareIntent) {
232ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        IMPL.configureMenuItem(item, shareIntent);
233ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
234ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
235ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    /**
236ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Configure a menu item to act as a sharing action.
237ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
238ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @param menu Menu containing the item to use for sharing
239ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @param menuItemId ID of the share item within menu
240ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @param shareIntent IntentBuilder with data about the content to share
241ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * @see #configureMenuItem(MenuItem, IntentBuilder)
242ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     */
243ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    public static void configureMenuItem(Menu menu, int menuItemId, IntentBuilder shareIntent) {
244ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        MenuItem item = menu.findItem(menuItemId);
245ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        if (item == null) {
246ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            throw new IllegalArgumentException("Could not find menu item with id " + menuItemId +
247ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                    " in the supplied menu");
248ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
249ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        configureMenuItem(item, shareIntent);
250ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
251ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
252ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    /**
253ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * IntentBuilder is a helper for constructing {@link Intent#ACTION_SEND} and
254ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * {@link Intent#ACTION_SEND_MULTIPLE} sharing intents and starting activities
255ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * to share content. The ComponentName and package name of the calling activity
256ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * will be included.
257ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     */
258ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    public static class IntentBuilder {
259ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private Activity mActivity;
260ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private Intent mIntent;
261ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private CharSequence mChooserTitle;
262ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private ArrayList<String> mToAddresses;
263ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private ArrayList<String> mCcAddresses;
264ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private ArrayList<String> mBccAddresses;
265ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
266ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private ArrayList<Uri> mStreams;
267ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
268ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
269ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Create a new IntentBuilder for launching a sharing action from launchingActivity.
270ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
271ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param launchingActivity Activity that the share will be launched from
272ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return a new IntentBuilder instance
273ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
274ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public static IntentBuilder from(Activity launchingActivity) {
275ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return new IntentBuilder(launchingActivity);
276ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
277ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
278ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private IntentBuilder(Activity launchingActivity) {
279ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mActivity = launchingActivity;
280ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent = new Intent().setAction(Intent.ACTION_SEND);
281ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.putExtra(EXTRA_CALLING_PACKAGE, launchingActivity.getPackageName());
282ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.putExtra(EXTRA_CALLING_ACTIVITY, launchingActivity.getComponentName());
283ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
284ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
285ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
286ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
287ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Retrieve the Intent as configured so far by the IntentBuilder. This Intent
288ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * is suitable for use in a ShareActionProvider or chooser dialog.
289ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
290ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * <p>To create an intent that will launch the activity chooser so that the user
291ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * may select a target for the share, see {@link #createChooserIntent()}.
292ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
293ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return The current Intent being configured by this builder
294ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
295ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public Intent getIntent() {
296ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mToAddresses != null) {
297ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                combineArrayExtra(Intent.EXTRA_EMAIL, mToAddresses);
298ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mToAddresses = null;
299ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
300ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mCcAddresses != null) {
301ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                combineArrayExtra(Intent.EXTRA_CC, mCcAddresses);
302ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mCcAddresses = null;
303ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
304ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mBccAddresses != null) {
305ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                combineArrayExtra(Intent.EXTRA_BCC, mBccAddresses);
306ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mBccAddresses = null;
307ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
308ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
309ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            // Check if we need to change the action.
310ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            boolean needsSendMultiple = mStreams != null && mStreams.size() > 1;
311ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            boolean isSendMultiple = mIntent.getAction().equals(Intent.ACTION_SEND_MULTIPLE);
312ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
313ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (!needsSendMultiple && isSendMultiple) {
314ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                // Change back to a single send action; place the first stream into the
315ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                // intent for single sharing.
316ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mIntent.setAction(Intent.ACTION_SEND);
317ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                if (mStreams != null && !mStreams.isEmpty()) {
318ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                    mIntent.putExtra(Intent.EXTRA_STREAM, mStreams.get(0));
319ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                } else {
320ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                    mIntent.removeExtra(Intent.EXTRA_STREAM);
321ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                }
322ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mStreams = null;
323ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
324ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
325ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (needsSendMultiple && !isSendMultiple) {
326ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                // Change to a multiple send action; place the relevant ArrayList into the
327ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                // intent for multiple sharing.
328ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
329ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                if (mStreams != null && !mStreams.isEmpty()) {
330ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                    mIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, mStreams);
331ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                } else {
332ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                    mIntent.removeExtra(Intent.EXTRA_STREAM);
333ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                }
334ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
335ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
336ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mIntent;
337ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
338ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
339ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        Activity getActivity() {
340ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mActivity;
341ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
342ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
343ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private void combineArrayExtra(String extra, ArrayList<String> add) {
344ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            String[] currentAddresses = mIntent.getStringArrayExtra(extra);
345ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            int currentLength = currentAddresses != null ? currentAddresses.length : 0;
346ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            String[] finalAddresses = new String[currentLength + add.size()];
347ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            add.toArray(finalAddresses);
348ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (currentAddresses != null) {
349ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                System.arraycopy(currentAddresses, 0, finalAddresses, add.size(), currentLength);
350ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
351ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.putExtra(extra, finalAddresses);
352ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
353ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
354ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private void combineArrayExtra(String extra, String[] add) {
355ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            // Add any items still pending
356ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            Intent intent = getIntent();
357ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            String[] old = intent.getStringArrayExtra(extra);
358ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            int oldLength = old != null ? old.length : 0;
359ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            String[] result = new String[oldLength + add.length];
360ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (old != null) System.arraycopy(old, 0, result, 0, oldLength);
361ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            System.arraycopy(add, 0, result, oldLength, add.length);
362ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            intent.putExtra(extra, result);
363ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
364ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
365ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
366ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Create an Intent that will launch the standard Android activity chooser,
367ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * allowing the user to pick what activity/app on the system should handle
368ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * the share.
369ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
370ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return A chooser Intent for the currently configured sharing action
371ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
372ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public Intent createChooserIntent() {
373ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return Intent.createChooser(getIntent(), mChooserTitle);
374ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
375ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
376ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
3777ac4b376371e890eb19838249e6749f64d707ad2Adam Powell         * Start a chooser activity for the current share intent.
3787ac4b376371e890eb19838249e6749f64d707ad2Adam Powell         *
3797ac4b376371e890eb19838249e6749f64d707ad2Adam Powell         * <p>Note that under most circumstances you should use
3807ac4b376371e890eb19838249e6749f64d707ad2Adam Powell         * {@link ShareCompat#configureMenuItem(MenuItem, IntentBuilder)
3817ac4b376371e890eb19838249e6749f64d707ad2Adam Powell         *  ShareCompat.configureMenuItem()} to add a Share item to the menu while
3827ac4b376371e890eb19838249e6749f64d707ad2Adam Powell         * presenting a detail view of the content to be shared instead
3837ac4b376371e890eb19838249e6749f64d707ad2Adam Powell         * of invoking this directly.</p>
384ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
3857ac4b376371e890eb19838249e6749f64d707ad2Adam Powell        public void startChooser() {
3867ac4b376371e890eb19838249e6749f64d707ad2Adam Powell            mActivity.startActivity(createChooserIntent());
387ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
388ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
389ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
390ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Set the title that will be used for the activity chooser for this share.
391ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
392ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param title Title string
393ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
394ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
395ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder setChooserTitle(CharSequence title) {
396ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mChooserTitle = title;
397ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
398ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
399ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
400ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
401ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Set the title that will be used for the activity chooser for this share.
402ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
403ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param resId Resource ID of the title string to use
404ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
405ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
406ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder setChooserTitle(int resId) {
407ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return setChooserTitle(mActivity.getText(resId));
408ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
409ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
410ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
411ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Set the type of data being shared
412ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
413ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param mimeType mimetype of the shared data
414ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
415ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#setType(String)
416ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
417ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder setType(String mimeType) {
418ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.setType(mimeType);
419ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
420ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
421ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
422ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
423ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Set the literal text data to be sent as part of the share.
42437c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * This may be a styled CharSequence.
425ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
426ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param text Text to share
427ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
428ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_TEXT
429ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
430ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder setText(CharSequence text) {
431ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.putExtra(Intent.EXTRA_TEXT, text);
432ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
433ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
434ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
435ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
43637c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * Set an HTML string to be sent as part of the share.
43737c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * If {@link Intent#EXTRA_TEXT EXTRA_TEXT} has not already been supplied,
43837c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * a styled version of the supplied HTML text will be added as EXTRA_TEXT as
43937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * parsed by {@link android.text.Html#fromHtml(String) Html.fromHtml}.
44037c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         *
44137c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * @param htmlText A string containing HTML markup as a richer version of the text
44237c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         *                 provided by EXTRA_TEXT.
44337c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * @return This IntentBuilder for method chaining
44437c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * @see #setText(CharSequence)
44537c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         */
44637c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        public IntentBuilder setHtmlText(String htmlText) {
44737c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            mIntent.putExtra(IntentCompat.EXTRA_HTML_TEXT, htmlText);
44837c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            if (!mIntent.hasExtra(Intent.EXTRA_TEXT)) {
44937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                // Supply a default if EXTRA_TEXT isn't set
45037c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                setText(Html.fromHtml(htmlText));
45137c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            }
45237c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            return this;
45337c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        }
45437c1509886a7897163f70f4645c08ddf0b41632dAdam Powell
45537c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        /**
456ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Set a stream URI to the data that should be shared.
457ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
458ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * <p>This replaces all currently set stream URIs and will produce a single-stream
459ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * ACTION_SEND intent.</p>
460ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
461ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param streamUri URI of the stream to share
462ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
463ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_STREAM
464ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
465ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder setStream(Uri streamUri) {
466ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (!mIntent.getAction().equals(Intent.ACTION_SEND)) {
467ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mIntent.setAction(Intent.ACTION_SEND);
468ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
469ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mStreams = null;
470ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.putExtra(Intent.EXTRA_STREAM, streamUri);
471ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
472ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
473ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
474ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
475ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Add a stream URI to the data that should be shared. If this is not the first
476ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * stream URI added the final intent constructed will become an ACTION_SEND_MULTIPLE
477ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * intent. Not all apps will handle both ACTION_SEND and ACTION_SEND_MULTIPLE.
478ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
479ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param streamUri URI of the stream to share
480ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
481ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_STREAM
482ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#ACTION_SEND
483ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#ACTION_SEND_MULTIPLE
484ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
485ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder addStream(Uri streamUri) {
486ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            Uri currentStream = mIntent.getParcelableExtra(Intent.EXTRA_STREAM);
487ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (currentStream == null) {
488ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                return setStream(streamUri);
489ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
490ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mStreams == null) {
491ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mStreams = new ArrayList<Uri>();
492ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
493ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (currentStream != null) {
494ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mIntent.removeExtra(Intent.EXTRA_STREAM);
495ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mStreams.add(currentStream);
496ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
497ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mStreams.add(streamUri);
498ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
499ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
500ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
501ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
502ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Set an array of email addresses as recipients of this share.
503ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * This replaces all current "to" recipients that have been set so far.
504ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
505ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param addresses Email addresses to send to
506ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
507ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_EMAIL
508ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
509ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder setEmailTo(String[] addresses) {
510ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mToAddresses != null) {
511ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mToAddresses = null;
512ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
513ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.putExtra(Intent.EXTRA_EMAIL, addresses);
514ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
515ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
516ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
517ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
518ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Add an email address to be used in the "to" field of the final Intent.
519ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
520ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param address Email address to send to
521ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
522ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_EMAIL
523ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
524ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder addEmailTo(String address) {
525ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mToAddresses == null) {
526ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mToAddresses = new ArrayList<String>();
527ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
528ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mToAddresses.add(address);
529ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
530ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
531ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
532ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
533ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Add an array of email addresses to be used in the "to" field of the final Intent.
534ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
535ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param addresses Email addresses to send to
536ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
537ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_EMAIL
538ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
539ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder addEmailTo(String[] addresses) {
540ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            combineArrayExtra(Intent.EXTRA_EMAIL, addresses);
541ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
542ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
543ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
544ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
545ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Set an array of email addresses to CC on this share.
546ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * This replaces all current "CC" recipients that have been set so far.
547ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
548ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param addresses Email addresses to CC on the share
549ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
550ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_CC
551ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
552ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder setEmailCc(String[] addresses) {
553ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.putExtra(Intent.EXTRA_CC, addresses);
554ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
555ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
556ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
557ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
558ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Add an email address to be used in the "cc" field of the final Intent.
559ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
560ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param address Email address to CC
561ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
562ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_CC
563ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
564ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder addEmailCc(String address) {
565ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mCcAddresses == null) {
566ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mCcAddresses = new ArrayList<String>();
567ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
568ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mCcAddresses.add(address);
569ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
570ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
571ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
572ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
573ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Add an array of email addresses to be used in the "cc" field of the final Intent.
574ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
575ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param addresses Email addresses to CC
576ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
577ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_CC
578ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
579ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder addEmailCc(String[] addresses) {
580ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            combineArrayExtra(Intent.EXTRA_CC, addresses);
581ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
582ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
583ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
584ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
585ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Set an array of email addresses to BCC on this share.
586ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * This replaces all current "BCC" recipients that have been set so far.
587ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
588ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param addresses Email addresses to BCC on the share
589ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
590ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_BCC
591ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
592ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder setEmailBcc(String[] addresses) {
593ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.putExtra(Intent.EXTRA_BCC, addresses);
594ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
595ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
596ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
597ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
598ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Add an email address to be used in the "bcc" field of the final Intent.
599ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
600ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param address Email address to BCC
601ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
602ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_BCC
603ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
604ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder addEmailBcc(String address) {
605ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mBccAddresses == null) {
606ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mBccAddresses = new ArrayList<String>();
607ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
608ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mBccAddresses.add(address);
609ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
610ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
611ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
612ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
613ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Add an array of email addresses to be used in the "bcc" field of the final Intent.
614ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
615ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param addresses Email addresses to BCC
616ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
617ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_BCC
618ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
619ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder addEmailBcc(String[] addresses) {
620ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            combineArrayExtra(Intent.EXTRA_BCC, addresses);
621ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
622ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
623ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
624ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
625ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Set a subject heading for this share; useful for sharing via email.
626ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
627ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param subject Subject heading for this share
628ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return This IntentBuilder for method chaining
629ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_SUBJECT
630ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
631ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public IntentBuilder setSubject(String subject) {
632ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
633ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return this;
634ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
635ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
636ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
637ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    /**
638ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * IntentReader is a helper for reading the data contained within a sharing (ACTION_SEND)
639ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * Intent. It provides methods to parse standard elements included with a share
640ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * in addition to extra metadata about the app that shared the content.
641ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
642ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <p>Social sharing apps are encouraged to provide attribution for the app that shared
643ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * the content. IntentReader offers access to the application label, calling activity info,
644ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * and application icon of the app that shared the content. This data may have been provided
645ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * voluntarily by the calling app and should always be displayed to the user before submission
646ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * for manual verification. The user should be offered the option to omit this information
647ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * from shared posts if desired.</p>
648ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     *
649ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * <p>Activities that intend to receive sharing intents should configure an intent-filter
650ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * to accept {@link Intent#ACTION_SEND} intents ("android.intent.action.SEND") and optionally
651ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * accept {@link Intent#ACTION_SEND_MULTIPLE} ("android.intent.action.SEND_MULTIPLE") if
652ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     * the activity is equipped to handle multiple data streams.</p>
653ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell     */
654ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    public static class IntentReader {
655ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private static final String TAG = "IntentReader";
656ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
657ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private Activity mActivity;
658ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private Intent mIntent;
659ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private String mCallingPackage;
660ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private ComponentName mCallingActivity;
661ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
662ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private ArrayList<Uri> mStreams;
663ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
664ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
665ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get an IntentReader for parsing and interpreting the sharing intent
666ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * used to start the given activity.
667ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
668ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param activity Activity that was started to share content
669ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return IntentReader for parsing sharing data
670ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
671ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public static IntentReader from(Activity activity) {
672ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return new IntentReader(activity);
673ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
674ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
675ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        private IntentReader(Activity activity) {
676ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mActivity = activity;
677ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mIntent = activity.getIntent();
678ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mCallingPackage = ShareCompat.getCallingPackage(activity);
679ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            mCallingActivity = ShareCompat.getCallingActivity(activity);
680ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
681ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
682ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
683ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Returns true if the activity this reader was obtained for was
684ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * started with an {@link Intent#ACTION_SEND} or {@link Intent#ACTION_SEND_MULTIPLE}
685ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * sharing Intent.
686ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
687ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return true if the activity was started with an ACTION_SEND
688ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *         or ACTION_SEND_MULTIPLE Intent
689ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
690ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public boolean isShareIntent() {
691ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            final String action = mIntent.getAction();
6920e2575ae97ccb986e9d32a57c9e4c44b3c1aa20eAdam Koch            return Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action);
693ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
694ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
695ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
696ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Returns true if the activity this reader was obtained for was started with an
697ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * {@link Intent#ACTION_SEND} intent and contains a single shared item.
698ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * The shared content should be obtained using either the {@link #getText()}
699ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * or {@link #getStream()} methods depending on the type of content shared.
700ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
701ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return true if the activity was started with an ACTION_SEND intent
702ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
703ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public boolean isSingleShare() {
7040e2575ae97ccb986e9d32a57c9e4c44b3c1aa20eAdam Koch            return Intent.ACTION_SEND.equals(mIntent.getAction());
705ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
706ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
707ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
708ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Returns true if the activity this reader was obtained for was started with an
709ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * {@link Intent#ACTION_SEND_MULTIPLE} intent. The Intent may contain more than
710ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * one stream item.
711ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
712ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return true if the activity was started with an ACTION_SEND_MULTIPLE intent
713ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
714ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public boolean isMultipleShare() {
7150e2575ae97ccb986e9d32a57c9e4c44b3c1aa20eAdam Koch            return Intent.ACTION_SEND_MULTIPLE.equals(mIntent.getAction());
716ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
717ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
718ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
719ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get the mimetype of the data shared to this activity.
720ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
721ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return mimetype of the shared data
722ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#getType()
723ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
724ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public String getType() {
725ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mIntent.getType();
726ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
727ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
728ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
729ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get the literal text shared with the target activity.
730ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
731ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return Literal shared text or null if none was supplied
732ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_TEXT
733ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
734ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public CharSequence getText() {
735ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
736ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
737ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
738ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
73937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * Get the styled HTML text shared with the target activity.
74037c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * If no HTML text was supplied but {@link Intent#EXTRA_TEXT} contained
74137c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * styled text, it will be converted to HTML if possible and returned.
74237c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * If the text provided by {@link Intent#EXTRA_TEXT} was not styled text,
74337c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * it will be escaped by {@link android.text.Html#escapeHtml(CharSequence)}
74437c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * and returned. If no text was provided at all, this method will return null.
74537c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         *
74637c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         * @return Styled text provided by the sender as HTML.
74737c1509886a7897163f70f4645c08ddf0b41632dAdam Powell         */
74837c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        public String getHtmlText() {
74937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            String result = mIntent.getStringExtra(IntentCompat.EXTRA_HTML_TEXT);
7500eefa9b2aa1c43a6c05def134bba74328b207a02Adam Powell            if (result == null) {
75137c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                CharSequence text = getText();
75237c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                if (text instanceof Spanned) {
75337c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    result = Html.toHtml((Spanned) text);
75437c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                } else if (text != null) {
75537c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                    result = IMPL.escapeHtml(text);
75637c1509886a7897163f70f4645c08ddf0b41632dAdam Powell                }
75737c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            }
75837c1509886a7897163f70f4645c08ddf0b41632dAdam Powell            return result;
75937c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        }
76037c1509886a7897163f70f4645c08ddf0b41632dAdam Powell
76137c1509886a7897163f70f4645c08ddf0b41632dAdam Powell        /**
762ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get a URI referring to a data stream shared with the target activity.
763ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
764ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * <p>This call will fail if the share intent contains multiple stream items.
765ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * If {@link #isMultipleShare()} returns true the application should use
766ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * {@link #getStream(int)} and {@link #getStreamCount()} to retrieve the
767ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * included stream items.</p>
768ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
769ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return A URI referring to a data stream to be shared or null if one was not supplied
770ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_STREAM
771ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
772ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public Uri getStream() {
773ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mIntent.getParcelableExtra(Intent.EXTRA_STREAM);
774ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
775ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
776ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
777ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get the URI of a stream item shared with the target activity.
778ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Index should be in the range [0-getStreamCount()).
779ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
780ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @param index Index of text item to retrieve
781ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return Requested stream item URI
782ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_STREAM
783ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#ACTION_SEND_MULTIPLE
784ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
785ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public Uri getStream(int index) {
786ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mStreams == null && isMultipleShare()) {
787ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mStreams = mIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
788ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
789ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mStreams != null) {
790ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                return mStreams.get(index);
791ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
792ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (index == 0) {
793ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                return mIntent.getParcelableExtra(Intent.EXTRA_STREAM);
794ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
795ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            throw new IndexOutOfBoundsException("Stream items available: " + getStreamCount() +
796ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                    " index requested: " + index);
797ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
798ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
799ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
800ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Return the number of stream items shared. The return value will be 0 or 1 if
801ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * this was an {@link Intent#ACTION_SEND} intent, or 0 or more if it was an
802ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * {@link Intent#ACTION_SEND_MULTIPLE} intent.
803ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
804ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return Count of text items contained within the Intent
805ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
806ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public int getStreamCount() {
807ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mStreams == null && isMultipleShare()) {
808ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                mStreams = mIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
809ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
810ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mStreams != null) {
811ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                return mStreams.size();
812ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
813ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mIntent.hasExtra(Intent.EXTRA_STREAM) ? 1 : 0;
814ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
815ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
816ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
817ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get an array of Strings, each an email address to share to.
818ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
819ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return An array of email addresses or null if none were supplied.
820ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_EMAIL
821ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
822ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public String[] getEmailTo() {
823ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mIntent.getStringArrayExtra(Intent.EXTRA_EMAIL);
824ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
825ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
826ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
827ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get an array of Strings, each an email address to CC on this share.
828ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
829ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return An array of email addresses or null if none were supplied.
830ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_CC
831ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
832ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public String[] getEmailCc() {
833ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mIntent.getStringArrayExtra(Intent.EXTRA_CC);
834ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
835ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
836ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
837ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get an array of Strings, each an email address to BCC on this share.
838ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
839ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return An array of email addresses or null if none were supplied.
840ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_BCC
841ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
842ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public String[] getEmailBcc() {
843ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mIntent.getStringArrayExtra(Intent.EXTRA_BCC);
844ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
845ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
846ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
847ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get a subject heading for this share; useful when sharing via email.
848ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
849ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return The subject heading for this share or null if one was not supplied.
850ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Intent#EXTRA_SUBJECT
851ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
852ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public String getSubject() {
853ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mIntent.getStringExtra(Intent.EXTRA_SUBJECT);
854ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
855ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
856ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
857ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get the name of the package that invoked this sharing intent. If the activity
858ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * was not started for a result, IntentBuilder will read this from extra metadata placed
859ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * in the Intent by ShareBuilder.
860ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
861ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * <p><em>Note:</em> This data may have been provided voluntarily by the calling
862ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * application. As such it should not be trusted for accuracy in the context of
863ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * security or verification.</p>
864ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
865ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return Name of the package that started this activity or null if unknown
866ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Activity#getCallingPackage()
867ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see ShareCompat#EXTRA_CALLING_PACKAGE
868ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
869ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public String getCallingPackage() {
870ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mCallingPackage;
871ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
872ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
873ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
874ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get the {@link ComponentName} of the Activity that invoked this sharing intent.
875ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * If the target sharing activity was not started for a result, IntentBuilder will read
876ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * this from extra metadata placed in the intent by ShareBuilder.
877ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
878ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * <p><em>Note:</em> This data may have been provided voluntarily by the calling
879ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * application. As such it should not be trusted for accuracy in the context of
880ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * security or verification.</p>
881ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
882ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return ComponentName of the calling Activity or null if unknown
883ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see Activity#getCallingActivity()
884ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @see ShareCompat#EXTRA_CALLING_ACTIVITY
885ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
886ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public ComponentName getCallingActivity() {
887ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return mCallingActivity;
888ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
889ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
890ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
891ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get the icon of the calling activity as a Drawable if data about
892ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * the calling activity is available.
893ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
894ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * <p><em>Note:</em> This data may have been provided voluntarily by the calling
895ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * application. As such it should not be trusted for accuracy in the context of
896ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * security or verification.</p>
897ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
898ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return The calling Activity's icon or null if unknown
899ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
900ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public Drawable getCallingActivityIcon() {
901ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mCallingActivity == null) return null;
902ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
903ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            PackageManager pm = mActivity.getPackageManager();
904ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            try {
905ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                return pm.getActivityIcon(mCallingActivity);
906ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            } catch (NameNotFoundException e) {
907ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                Log.e(TAG, "Could not retrieve icon for calling activity", e);
908ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
909ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return null;
910ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
911ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
912ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
913ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get the icon of the calling application as a Drawable if data
914ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * about the calling package is available.
915ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
916ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * <p><em>Note:</em> This data may have been provided voluntarily by the calling
917ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * application. As such it should not be trusted for accuracy in the context of
918ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * security or verification.</p>
919ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
920ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return The calling application's icon or null if unknown
921ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
922ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public Drawable getCallingApplicationIcon() {
923ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mCallingPackage == null) return null;
924ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
925ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            PackageManager pm = mActivity.getPackageManager();
926ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            try {
927ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                return pm.getApplicationIcon(mCallingPackage);
928ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            } catch (NameNotFoundException e) {
929ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                Log.e(TAG, "Could not retrieve icon for calling application", e);
930ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
931ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return null;
932ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
933ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
934ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        /**
935ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * Get the human-readable label (title) of the calling application if
936ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * data about the calling package is available.
937ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
938ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * <p><em>Note:</em> This data may have been provided voluntarily by the calling
939ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * application. As such it should not be trusted for accuracy in the context of
940ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * security or verification.</p>
941ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         *
942ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         * @return The calling application's label or null if unknown
943ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell         */
944ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        public CharSequence getCallingApplicationLabel() {
945ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            if (mCallingPackage == null) return null;
946ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell
947ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            PackageManager pm = mActivity.getPackageManager();
948ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            try {
949ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                return pm.getApplicationLabel(pm.getApplicationInfo(mCallingPackage, 0));
950ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            } catch (NameNotFoundException e) {
951ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell                Log.e(TAG, "Could not retrieve label for calling application", e);
952ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            }
953ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell            return null;
954ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell        }
955ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell    }
956ac4078687ff889e804b198bf5748e611bbb0fa30Adam Powell}
957