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

news/2024/4/19 19:01:25/文章来源:https://blog.csdn.net/tracydragonlxy/article/details/128097070

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_38801.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LVS-DR模式单网段和多网段案例实现

1 实验环境&#xff1a; 一台&#xff1a;客户端 eth0:仅主机 192.168.10.8/24 GW:192.168.10.18一台&#xff1a;ROUTER eth0 :NAT 192.168.100.18/24 eth1: 仅主机 192.168.10.18/24 启用 IP_FORWARD一台&#xff1a;LVS eth0:NAT:DIP:192.168.100.48/24 GW:192.168.100.18两…

大数据必学Java基础(一百零八):过滤器的生命周期

文章目录 过滤器的生命周期 一、构造方法 二、初始化方法 三、拦截请求方法

【AI学习笔记】TensorFlow GPU版本的安装(超详细)

安装步骤&#xff1a;1. 确认显卡是否支持CUDA2. 安装CUDA3. 安装cuDNN3.1 安装 cudnn3.2 将cudnn64_8.dll存放的位置加入Path环境变量4. 安装TensorFlow GPU版本4.1 在Anaconda建立TensorFlow GPU虚拟环境4.2 安装Tensorflow-gpu4.3 安装Keras总结1. 确认显卡是否支持CUDA 在…

供应荧光染料AF532 活性酯,AF532-NHS,CAS:477876-64-5

一&#xff1a;产品描述 1、名称 AF5 532酯 AF532-NHS AF532 活性酯 Alexa Fluor 532 AF532 NHS ester 2、CAS编号&#xff1a;477876-64-5 3、分子式&#xff1a;C34H33N3O11S2 4、分子量&#xff1a;723.77 5、质量控制&#xff1a;95% 6、储存&#xff1a; -20…

Arduino开发实例-DIY酒精浓度检测计

DIY酒精浓度检测计 在本文中,将详细介绍如何创建一个简单的酒精检测器。 它可以在各种应用领域中使用。市场上有许多先进的酒精传感器,价格合理,但我们在这里使用一些基本的微控制器来制作这个项目,如 Arduino、LED、蜂鸣器和 MQ3 酒精传感器。 1、MQ-3传感器介绍 MQ-3传…

A*算法-Python实现

好久没有在CSDN上发文章了&#xff0c;快一年了吧。这两天重新登录了一下&#xff0c;不看不知道&#xff0c;一看吓一跳&#xff0c;没想到访问量快13万了。 之前写博客的时候&#xff0c;想着把一些有用的东西写下来&#xff0c;一方面是当做笔记了&#xff0c;免得以后忘记…

5G无线技术基础自学系列 | SU-MIMO原理

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 通过多天线技术支持单用户在上下行数据…

Vue3框架中路由的使用和局部刷新的功能(第十一课)

使用vue-router的步骤:p第一步&#xff1a;创建路由需要映射的组件&#xff08;打算显示的页面&#xff09;&#xff1b;p第二步&#xff1a;通过createRouter创建路由对象&#xff0c;并且传入routes和history模式&#xff1b;配置路由映射: 组件和路径映射关系的routes数组&a…

DFL3:软件版本的选择和安装详解

这本是一个简单的问题&#xff0c;但是对于新手而言&#xff0c;所有问题&#xff0c;总是说的越清楚越仔细越好。我之所以这么说&#xff0c;肯定是有人问了。所以我就专门开一篇文章来说一说&#xff0c;软件版本的异同&#xff0c;以及如何选择。针对不同的语言&#xff0c;…

mysql相关基础知识篇(五)

1.MySQL 事务的四大特性说一下&#xff1f; 原子性&#xff1a;事务作为一个整体被执行&#xff0c;包含在其中的对数据库的操作要么全部被执行&#xff0c;要么都不执行。一致性&#xff1a;指在事务开始之前和事务结束以后&#xff0c;数据不会被破坏&#xff0c;假如 A 账户…

(2)点云库处理学习——剔除点云值

1、主要参考 1.1参考地址 (1) 点云离群点剔除 — open3d python_Coding的叶子的博客-CSDN博客_离群点去除 (2) open3d之点云异常值去除&#xff08;笔记5&#xff09;_Satellite_H的博客-CSDN博客 (3)斯坦福经典兔子的点云数据下载地址 下载地址 Model : Bunny 1.2兔子…

Git 打patch (打补丁)的使用

patch 的使用 一般是diff ,apply ,format-patch,am 1 生成patch git diff > test.patch 这个是打补丁(test.patch自己取的名字,这个命令可以看出没有指定修改的问题所以默认把所有修改的文件都打patch了,同时还需要注意,这里是本地修改的没有执行add缓存的) 如果想指定某…

[附源码]计算机毕业设计SpringBoot高血压分析平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

时序特征提取工具

在选择了需要提取的特征&#xff0c;确定了时序数据特征提取数据集的长度并对先验知识建模之后&#xff0c;就需要利用工具搭建特征提取系统。科研机构围绕不同问题域搭建的开源时序数据特征提取工具已经不少&#xff0c;我们可以利用这些工具快速实现希望达成的算法效果。下面…

驱动——platform驱动总线三种匹配方式

三种platform驱动匹配方式代码案例以及现象 方式一&#xff1a;通过设置名字进行匹配 相关API简介&#xff1a; 1、platform_device的API ①分配对象 struct platform_device { const char *name;//用于进行匹配的名字 int id;//总线号 PLATFORM_DEVID_AUTO&#xff08;自…

ARM cortex-A7核UART实验 收发数据

头文件&#xff1a; 1 #ifndef __UART4_H__ 2 #define __UART4_H__ 3 4 #include "../common/include/stm32mp1xx_rcc.h" 5 #include "..…

【Android App】获取照片里的位置信息及使用全球卫星导航系统(GNSS)获取位置实战(附源码和演示 超详细)

需要全部代码请点赞关注收藏后评论区留言私信~~~ 一、获取照片里的位置信息 手机拍摄的相片还保存着时间、地点、镜头参数等信息&#xff0c;这些信息由相片接口工具ExifInterface管理&#xff0c;它的常用方法说明如下&#xff1a; getLatLong&#xff1a;获取相片拍摄时候的…

【人工智能 机器学习 深度学习】基础选择题1~30题 练习

目录 一、1~10题1.1 题目1.2 答案二、11~20题2.1 题目2.2 答案三、21~30题3.1 题目3.2 答案写在前面:适用于对 人工智能&机器学习&深度学习 进行复习的同学,同时,也可以通过基础题目的练习,加深理解。 一、1~10题 均是先给出10道题目,而后给出 10道题目的答案。 …

Python用广义加性模型GAM进行时间序列分析

每当你发现一个与时间对应的趋势时&#xff0c;你就会看到一个时间序列。我们围绕广义加性模型GAM技术进行一些咨询&#xff0c;帮助客户解决独特的业务问题。研究金融市场表现和天气预报的事实上的选择&#xff0c;时间序列是最普遍的分析技术之一&#xff0c;因为它与时间有着…

关于TreeView的简单使用(Qt6.4.1)

前言 TreeView是在Qt6.3中加入的&#xff0c;弥补了Qt中无官方树图。笔者上手尝试了下&#xff0c;虽然有点麻烦&#xff0c;但官方也做了不少简化。 本次教程&#xff0c;笔者创建一个简单的示例&#xff0c;以帮助读者使用TreeView。 一、创建模型类 当前模型需要使用C定义…