Android 创建桌面组件Widget——构建应用微件(二)

2024-03-14 05:10

本文主要是介绍Android 创建桌面组件Widget——构建应用微件(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android 创建桌面组件Widget——构建应用微件(二)

  • Android 创建桌面组件Widget——构建应用微件(二)
    • 概览
        • 使用 AppWidgetProvider 类
          • 接收应用微件广播 Intent
        • 固定应用微件
        • 设置预览图片
    • 完整代码

Android 创建桌面组件Widget——构建应用微件(一)

Android 创建桌面组件Widget——构建应用微件(二)

效果图:
创建一个可以改变大小的widget,包含一个Button和一个TextView,点击按钮跳转到指定的Activity。
请添加图片描述

概览

微件是自定义主屏幕的一个重要方面。您可以将微件想象成“一目了然”的视图,它们让最重要的应用数据和功能一览无余,从用户的主屏幕即可进行访问。用户可以在其主屏幕面板间移动微件,如果系统支持,用户还可以调整微件的大小,按照他们的偏好量身定制微件中的信息量。

使用 AppWidgetProvider 类

AppWidgetProvider类扩展了BroadcastReceiver作为一个辅助类来处理应用微件广播。AppWidgetProvider仅接收与应用微件有关的事件广播,例如当更新、删除、启用和停用应用微件时发出的广播。当发生这些广播事件时,AppWidgetProvider会接收以下方法调用:

  • onUpdate()
    调用此方法可以按AppWidgetProviderInfo中的updatePeriodMillis属性定义的时间间隔来更新应用微件。当用户添加应用微件时也会调用此方法,所以它应执行基本设置,如定义视图的事件处理脚本以及根据需要启动临时的 Service。不过,如果您已声明配置Activity,则当用户添加应用微件时不会调用此方法,但会调用它来执行后续更新。由配置Activity负责在配置完成后执行首次更新。
  • onAppWidgetOptionsChanged()
    当首次放置微件时以及每当调整微件的大小时,会调用此方法。您可以使用此回调来根据微件的大小范围显示或隐藏内容。您可以通过调用 getAppWidgetOptions() 来获取大小范围,该方法会返回包含以下各项的 Bundle
    • OPTION_APPWIDGET_MIN_WIDTH : 包含微件实例的当前宽度的下限(以 dp 为单位)。
    • OPTION_APPWIDGET_MIN_HEIGHT: 包含微件实例的当前高度的下限(以 dp 为单位)
    • OPTION_APPWIDGET_MAX_WIDTH: 包含微件实例的当前宽度的上限(以 dp 为单位)
    • OPTION_APPWIDGET_MAX_HEIGHT: 包含微件实例的当前高度的上限(以 dp 为单位)。
    • 此回调是在 API 级别 16 (Android 4.1) 中引入的。如果您实现此回调,请确保您的应用不依赖于它,因为在旧款设备上不会调用它。
  • onDeleted(Context, int[])
    每次从应用微件托管应用中删除应用微件时,都会调用此方法。
  • onEnabled(Context)
    首次创建应用微件的实例时,会调用此方法。例如,如果用户添加应用微件的两个实例,只有首次添加时会调用此方法。如果您需要打开一个新的数据库或执行只需要对所有应用微件实例执行一次的其他设置,则此方法非常合适。
  • onDisabled(Context)
    从应用微件托管应用中删除了应用微件的最后一个实例时,会调用此方法。您应使用此方法来清理在 onEnabled(Context)中完成的所有工作,如删除临时数据库。
  • ``
    针对每个广播调用此方法,并且是在上述各个回调方法之前调用。您通常不需要实现此方法,因为默认的 AppWidgetProvider 实现会过滤所有应用微件广播并视情况调用上述方法。

最重要的 AppWidgetProvider 回调是 onUpdate(),因为向托管应用添加每个应用微件时都会调用它(除非您使用配置 Activity)。如果应用微件接受任何用户交互事件,则您需要在此回调中注册事件处理脚本。如果应用微件未创建临时文件或数据库,或者未执行其他需要清理的工作,则 onUpdate() 可能是您需要定义的唯一一个回调方法。例如,如果您希望应用微件具有一个在用户点击时会启动 Activity 的按钮,则可以使用以下 AppWidgetProvider 实现:

public class ExampleAppWidgetProvider extends AppWidgetProvider {public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {final int N = appWidgetIds.length;// Perform this loop procedure for each App Widget that belongs to this providerfor (int i=0; i<N; i++) {int appWidgetId = appWidgetIds[i];// Create an Intent to launch ExampleActivityIntent intent = new Intent(context, ExampleActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);// Get the layout for the App Widget and attach an on-click listener// to the buttonRemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);views.setOnClickPendingIntent(R.id.button, pendingIntent);// Tell the AppWidgetManager to perform an update on the current app widgetappWidgetManager.updateAppWidget(appWidgetId, views);}}
}
接收应用微件广播 Intent

AppWidgetProvider 只是一个辅助类。如果您希望直接接收应用微件广播,您可以实现自己的 BroadcastReceiver 或替换 onReceive(Context, Intent) 回调。您需要关注的 Intent 如下所示:

ACTION_APPWIDGET_UPDATE
ACTION_APPWIDGET_DELETED
ACTION_APPWIDGET_ENABLED
ACTION_APPWIDGET_DISABLED
ACTION_APPWIDGET_OPTIONS_CHANGED

固定应用微件

在搭载 Android 8.0(API 级别 26)及更高版本的设备上,允许您创建固定的快捷方式的启动器也允许您将应用微件固定到启动器上。与固定的快捷方式类似,这些固定的微件也能让用户访问应用中的特定任务。

在您的应用中,您可以创建一个请求,让系统将微件固定到支持的启动器上,只需完成下面一系列步骤即可:

  1. 在应用的清单文件中创建微件,如以下代码段所示:
    <manifest>...<application>...<receiver android:name="MyAppWidgetProvider"><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter><meta-data android:name="android.appwidget.provider"android:resource="@xml/my_appwidget_info" /></receiver></application></manifest>
  1. 调用 requestPinAppWidget() 方法,如以下代码段所示:
    AppWidgetManager appWidgetManager =context.getSystemService(AppWidgetManager.class);ComponentName myProvider =new ComponentName(context, MyAppWidgetProvider.class);if (appWidgetManager.isRequestPinAppWidgetSupported()) {// Create the PendingIntent object only if your app needs to be notified// that the user allowed the widget to be pinned. Note that, if the pinning// operation fails, your app isn't notified.Intent pinnedWidgetCallbackIntent = new Intent( ... );// Configure the intent so that your app's broadcast receiver gets// the callback successfully. This callback receives the ID of the// newly-pinned widget (EXTRA_APPWIDGET_ID).PendingIntent successCallback = PendingIntent.getBroadcast(context, 0,pinnedWidgetCallbackIntent, PendingIntent.FLAG_UPDATE_CURRENT);appWidgetManager.requestPinAppWidget(myProvider, null, successCallback);}

注意:如果无需通知您的应用系统是否已成功地将微件固定到受支持的启动器上,则您可以将 null 作为 requestPinAppWidget() 的第三个参数传入。

设置预览图片

Android 3.0 引入了 previewImage 字段,用于指定预览来描绘应用微件是什么样子的。此预览通过微件选择器显示给用户。如果未提供此字段,则应用微件的图标将用于预览。

在 XML 中指定此设置的方式如下:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"...android:previewImage="@drawable/preview"></appwidget-provider>

为了帮助创建应用微件的预览图片(在previewImage字段中指定),Android 模拟器包含一个名为“微件预览”的应用。要创建预览图片,请启动此应用,为您的应用选择应用微件并设置您希望如何显示预览图片,然后将其保存并放在您的应用的可绘制资源中。

完整代码

  1. ExampleAppWidgetProvider.java 文件
public class ExampleAppWidgetProvider extends AppWidgetProvider {private static final String TAG = "ExampleAppWidgetProvider";@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {Log.i(TAG, "onUpdate: ");for (int appWidgetId : appWidgetIds) {updateAppWidget(context, appWidgetManager, appWidgetId);}time = System.currentTimeMillis();}private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {RemoteViews view = new RemoteViews(context.getPackageName(), R.layout.widget_content);// 点击桌面组件中的按钮,跳转到主界面Intent i = new Intent(context, MainActivity.class);PendingIntent intent = PendingIntent.getActivity(context, 0, i, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);view.setOnClickPendingIntent(R.id.btn_click, intent);
//        view.setTextViewText(R.id.tv_info, "clicked");appWidgetManager.updateAppWidget(appWidgetId, view);}
}
  1. layout/widget_content.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:orientation="vertical"><Buttonandroid:id="@+id/btn_click"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="click me"/><TextViewandroid:id="@+id/tv_info"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="hello, this is appwidget"android:layout_centerHorizontal="true"android:layout_alignParentBottom="true"/></RelativeLayout>
  1. xml/example_appwidget_info.xml文件
<?xml version="1.0" encoding="utf-8"?>
<appwidget-providerxmlns:android="http://schemas.android.com/apk/res/android"android:initialKeyguardLayout="@layout/widget_content"android:initialLayout="@layout/widget_content"android:minHeight="110dp"android:minWidth="180dp"android:previewImage="@drawable/ic_launcher_foreground"android:resizeMode="vertical|horizontal"android:updatePeriodMillis="600000"android:widgetCategory="home_screen"></appwidget-provider>
  1. AndroidManifest.xml文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.csu.mywidget"><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyExample"><receiverandroid:name=".ExampleAppWidgetProvider"android:enabled="true"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/example_appwidget_info"/></receiver><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

参考:
https://developer.android.google.cn/guide/practices/ui_guidelines/widget_design
https://developer.android.google.cn/guide/topics/appwidgets#collection_sample
https://blog.csdn.net/tracydragonlxy/article/details/127231654?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22127231654%22%2C%22source%22%3A%22tracydragonlxy%22%7D

这篇关于Android 创建桌面组件Widget——构建应用微件(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/807293

相关文章

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

JSONArray在Java中的应用操作实例

《JSONArray在Java中的应用操作实例》JSONArray是org.json库用于处理JSON数组的类,可将Java对象(Map/List)转换为JSON格式,提供增删改查等操作,适用于前后端... 目录1. jsONArray定义与功能1.1 JSONArray概念阐释1.1.1 什么是JSONA

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提