在开发自定义 Android Launcher 应用时,添加支持桌面小组件(App Widgets)是一个重要的功能。以下是一个基本的步骤指南,帮助你在自定义 Launcher 应用中添加和管理小组件。
1. 设置权限和声明 App Widget Host
首先,你需要在 AndroidManifest.xml
文件中声明必要的权限,并添加 AppWidgetProvider
接收器:
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
...>
<receiver android:name=".MyAppWidgetProvider" android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_provider" />
</receiver>
</application>
2. 创建 App Widget Host
为了管理小组件,你需要创建一个 AppWidgetHost
。这通常在你的主活动中实现:
Java 示例
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
public class DemoActivity extends AppCompatActivity {
private static final int APPWIDGET_HOST_ID = 1024;
private static final int REQUEST_PICK_APPWIDGET = 1;
private static final int REQUEST_CREATE_APPWIDGET = 2;
private AppWidgetManager appWidgetManager;
private AppWidgetHost appWidgetHost;
private LinearLayout widgetContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
widgetContainer = findViewById(R.id.widget_container);
appWidgetManager = AppWidgetManager.getInstance(this);
appWidgetHost = new AppWidgetHost(this, APPWIDGET_HOST_ID);
appWidgetHost.startListening();
}
public void addWidget(View view) {
int appWidgetId = appWidgetHost.allocateAppWidgetId();
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_PICK_APPWIDGET && resultCode == RESULT_OK) {
int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
if (appWidgetId != -1) {
AppWidgetProviderInfo appWidgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
Log.d("TAG", "appWidgetId:"+appWidgetId + ", appWidgetInfo.configure:"+appWidgetInfo.configure);
if (appWidgetInfo.configure != null) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
intent.setComponent(appWidgetInfo.configure);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
} else {
addAppWidget(appWidgetId);
}
}
} else if (requestCode == REQUEST_CREATE_APPWIDGET && resultCode == RESULT_OK) {
int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
Log.d("TAG", "appWidgetId:"+appWidgetId);
addAppWidget(appWidgetId);
}
super.onActivityResult(requestCode, resultCode, data);
}
private void addAppWidget(int appWidgetId) {
Log.d("TAG", "appWidgetId:"+appWidgetId);
AppWidgetProviderInfo appWidgetInfo = appWidgetManager.getAppWidgetInfo(appWidgetId);
AppWidgetHostView hostView = appWidgetHost.createView(this, appWidgetId, appWidgetInfo);
hostView.setAppWidget(appWidgetId, appWidgetInfo);
widgetContainer.addView(hostView);
}
@Override
protected void onDestroy() {
super.onDestroy();
appWidgetHost.stopListening();
}
}
3. 配置 App Widget Provider
你需要在 res/xml/
目录下创建一个 XML 文件(例如 appwidget_provider.xml
),来定义小组件的元数据:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/widget_layout" />
4. 创建一个小组件布局
在 res/layout/
目录下创建一个布局文件(例如 widget_layout.xml
),定义小组件的外观:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TextView
android:id="@+id/widget_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Widget"
android:textSize="20sp" />
</RelativeLayout>
5. 实现 App Widget Provider 类
创建一个类来处理小组件的行为(例如 MyAppWidgetProvider.java
或 MyAppWidgetProvider.kt
):
Java 示例
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
public class MyAppWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setTextViewText(R.id.widget_text, "Hello Widget");
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
当然,这里是一个 activity_launcher.xml
文件的示例,包含用于显示小组件的容器和添加小组件的按钮:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:padding="16dp"
tools:context=".LauncherActivity">
<!-- 添加小组件的按钮 -->
<Button
android:id="@+id/add_widget_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Widget"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp"
android:onClick="addWidget" />
<!-- 小组件容器 -->
<LinearLayout
android:id="@+id/widget_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/add_widget_button"
android:orientation="vertical"
android:padding="16dp">
</LinearLayout>
</RelativeLayout>
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)
PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题