1 /* <lambda>null2 * Copyright 2020 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 * https://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 @file:Suppress("DEPRECATION") // ListActivity 18 19 package com.google.accompanist.sample 20 21 import android.annotation.SuppressLint 22 import android.app.ListActivity 23 import android.content.Intent 24 import android.os.Bundle 25 import android.view.View 26 import android.widget.ListView 27 import android.widget.SimpleAdapter 28 import java.text.Collator 29 import java.util.ArrayList 30 import java.util.Collections 31 import java.util.Comparator 32 import java.util.HashMap 33 34 /** 35 * A [ListActivity] which automatically populates the list of sample activities in this app 36 * with the category `com.google.accompanist.sample.SAMPLE_CODE`. 37 */ 38 class MainActivity : ListActivity() { 39 override fun onCreate(savedInstanceState: Bundle?) { 40 super.onCreate(savedInstanceState) 41 42 listAdapter = SimpleAdapter( 43 this, 44 getData(intent.getStringExtra(EXTRA_PATH)), 45 android.R.layout.simple_list_item_1, 46 arrayOf("title"), 47 intArrayOf(android.R.id.text1) 48 ) 49 50 listView.isTextFilterEnabled = true 51 } 52 53 private fun getData(prefix: String?): List<Map<String, Any>> { 54 val myData = ArrayList<Map<String, Any>>() 55 56 val mainIntent = Intent(Intent.ACTION_MAIN, null) 57 mainIntent.addCategory("com.google.accompanist.sample.SAMPLE_CODE") 58 59 @SuppressLint("QueryPermissionsNeeded") // Only querying our own Activities 60 val list = packageManager.queryIntentActivities(mainIntent, 0) 61 62 val prefixPath: Array<String>? 63 var prefixWithSlash = prefix 64 65 if (prefix.isNullOrEmpty()) { 66 prefixPath = null 67 } else { 68 prefixPath = prefix.split("/".toRegex()).toTypedArray() 69 prefixWithSlash = "$prefix/" 70 } 71 72 val entries = HashMap<String, Boolean>() 73 74 list.forEach { info -> 75 val labelSeq = info.loadLabel(packageManager) 76 val label = labelSeq?.toString() ?: info.activityInfo.name 77 78 if (prefixWithSlash.isNullOrEmpty() || label.startsWith(prefixWithSlash)) { 79 val labelPath = label.split("/".toRegex()).toTypedArray() 80 val nextLabel = if (prefixPath == null) labelPath[0] else labelPath[prefixPath.size] 81 if (prefixPath?.size ?: 0 == labelPath.size - 1) { 82 addItem( 83 data = myData, 84 name = nextLabel, 85 intent = activityIntent( 86 info.activityInfo.applicationInfo.packageName, 87 info.activityInfo.name 88 ) 89 ) 90 } else { 91 if (entries[nextLabel] == null) { 92 addItem( 93 data = myData, 94 name = nextLabel, 95 intent = browseIntent( 96 if (prefix == "") nextLabel else "$prefix/$nextLabel" 97 ) 98 ) 99 entries[nextLabel] = true 100 } 101 } 102 } 103 } 104 105 Collections.sort(myData, sDisplayNameComparator) 106 107 return myData 108 } 109 110 private fun activityIntent(pkg: String, componentName: String): Intent { 111 val result = Intent() 112 result.setClassName(pkg, componentName) 113 return result 114 } 115 116 private fun browseIntent(path: String): Intent { 117 val result = Intent() 118 result.setClass(this, MainActivity::class.java) 119 result.putExtra(EXTRA_PATH, path) 120 return result 121 } 122 123 private fun addItem(data: MutableList<Map<String, Any>>, name: String, intent: Intent) { 124 val temp = mutableMapOf<String, Any>() 125 temp["title"] = name 126 temp["intent"] = intent 127 data += temp 128 } 129 130 override fun onListItemClick(l: ListView, v: View, position: Int, id: Long) { 131 val map = l.getItemAtPosition(position) as Map<*, *> 132 val intent = map["intent"] as Intent? 133 startActivity(intent) 134 } 135 136 companion object { 137 private const val EXTRA_PATH = "com.example.android.apis.Path" 138 139 private val sDisplayNameComparator = object : Comparator<Map<String, Any>> { 140 private val collator = Collator.getInstance() 141 142 override fun compare(map1: Map<String, Any>, map2: Map<String, Any>): Int { 143 return collator.compare(map1["title"], map2["title"]) 144 } 145 } 146 } 147 } 148