本周早些时候,我问了一个类似的问题,但我仍然不明白如何获得所有已安装的应用程序的列表,然后选择一个运行。
我试过了:
Intent intent = new Intent(ACTION_MAIN);
intent.addCategory(CATEGORY_LAUNCHER);
这只显示预安装或可以运行ACTION_MAIN Intent类型的应用程序。
我也知道我可以使用PackageManager来获取所有已安装的应用程序,但我如何使用它来运行特定的应用程序呢?
本周早些时候,我问了一个类似的问题,但我仍然不明白如何获得所有已安装的应用程序的列表,然后选择一个运行。
我试过了:
Intent intent = new Intent(ACTION_MAIN);
intent.addCategory(CATEGORY_LAUNCHER);
这只显示预安装或可以运行ACTION_MAIN Intent类型的应用程序。
我也知道我可以使用PackageManager来获取所有已安装的应用程序,但我如何使用它来运行特定的应用程序呢?
当前回答
获取所有应用程序:
PackageManager pm = getContext().getPackageManager();
List<ApplicationInfo> apps = pm.getInstalledApplications(0);
检查是否安装了应用程序,然后打开:
if((app.flags & (ApplicationInfo.FLAG_UPDATED_SYSTEM_APP | ApplicationInfo.FLAG_SYSTEM)) > 0) {
String app_package = app.packageName;
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(app_package);
context.startActivity(launchIntent);
其他回答
这个答案是正确的一个列表安装的应用程序显示和搜索功能添加。
科特林
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
}
}
这是菜单 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)
}
}
public static List<ApplicationInfo> getApplications(Context context) {
return context.getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA);
}
获取已安装的非系统应用程序列表
public static void installedApps()
{
List<PackageInfo> packList = getPackageManager().getInstalledPackages(0);
for (int i=0; i < packList.size(); i++)
{
PackageInfo packInfo = packList.get(i);
if ( (packInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
{
String appName = packInfo.applicationInfo.loadLabel(getPackageManager()).toString();
Log.e("App № " + Integer.toString(i), appName);
}
}
}
干净的解决方案,过滤成功的系统应用程序
这个解决方案背后的思想是,每个系统应用程序的主活动都没有一个自定义的活动图标。这个方法给了我一个很好的结果:
public static Set<PackageInfo> getInstalledApps(Context ctx) {
final PackageManager packageManager = ctx.getPackageManager();
final List<PackageInfo> allInstalledPackages = packageManager.getInstalledPackages(PackageManager.GET_META_DATA);
final Set<PackageInfo> filteredPackages = new HashSet();
Drawable defaultActivityIcon = packageManager.getDefaultActivityIcon();
for(PackageInfo each : allInstalledPackages) {
if(ctx.getPackageName().equals(each.packageName)) {
continue; // skip own app
}
try {
// add only apps with application icon
Intent intentOfStartActivity = packageManager.getLaunchIntentForPackage(each.packageName);
if(intentOfStartActivity == null)
continue;
Drawable applicationIcon = packageManager.getActivityIcon(intentOfStartActivity);
if(applicationIcon != null && !defaultActivityIcon.equals(applicationIcon)) {
filteredPackages.add(each);
}
} catch (PackageManager.NameNotFoundException e) {
Log.i("MyTag", "Unknown package name " + each.packageName);
}
}
return filteredPackages;
}
你可以通过下面的代码找到Android设备中已安装的应用程序列表,“packageInfo”包含已安装的应用程序信息 在设备。我们可以为安装的应用程序检索Intent packageinfo对象可以使用startactivity(intent)来启动 应用程序。这取决于你如何组织UI或Listview 或显示数据表格。基于位置的点击事件,你可以检索意图 对象和启动活动意图。
final PackageManager pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages)
{
if(pm.getLaunchIntentForPackage(packageInfo.packageName)!= null &&
!pm.getLaunchIntentForPackage(packageInfo.packageName).equals(""))
{
System.out.println("Package Name :" + packageInfo.packageName);
System.out.println("Launch Intent For Package :" +
pm.getLaunchIntentForPackage(packageInfo.packageName));
System.out.println("Application Label :" + pm.getApplicationLabel(packageInfo));
System.out.println("Application Label :" +
pm.getApplicationIcon(packageInfo.packageName).toString());
System.out.println("i : "+i);
/*if(i==2)
{
startActivity(pm.getLaunchIntentForPackage(packageInfo.packageName));
break;
}*/
i++;
}
}