1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.apps.tag.record;
18 
19 import com.android.apps.tag.R;
20 import com.google.common.collect.Lists;
21 
22 import android.app.Activity;
23 import android.content.ComponentName;
24 import android.content.Intent;
25 import android.content.pm.ActivityInfo;
26 import android.content.pm.PackageManager;
27 import android.content.pm.ResolveInfo;
28 import android.util.Log;
29 import android.view.LayoutInflater;
30 import android.view.View;
31 import android.view.View.OnClickListener;
32 import android.view.ViewGroup;
33 import android.view.ViewGroup.LayoutParams;
34 import android.widget.ImageView;
35 import android.widget.LinearLayout;
36 import android.widget.TextView;
37 
38 import java.util.Collections;
39 import java.util.Comparator;
40 import java.util.List;
41 
42 /**
43  * Utilities for parsed records to use.
44  */
45 public class RecordUtils {
46     /**
47      * Contains info for click events that happen on views created via {@link #getViewsForIntent}.
48      */
49     public static final class ClickInfo {
50         public Activity activity;
51         public Intent intent;
52 
ClickInfo(Activity activity, Intent intent)53         public ClickInfo(Activity activity, Intent intent) {
54             this.activity = activity;
55             this.intent = intent;
56         }
57     }
58 
59     /**
60      * Creates one or more views for a parsed record that wants to display an actionable intent.
61      * The views will have a {@link ClickInfo} set as their tag.
62      */
getViewsForIntent(Activity activity, LayoutInflater inflater, ViewGroup parent, OnClickListener listener, Intent intent, String description)63     public static View getViewsForIntent(Activity activity, LayoutInflater inflater,
64             ViewGroup parent, OnClickListener listener, Intent intent, String description) {
65         // Lookup which packages can handle this intent.
66         PackageManager pm = activity.getPackageManager();
67         int flags = PackageManager.GET_RESOLVED_FILTER | PackageManager.MATCH_DEFAULT_ONLY;
68         List<ResolveInfo> activities = pm.queryIntentActivities(intent, flags);
69         int numActivities = activities.size();
70         if (numActivities == 0 || (numActivities == 1 && !activities.get(0).activityInfo.enabled)) {
71             TextView text = (TextView) inflater.inflate(R.layout.tag_text, parent, false);
72             text.setText(description);
73             return text;
74         } else if (numActivities == 1) {
75             return buildActivityView(activity, activities.get(0), pm, inflater, parent, listener,
76                     intent, description);
77         } else {
78             // Build a container to hold the multiple entries
79             LinearLayout container = new LinearLayout(activity);
80             container.setOrientation(LinearLayout.VERTICAL);
81             container.setLayoutParams(new LayoutParams(
82                     LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
83 
84             // Create an entry for each activity that can handle the URI
85             for (ResolveInfo resolveInfo : activities) {
86                 if (!resolveInfo.activityInfo.enabled) {
87                     continue;
88                 }
89 
90                 if (container.getChildCount() > 0) {
91                     inflater.inflate(R.layout.tag_divider, container);
92                 }
93                 // Clone the intent for each view so they can each have their own components setup
94                 Intent clone = new Intent(intent);
95                 container.addView(buildActivityView(activity, resolveInfo, pm, inflater, container,
96                         listener, clone, description));
97             }
98             return container;
99         }
100     }
101 
102     /**
103      * Build a view to display a single activity that can handle this URI.
104      */
buildActivityView(Activity activity, ResolveInfo resolveInfo, PackageManager pm, LayoutInflater inflater, ViewGroup parent, OnClickListener listener, Intent intent, String defaultText)105     private static View buildActivityView(Activity activity, ResolveInfo resolveInfo, PackageManager pm,
106             LayoutInflater inflater, ViewGroup parent, OnClickListener listener, Intent intent,
107             String defaultText) {
108         ActivityInfo activityInfo = resolveInfo.activityInfo;
109 
110         intent.setAction(resolveInfo.filter.getAction(0));
111         intent.setComponent(new ComponentName(activityInfo.packageName, activityInfo.name));
112 
113         View item = inflater.inflate(R.layout.tag_uri, parent, false);
114         item.setOnClickListener(listener);
115         item.setTag(new ClickInfo(activity, intent));
116 
117         ImageView icon = (ImageView) item.findViewById(R.id.icon);
118         icon.setImageDrawable(resolveInfo.loadIcon(pm));
119 
120         TextView text = (TextView) item.findViewById(R.id.secondary);
121         text.setText(resolveInfo.loadLabel(pm));
122 
123         text = (TextView) item.findViewById(R.id.primary);
124         text.setText(defaultText);
125 
126         return item;
127     }
128 }
129