mobile/android/base/prompts/IntentChooserPrompt.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 package org.mozilla.gecko.prompts;
     7 import org.mozilla.gecko.GeckoAppShell;
     8 import org.mozilla.gecko.util.ThreadUtils;
     9 import org.mozilla.gecko.widget.GeckoActionProvider;
    11 import android.app.Activity;
    12 import android.content.ComponentName;
    13 import android.content.Context;
    14 import android.content.Intent;
    15 import android.content.pm.PackageManager;
    16 import android.content.pm.ResolveInfo;
    17 import android.widget.ListView;
    18 import android.util.Log;
    20 import org.json.JSONException;
    21 import org.json.JSONObject;
    23 import java.util.ArrayList;
    24 import java.util.List;
    26 /**
    27  * Shows a prompt letting the user pick from a list of intent handlers for a set of Intents or
    28  * for a GeckoActionProvider.  Basic usage:
    29  *   IntentChooserPrompt prompt = new IntentChooserPrompt(context, new Intent[] {
    30  *      ... // some intents
    31  *    });
    32  *    prompt.show("Title", context, new IntentHandler() {
    33  *        public void onIntentSelected(Intent intent, int position) { }
    34  *        public void onCancelled() { }
    35  *    });
    36  **/
    37 public class IntentChooserPrompt {
    38     private static final String LOGTAG = "GeckoIntentChooser";
    40     private final ArrayList<PromptListItem> mItems;
    42     public IntentChooserPrompt(Context context, Intent[] intents) {
    43         mItems = getItems(context, intents);
    44     }
    46     public IntentChooserPrompt(Context context, GeckoActionProvider provider) {
    47         mItems = getItems(context, provider);
    48     }
    50     /* If an IntentHandler is passed in, will asynchronously call the handler when the dialog is closed
    51      * Otherwise, will return the Intent that was chosen by the user. Must be called on the UI thread.
    52      */
    53     public void show(final String title, final Context context, final IntentHandler handler) {
    54         ThreadUtils.assertOnUiThread();
    56         if (mItems.isEmpty()) {
    57             Log.i(LOGTAG, "No activities for the intent chooser!");
    58             handler.onCancelled();
    59             return;
    60         }
    62         // If there's only one item in the intent list, just return it
    63         if (mItems.size() == 1) {
    64             handler.onIntentSelected(mItems.get(0).getIntent(), 0);
    65             return;
    66         }
    68         final Prompt prompt = new Prompt(context, new Prompt.PromptCallback() {
    69             @Override
    70             public void onPromptFinished(String promptServiceResult) {
    71                 if (handler == null) {
    72                     return;
    73                 }
    75                 int itemId = -1;
    76                 try {
    77                     itemId = new JSONObject(promptServiceResult).getInt("button");
    78                 } catch (JSONException e) {
    79                     Log.e(LOGTAG, "result from promptservice was invalid: ", e);
    80                 }
    82                 if (itemId == -1) {
    83                     handler.onCancelled();
    84                 } else {
    85                     handler.onIntentSelected(mItems.get(itemId).getIntent(), itemId);
    86                 }
    87             }
    88         });
    90         PromptListItem[] arrays = new PromptListItem[mItems.size()];
    91         mItems.toArray(arrays);
    92         prompt.show(title, "", arrays, ListView.CHOICE_MODE_NONE);
    94         return;
    95     }
    97     // Whether or not any activities were found. Useful for checking if you should try a different Intent set
    98     public boolean hasActivities(Context context) {
    99         return mItems.isEmpty();
   100     }
   102     // Gets a list of PromptListItems for an Intent array
   103     private ArrayList<PromptListItem> getItems(final Context context, Intent[] intents) {
   104         final ArrayList<PromptListItem> items = new ArrayList<PromptListItem>();
   106         // If we have intents, use them to build the initial list
   107         for (final Intent intent : intents) {
   108             items.addAll(getItemsForIntent(context, intent));
   109         }
   111         return items;
   112     }
   114     // Gets a list of PromptListItems for a GeckoActionProvider
   115     private ArrayList<PromptListItem> getItems(final Context context, final GeckoActionProvider provider) {
   116         final ArrayList<PromptListItem> items = new ArrayList<PromptListItem>();
   118         // Add any intents from the provider.
   119         final PackageManager packageManager = context.getPackageManager();
   120         final ArrayList<ResolveInfo> infos = provider.getSortedActivites();
   122         for (final ResolveInfo info : infos) {
   123             items.add(getItemForResolveInfo(info, packageManager, provider.getIntent()));
   124         }
   126         return items;
   127     }
   129     private PromptListItem getItemForResolveInfo(ResolveInfo info, PackageManager pm, Intent intent) {
   130         PromptListItem item = new PromptListItem(info.loadLabel(pm).toString());
   131         item.setIcon(info.loadIcon(pm));
   133         Intent i = new Intent(intent);
   134         // These intents should be implicit.
   135         i.setComponent(new ComponentName(info.activityInfo.applicationInfo.packageName,
   136                                          info.activityInfo.name));
   137         item.setIntent(new Intent(i));
   139         return item;
   140     }
   142     private ArrayList<PromptListItem> getItemsForIntent(Context context, Intent intent) {
   143         ArrayList<PromptListItem> items = new ArrayList<PromptListItem>();
   144         PackageManager pm = context.getPackageManager();
   145         List<ResolveInfo> lri = pm.queryIntentActivityOptions(GeckoAppShell.getGeckoInterface().getActivity().getComponentName(), null, intent, 0);
   147         // If we didn't find any activities, just return the empty list
   148         if (lri == null) {
   149             return items;
   150         }
   152         // Otherwise, convert the ResolveInfo. Note we don't currently check for duplicates here.
   153         for (ResolveInfo ri : lri) {
   154             items.add(getItemForResolveInfo(ri, pm, intent));
   155         }
   157         return items;
   158     }
   159 }

mercurial