文章目录
- Launcher简介
- 注册AndroidManifest
- 使用PackageManager扫描所有app
- 显示app信息,添加点击事件
Launcher简介
Launcher就是Android系统的桌面,它也是一个app,用于管理其他的app。
注册AndroidManifest
要让app作为Launcher,需要在Manifest中添加两个category:
<activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.HOME"/><category android:name="android.intent.category.DEFAULT"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter>
</activity>
此时安装此app之后,点击Home键就会看到以下界面,让你选择使用哪一个桌面应用:
如果选择我们自己开发的 LauncherDemo,就会启动 LauncherDemo 应用。
使用PackageManager扫描所有app
编辑MainActivity:
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)initView()}private fun initView() {val apps = scanApps()val adapter = AppAdapter(apps)rvApps.layoutManager = GridLayoutManager(this, 3)rvApps.adapter = adapter}private fun scanApps():List<ResolveInfo>{val intent = Intent(Intent.ACTION_MAIN, null).apply {addCategory(Intent.CATEGORY_LAUNCHER)}return packageManager.queryIntentActivities(intent, 0)}
}
我们在MainActivity中使用PackageManager的queryIntentActivities
方法扫描出手机上已安装的所有app信息。
activity_main 布局代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rvApps"android:layout_width="match_parent"android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
由于布局中使用了 RecyclerView,记得导入 RecyclerView 库:
implementation 'androidx.recyclerview:recyclerview:1.1.0'
显示app信息,添加点击事件
新建AppAdapter类:
class AppAdapter(private val apps: List<ResolveInfo>) : RecyclerView.Adapter<AppAdapter.AppHolder>() {private lateinit var context: Contextclass AppHolder(itemView: View) : RecyclerView.ViewHolder(itemView)override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppHolder {context = parent.contextval view = View.inflate(context, R.layout.item_app, null)return AppHolder(view)}override fun getItemCount(): Int {return apps.size}override fun onBindViewHolder(holder: AppHolder, position: Int) {val resolveInfo = apps[position]val activityInfo = resolveInfo.activityInfoholder.itemView.ivIcon.setImageDrawable(activityInfo.loadIcon(context.packageManager))holder.itemView.tvName.text = resolveInfo.loadLabel(context.packageManager)holder.itemView.setOnClickListener {val intent = Intent().apply {component = ComponentName(activityInfo.packageName, activityInfo.name)}context.startActivity(intent)}}
}
在此类中使用activityInfo.loadIcon
方法加载app图标,使用resolveInfo.loadLabel
方法加载app名字,并且添加了点击启动对应app的点击事件。
item_app布局文件如下:
<?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"android:padding="10dp"><ImageViewandroid:id="@+id/ivIcon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:maxWidth="36dp"android:maxHeight="36dp"app:layout_constraintBottom_toTopOf="@id/tvName"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"tools:src="@mipmap/ic_launcher" /><TextViewandroid:id="@+id/tvName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:ellipsize="end"android:lines="1"android:singleLine="true"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/ivIcon"tools:text="@string/app_name" /></androidx.constraintlayout.widget.ConstraintLayout>
运行程序,效果图如下: