Android Widgets
Android Widgets are small applications that can be embedded in other applications such as a home screen or a lock screen and receive periodic updates. These elements run as a part of a process of a main application, but don't require running the main application explicitly.
Widget use RemoteViews object to provide self user interface. Class of this object describes a view hierarchy that can be displayed in another process. RemoteViews imposes some restrictions on the usage of view and layout types. You can’t use custom elements in widget, but if you still want to use a custom font, for example, then you have to translate it into a ImageView and send to the RemoteViews object. The list of supported views and layouts can be found on the AppWidgets on Google Developer Portal
There can be widgets of any size, but Google recommends a formula to calculate the widget size: ((Number of columns / rows) * 74) 2.
To create a widget you need to implement layout xml file. Secondly, you need to create a class that will extend a class AppWidgetProvide and contains the life cycle callbacks of widgets.
public class MyWidgetProvider extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.image, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
onUpdate method will be called depending on the update period, it is necessary to perform actions that change the state of the widget. Also in the manifest of your application you must define the widget, in order to do this add the receiver and intent filter, for example:
<?xml version="1.0" encoding="utf8"?>
<appwidgetprovider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget_loading"android:configure=
"com.example.app.widget.WidgetConfigureActivity"
android:minHeight="144dp"
android:minResizeHeight="144dp"
android:minResizeWidth="250dp"
android:minWidth="250dp"
android:previewImage="@drawable/ic_launcher"
android:resizeMode="vertical|horizontal"
android:updatePeriodMillis="86400000"
android:widgetCategory="keyguard|home_screen" />
Google recommends to set up at least one hour of the minimum period of update of your Android mobile application widget(s) so you could save the battery level. If you want to avoid this limitation and update your widget more often, you'll have to use an AlarmManager and additionally set pdatePeriodMillis parameter to ”0”.
private void startRepeating(Context context) {
final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), UPDATE_PERIOD, serviceIntent);
}
private void cancelRepeating(Context context) {
final AlarmManager alarmManager = (AlarmManager)
context.getSystemService(Context.ALARM_SERVICE);
if (serviceIntent != null) {
alarmManager.cancel(serviceIntent);
}
}
Using of AlarmManager supposes to move updates logic of the widget to Service or IntentService.
public class UpdateWidgetService extends IntentService {
private AppWidgetManager appWidgetManager;
private RemoteViews remoteViews;
public UpdateWidgetService() {
super("UpdateWidgetService");
}
@Override
protected void onHandleIntent(Intent intent) {
appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS)
for (int widgetId : allWidgetIds) {
// TODO: refresh logic.
}
}
}
Android widgets are a great way to show off its customization flexibility, allowing a home screen to be made as functional as possible and be tailored to the user's needs.
As usually we are waiting for your comments :)