1e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski/* 2e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * Copyright (C) 2015 The Android Open Source Project 3e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * 4e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * Licensed under the Apache License, Version 2.0 (the "License"); 5e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * you may not use this file except in compliance with the License. 6e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * You may obtain a copy of the License at 7e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * 8e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * http://www.apache.org/licenses/LICENSE-2.0 9e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * 10e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * Unless required by applicable law or agreed to in writing, software 11e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * distributed under the License is distributed on an "AS IS" BASIS, 12e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * See the License for the specific language governing permissions and 14e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * limitations under the License. 15e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski */ 16e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 17e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynskipackage com.example.android.support.percent; 18e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 1919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.app.ListActivity; 2019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.content.Intent; 2119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.content.pm.PackageManager; 2219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.content.pm.ResolveInfo; 23e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynskiimport android.os.Bundle; 24e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynskiimport android.view.View; 2519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.widget.ListView; 2619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.widget.SimpleAdapter; 27e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 2819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.text.Collator; 2919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.ArrayList; 3019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.Collections; 3119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.Comparator; 3219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.HashMap; 3319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.List; 3419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.Map; 35e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 3619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovpublic class SupportPercentDemos extends ListActivity { 37e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 38e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski @Override 3919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov public void onCreate(Bundle savedInstanceState) { 40e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski super.onCreate(savedInstanceState); 4119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 4219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov Intent intent = getIntent(); 4319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov String path = intent.getStringExtra("com.example.android.apis.Path"); 4419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 4519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov if (path == null) { 4619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov path = ""; 4719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov } 4819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 4919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov setListAdapter(new SimpleAdapter(this, getData(path), 5019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov android.R.layout.simple_list_item_1, new String[] { "title" }, 5119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov new int[] { android.R.id.text1 })); 5219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov getListView().setTextFilterEnabled(true); 53e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski } 54e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 5519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov protected List<Map<String, Object>> getData(String prefix) { 5619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>(); 5719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 5819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 5919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov mainIntent.addCategory("com.example.android.supportpercent.SAMPLE_CODE"); 6019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 6119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov PackageManager pm = getPackageManager(); 6219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0); 6319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 6419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov if (null == list) 6519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov return myData; 6619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 6719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov String[] prefixPath; 6819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov String prefixWithSlash = prefix; 6919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 7019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov if (prefix.equals("")) { 7119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov prefixPath = null; 7219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov } else { 7319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov prefixPath = prefix.split("/"); 7419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov prefixWithSlash = prefix + "/"; 75e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski } 76e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 7719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov int len = list.size(); 7819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 7919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov Map<String, Boolean> entries = new HashMap<String, Boolean>(); 8019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 8119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov for (int i = 0; i < len; i++) { 8219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov ResolveInfo info = list.get(i); 8319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov CharSequence labelSeq = info.loadLabel(pm); 8419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov String label = labelSeq != null 8519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov ? labelSeq.toString() 8619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov : info.activityInfo.name; 8719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 8819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) { 8919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 9019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov String[] labelPath = label.split("/"); 9119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 9219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length]; 93973c8f507a83250d3aae077427bd4df67ba4ff61Filip Gruszczynski 9419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) { 9519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov addItem(myData, nextLabel, activityIntent( 9619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov info.activityInfo.applicationInfo.packageName, 9719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov info.activityInfo.name)); 9819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov } else { 9919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov if (entries.get(nextLabel) == null) { 10019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov addItem(myData, nextLabel, browseIntent( 10119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov prefix.equals("") ? nextLabel : prefix + "/" + nextLabel)); 10219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov entries.put(nextLabel, true); 10319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov } 10419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov } 105e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski } 106e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski } 107e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 10819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov Collections.sort(myData, sDisplayNameComparator); 10919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 11019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov return myData; 111e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski } 112e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 11319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov private final static Comparator<Map<String, Object>> sDisplayNameComparator = 11419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov new Comparator<Map<String, Object>>() { 11519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov private final Collator collator = Collator.getInstance(); 116e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski 11719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov @Override 11819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov public int compare(Map<String, Object> map1, Map<String, Object> map2) { 11919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov return collator.compare(map1.get("title"), map2.get("title")); 12019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov } 12119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov }; 12219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 12319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov protected Intent activityIntent(String pkg, String componentName) { 12419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov Intent result = new Intent(); 12519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov result.setClassName(pkg, componentName); 12619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov return result; 12719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov } 12819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 12919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov protected Intent browseIntent(String path) { 13019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov Intent result = new Intent(); 13119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov result.setClass(this, SupportPercentDemos.class); 13219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov result.putExtra("com.example.android.apis.Path", path); 13319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov return result; 13419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov } 13519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 13619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov protected void addItem(List<Map<String, Object>> data, String name, Intent intent) { 13719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov Map<String, Object> temp = new HashMap<String, Object>(); 13819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov temp.put("title", name); 13919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov temp.put("intent", intent); 14019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov data.add(temp); 14119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov } 14219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 14319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov @Override 14419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov @SuppressWarnings("unchecked") 14519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov protected void onListItemClick(ListView l, View v, int position, long id) { 14619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov Map<String, Object> map = (Map<String, Object>)l.getItemAtPosition(position); 14719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov 14819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov Intent intent = (Intent) map.get("intent"); 14919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov startActivity(intent); 150e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski } 151e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski} 152