本篇主要对appwidget开发进行简单介绍,为后续漏洞挖掘相关做前置铺垫
appwidget简介
官方解释如下:
- 应用微件是可以嵌入其他应用(如主屏幕)并接收定期更新的微型应用视图。这些视图称为界面中的微件,您可以使用应用微件提供程序发布微件。能够容纳其他应用微件的应用组件称为应用微件托管应用。下面的屏幕截图显示了音乐应用微件。
实际也就是桌面的小组件,现在的主流app基本都会搞这个东西,如下
appwidget开发流程
androidmanifest.xml声明receiver
定义appwidget的元数据【基本特性样式】
书写appwidget的layout布局文件
实现extends AppWidgetProvider的widget
1.androidmanifest声明
<receiverandroid:name=".NewAppWidget"android:exported="false"><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter><meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/new_app_widget_info" /></receiver>
2.AppWidgetProviderInfo 元数据
demo
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"android:description="@string/app_widget_description"android:initialKeyguardLayout="@layout/new_app_widget"android:initialLayout="@layout/new_app_widget"android:minWidth="40dp"android:minHeight="40dp"android:previewImage="@drawable/example_appwidget_preview"android:previewLayout="@layout/new_app_widget"android:resizeMode="horizontal|vertical"android:targetCellWidth="1"android:targetCellHeight="1"android:updatePeriodMillis="86400000"android:widgetCategory="home_screen" />
一些属性注解
- initialLayout:指定微件的布局资源
- minWidth、minHeight:默认情况下微件的最小占用空间
- minResizeWidth、minResizeHeight:微件的绝对最小大小。意思这个是下限,小于这个标准微件就不能用了
- minResizeWidth、minResizeHeight:指定微件可以调整到的最小宽高
- previewImage:微件的预览显示设置
- resizeMode:设置微件大小调整的规则
- horizontal
- vertical
- none【默认】
- widgetCategory:微件是否可以显示在主屏幕 (home_screen) 以及锁定屏幕 (keyguard)上【高于android5.0则只有home_screen可用】
- configure:配置微件的activity【可选】
- updatePeriodMillis:配合下面的onUpdate回调方法,确定微件的更新频率
3.layout布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"style="@style/Widget.Appwidget.AppWidget.Container"android:layout_width="match_parent"android:layout_height="match_parent"android:theme="@style/Theme.Appwidget.AppWidgetContainer"><TextViewandroid:id="@+id/appwidget_text"style="@style/Widget.Appwidget.AppWidget.InnerView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_centerVertical="true"android:layout_margin="8dp"android:contentDescription="@string/appwidget_text"android:text="@string/appwidget_text"android:textSize="24sp"android:textStyle="bold|italic" />
</RelativeLayout>
支持的布局
- RemoteViews 对象
- FrameLayout
- LinearLayout
- RelativeLayout
- GridLayout
- ViewStub
- 微件类【不支持下列类的后代】
- AnalogClock
- Button
- Chronometer
- ImageButton
- ImageView
- ProgressBar
- TextView
- ViewFlipper
- ListView
- GridView
- StackView
- AdapterViewFlipper
4.AppWidgetProvider的周期函数
onUpdate()【核心】(默认生成)
- 按照指定的时间间隔
updatePeriodMillis
更新微件 - 还有一个规则
- 如果声明配置了对应的activity,则在微件被创建时由activity来执行首次更新
- 如果没有配置对应的activity,则在微件被创建时该方法也会被调用
@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {// There may be multiple widgets active, so update all of themfor (int appWidgetId : appWidgetIds) {updateAppWidget(context, appWidgetManager, appWidgetId);}}
onAppWidgetOptionsChanged()
- 每次调整应用微件大小的时候会被调用
@Overridepublic void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);}
onDeleted(Context, int[])
- 每次删除应用微件实例的时候会被调用
@Overridepublic void onDeleted(Context context, int[] appWidgetIds) {super.onDeleted(context, appWidgetIds);}
onEnabled(Context)(默认生成)
- 首次创建应用微件实例的时候会被调用【数据库创建打开等】
@Overridepublic void onEnabled(Context context) {// Enter relevant functionality for when the first widget is created}
onDisabled(Context)(默认生成)
- 删除应用微件的最后一个实例时会被调用【删除数据库等】
@Overridepublic void onDisabled(Context context) {// Enter relevant functionality for when the last widget is disabled}
onReceive(Context, Intent)
- 针对每个广播调用该方法
@Overridepublic void onReceive(Context context, Intent intent) {super.onReceive(context, intent);}
如果想看实际效果的话,可以直接android studio建一个默认的appwidget,然后分析生成的源码
官方链接