本篇主要对appwidget开发进行简单介绍,为后续漏洞挖掘相关做前置铺垫
appwidget简介
官方解释如下:
- 应用微件是可以嵌入其他应用(如主屏幕)并接收定期更新的微型应用视图。这些视图称为界面中的微件,您可以使用应用微件提供程序发布微件。能够容纳其他应用微件的应用组件称为应用微件托管应用。下面的屏幕截图显示了音乐应用微件。
实际也就是桌面的小组件,现在的主流app基本都会搞这个东西,如下
appwidget开发流程
androidmanifest.xml声明receiver
定义appwidget的元数据【基本特性样式】
书写appwidget的layout布局文件
实现extends AppWidgetProvider的widget
1.androidmanifest声明
<receiver
android:name=".NewAppWidget"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android: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">
<TextView
android: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,则在微件被创建时该方法也会被调用
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
onAppWidgetOptionsChanged()
- 每次调整应用微件大小的时候会被调用
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
}
onDeleted(Context, int[])
- 每次删除应用微件实例的时候会被调用
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
onEnabled(Context)(默认生成)
- 首次创建应用微件实例的时候会被调用【数据库创建打开等】
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
onDisabled(Context)(默认生成)
- 删除应用微件的最后一个实例时会被调用【删除数据库等】
@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
onReceive(Context, Intent)
- 针对每个广播调用该方法
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
如果想看实际效果的话,可以直接android studio建一个默认的appwidget,然后分析生成的源码
官方链接