This answer is correct an list of installed app show and search feature add.
Kotlin
activity_all_installed_app.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AllInstalledAppActivity">
<TextView
android:id="@+id/totalInstalledApp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/total_Installed_Apps"
android:textStyle="bold"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/totalInstalledApp"
tools:listitem="@layout/installed_app_layout" />
</androidx.constraintlayout.widget.ConstraintLayout>
installed_app_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="4dp"
android:elevation="6dp"
android:background="?attr/selectableItemBackground">
<androidx.cardview.widget.CardView
android:id="@+id/cardview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
app:cardCornerRadius="5dp"
app:cardUseCompatPadding="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/app_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:contentDescription="@string/todo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/list_app_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/app_name"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/app_icon"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/app_package"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/app_package_name"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/app_icon"
app:layout_constraintTop_toBottomOf="@+id/list_app_name" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
AppModel.kt
import android.graphics.drawable.Drawable
class AppModel(private var name:String, private var icon: Drawable, private var packages:String) {
fun getName(): String {
return name
}
fun getIcon(): Drawable {
return icon
}
fun getPackages(): String {
return packages
}
}
AppAdapter.kt
import android.app.AlertDialog
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.materialsouk.allcodeapp.R
import com.materialsouk.allcodeapp.models.AppModel
import java.util.ArrayList
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import android.widget.Toast
class AppAdapter(private val context: Context, private var appModelList: ArrayList<AppModel>) :
RecyclerView.Adapter<AppAdapter.ViewHolder>() {
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val appNameTxt: TextView = itemView.findViewById(R.id.list_app_name)
val appPackageNameTxt: TextView = itemView.findViewById(R.id.app_package)
val appIcon: ImageView = itemView.findViewById(R.id.app_icon)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view: View =
LayoutInflater.from(parent.context)
.inflate(R.layout.installed_app_layout, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.appNameTxt.text = appModelList[position].getName()
holder.appIcon.setImageDrawable(appModelList[position].getIcon())
holder.appPackageNameTxt.text = appModelList[position].getPackages()
holder.itemView.setOnClickListener {
val dialogListTitle = arrayOf("Open App", "App Info")
val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder.setTitle("Choose Action")
.setItems(
dialogListTitle
) { _, which ->
when (which) {
0 -> {
val intent =
context.packageManager.getLaunchIntentForPackage(appModelList[position].getPackages())
if (intent != null) {
context.startActivity(intent)
}else{
Toast.makeText(context,"System app is not open for any reason.",Toast.LENGTH_LONG).show()
}
}
1 -> {
val intent = Intent()
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
intent.data =
Uri.parse("package:${appModelList[position].getPackages()}")
context.startActivity(intent)
}
}
}
builder.show()
}
}
override fun getItemCount(): Int {
return appModelList.size
}
}
This is menu
search_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/app_bar_search"
android:icon="@drawable/ic_search_black_24dp"
android:title="@string/search"
app:showAsAction="ifRoom|withText"
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
</menu>
AllInstalledAppActivity.kt
import android.annotation.SuppressLint
import android.app.Dialog
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.RecyclerView
import com.materialsouk.allcodeapp.models.AppModel
import android.content.pm.PackageInfo
import android.content.pm.ApplicationInfo
import android.os.Handler
import android.os.Looper
import android.view.Menu
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.widget.SearchView
import com.materialsouk.allcodeapp.adapters.AppAdapter
import java.util.*
import kotlin.collections.ArrayList
class AllInstalledAppActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var installedAppsList: ArrayList<AppModel>
private lateinit var installedAppAdapter: AppAdapter
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_all_installed_app)
recyclerView = findViewById(R.id.recycler_view)
val loadingDialog = Dialog(this)
loadingDialog.setContentView(R.layout.loading)
loadingDialog.window!!.setLayout(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
loadingDialog.setCancelable(false)
installedAppsList = ArrayList()
loadingDialog.show()
Handler(Looper.getMainLooper()).postDelayed({
getInstalledApps()
loadingDialog.dismiss()
findViewById<TextView>(R.id.totalInstalledApp).text =
"${getString(R.string.total_Installed_Apps)} ${installedAppsList.size}"
installedAppAdapter = AppAdapter(this, installedAppsList)
recyclerView.adapter = installedAppAdapter
}, 500)
}
@SuppressLint("QueryPermissionsNeeded")
private fun getInstalledApps(): ArrayList<AppModel> {
installedAppsList.clear()
val packs = packageManager.getInstalledPackages(0)
for (i in packs.indices) {
val p = packs[i]
if (!isSystemPackage(p)) {
val appName = p.applicationInfo.loadLabel(packageManager).toString()
val icon = p.applicationInfo.loadIcon(packageManager)
val packages = p.applicationInfo.packageName
installedAppsList.add(AppModel(appName, icon, packages))
}
}
installedAppsList.sortBy { it.getName().capitalized() }
return installedAppsList
}
private fun String.capitalized(): String {
return this.replaceFirstChar {
if (it.isLowerCase())
it.titlecase(Locale.getDefault())
else it.toString()
}
}
private fun isSystemPackage(pkgInfo: PackageInfo): Boolean {
return pkgInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.search_menu, menu)
val search = menu.findItem(R.id.app_bar_search)
val searchView = search.actionView as SearchView
searchView.maxWidth = android.R.attr.width
searchView.queryHint = "Search app name or package"
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
@SuppressLint("NotifyDataSetChanged")
override fun onQueryTextChange(newText: String?): Boolean {
val appModelArrayList: ArrayList<AppModel> = ArrayList()
for (i in installedAppsList) {
if (i.getName().lowercase(Locale.getDefault()).contains(
newText!!.lowercase(
Locale.getDefault()
)
)
||
i.getPackages().lowercase(Locale.getDefault()).contains(
newText.lowercase(
Locale.getDefault()
)
)
) {
appModelArrayList.add(i)
}
}
installedAppAdapter =
AppAdapter(this@AllInstalledAppActivity, appModelArrayList)
recyclerView.adapter = installedAppAdapter
installedAppAdapter.notifyDataSetChanged()
return true
}
})
return super.onCreateOptionsMenu(menu)
}
}