为 Android 首屏创建 AppWidget
1. [代码]MovieSearchWidget.java
package com.javacodegeeks.android.apps.moviesearchapp.widget;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.IBinder;
import android.widget.RemoteViews;
import com.javacodegeeks.android.apps.moviesearchapp.R;
import com.javacodegeeks.android.apps.moviesearchapp.model.Movie;
import com.javacodegeeks.android.apps.moviesearchapp.services.MovieSeeker;
public class MovieSearchWidget extends AppWidgetProvider {
private static final String IMDB_BASE_URL = "http://m.imdb.com/title/";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// To prevent any ANR timeouts, we perform the update in a service
context.startService(new Intent(context, UpdateService.class));
}
public static class UpdateService extends Service {
private MovieSeeker movieSeeker = new MovieSeeker();
@Override
public void onStart(Intent intent, int startId) {
// Build the widget update for today
RemoteViews updateViews = buildUpdate(this);
// Push update for this widget to the home screen
ComponentName thisWidget = new ComponentName(this, MovieSearchWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
public RemoteViews buildUpdate(Context context) {
Movie movie = movieSeeker.findLatest();
String imdbUrl = IMDB_BASE_URL + movie.imdbId;
// Build an update that holds the updated widget contents
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
updateViews.setTextViewText(R.id.app_name, getString(R.string.app_name));
updateViews.setTextViewText(R.id.movie_name, movie.name);
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.BROWSABLE");
intent.setData(Uri.parse(imdbUrl));
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
updateViews.setOnClickPendingIntent(R.id.movie_name, pendingIntent);
return updateViews;
}
@Override
public IBinder onBind(Intent intent) {
// We don't need to bind to this service
return null;
}
}
}
2. [代码]movie_search_widget.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="72dip"
android:updatePeriodMillis="10000"
android:initialLayout="@layout/widget_layout"
/>
3. [代码]/res/layout/widget_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="72dip"
android:updatePeriodMillis="10000"
android:initialLayout="@layout/widget_layout"
/>
4. [代码]/res/layout/widget_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="true"
style="@style/WidgetBackground">
<TextView
android:id="@+id/app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="14dip"
android:layout_marginBottom="1dip"
android:includeFontPadding="false"
android:singleLine="true"
android:ellipsize="end"
style="@style/Text.WordTitle" />
<TextView
android:id="@+id/movie_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/app_name"
android:paddingRight="5dip"
android:paddingBottom="4dip"
android:includeFontPadding="false"
android:lineSpacingMultiplier="0.9"
android:maxLines="4"
android:fadingEdge="vertical"
style="@style/Text.Movie" />
</RelativeLayout>
5. [代码]res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="WidgetBackground">
<item name="android:background">@drawable/widget_bg</item>
</style>
<style name="Text">
</style>
<style name="Text.Title">
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@android:color/black</item>
</style>
<style name="Text.Movie">
<item name="android:textSize">13sp</item>
<item name="android:textColor">@android:color/black</item>
</style>
</resources>
6. [代码]AndroidManifest.xml
<application android:icon="@drawable/icon" android:label="@string/app_name">
...
<!-- Broadcast Receiver that will process AppWidget updates -->
<receiver android:name=".widget.MovieSearchWidget" android:label="@string/widget_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/movie_search_widget" />
</receiver>
<!-- Service to perform web API queries -->
<service android:name=".widget.MovieSearchWidget$UpdateService" />
...
</application>