// ******************************************************************* //
// ** Chapter 10 Code Listings ** //
// ** Professional Android 2 Application Development ** //
// ** Reto Meier ** //
// ** (c)2010 Wrox ** //
// ******************************************************************* //
// ** App Wigets ************************************************** //
// *******************************************************************
// ** LISTING 10-1: App Widget XML layout resource
// *******************************************************************
// ** LISTING 10-2: App Widget Provider definition
// *******************************************************************
// ** LISTING 10-3: App Widget implementation
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
public class MyAppWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// TODO Update the Widget UI.
}
}
// *******************************************************************
// ** LISTING 10-4: App Widget manifest node
// *******************************************************************
// ** LISTING 10-5: Using Remote Views
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_remote_layout);
// Get the App Wiget Manager.
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
// Retrieve the identifiers for each instance of your chosen widget.
ComponentName thisWidget = new ComponentName(context, MyAppWidget.class);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
appWidgetManager.updateAppWidget(appWidgetIds, views);
// *******************************************************************
// ** LISTING 10-6: A standard pattern for updating Widget UI
final int N = appWidgetIds.length;
// Iterate through each widget, creating a RemoteViews object and
// applying the modified RemoteViews to each widget.
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
// Create a Remove View
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_widget_layout);
// TODO Update the widget UI using the views object.
// Notify the App Widget Manager to update the widget using
// the modified remote view.
appWidgetManager.updateAppWidget(appWidgetId, views);
}
// *******************************************************************
// ** LISTING 10-7: Using a Remote View within the App Widget Provider’s onUpdate Handler
@Override
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];
// Create a Remove View
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.my_widget_layout);
// TODO Update the UI.
// Notify the App Widget Manager to update the widget using
// the modified remote view.
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
// *******************************************************************
// ** LISTING 10-8: Using a Remote View to modify App Widget UI
// Set the image level for an ImageView.
views.setInt(R.id.widget_image_view, "setImageLevel", 2);
// Show the cursor of a TextView.
views.setBoolean(R.id.widget_text_view, "setCursorVisible", true);
// Assign a bitmap to an ImageButton.
views.setBitmap(R.id.widget_image_button, "setImageBitmap", myBitmap);
// *******************************************************************
// ** LISTING 10-9: Modifying View properties within an App Widget Remote View
// Update a Text View
views.setTextViewText(R.id.widget_text_view, "Updated Text");
views.setTextColor(R.id.widget_text_view, Color.BLUE);
// Update an Image View
views.setImageViewBitmap(R.id.widget_image_view, myBitmap);
// Update a Progress Bar
views.setProgressBar(R.id.widget_progressbar, 100, 50, false);
// Update a Chronometer
views.setChronometer(.id.widget_chronometer,
SystemClock.elapsedRealtime(), null, true);
// *******************************************************************
// ** LISTING 10-10: Adding a Click Listener to an App Widget
Intent intent = new Intent("com.paad.ACTION_WIDGET_CLICK");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
views.setOnClickPendingIntent(R.id.my_text_view, pendingIntent);
// *******************************************************************
// ** LISTING 10-11: A Selection State Drawable resource for an App Widget
// *******************************************************************
// ** LISTING 10-12: Setting the App Widget minimum update rate
// *******************************************************************
// ** LISTING 10-13: Listening for Intent broacasts within App Widgets
// *******************************************************************
// ** LISTING 10-14: Updating App Widgets based on broadcast Intents
public static String FORCE_WIDGET_UPDATE = "com.paad.chapter9.FORCE_WIDGET_UPDATE";
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (FORCE_WIDGET_UPDATE.equals(intent.getAction())) {
// TODO Update widget UI.
}
}
// ** Live Folders ************************************************ //
// *******************************************************************
// ** LISTING 10-15: Creating a projection to support a Live Folder
final HashMap liveFolderProjection = new HashMap();
liveFolderProjection.put(LiveFolders._ID, KEY_ID + " AS " + LiveFolders._ID);
liveFolderProjection.put(LiveFolders.NAME, KEY_NAME_COLUMN + " AS " + LiveFolders.NAME);
liveFolderProjection.put(LiveFolders.DESCRIPTION, KEY_DESCRIPTION_COLUMN + " AS " + LiveFolders.DESCRIPTION);
liveFolderProjection.put(LiveFolders.IMAGE, KEY_IMAGE_COLUMN + " AS " + LiveFolders.IMAGE);
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(MY_TABLES);
qb.setProjectionMap(LIVE_FOLDER_PROJECTION);
// *******************************************************************
// ** LISTING 10-16: Live Folder creation Activity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String action = getIntent().getAction();
if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
Intent intent = new Intent();
intent.setData(EarthquakeProvider.LIVE_FOLDER_URI);
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT, new Intent(Intent.ACTION_VIEW,
EarthquakeProvider.CONTENT_URI));
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE, LiveFolders.DISPLAY_MODE_LIST);
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON,
Intent.ShortcutIconResource.fromContext(context, R.drawable.icon));
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, "Earthquakes");
setResult(RESULT_OK, createLiveFolderIntent(this));
}
else
setResult(RESULT_CANCELED);
finish();
}
// *******************************************************************
// ** LISTING 10-17: Adding the Live Folder Intent Filter
// ** Search ************************************************** //
// *******************************************************************
// ** LISTING 10-18: Defining application search metadata
// *******************************************************************
// ** LISTING 10-19: Registering a search results Activity
// *******************************************************************
// ** LISTING 10-20: Setting a default search result Activity for an application
// *******************************************************************
// ** LISTING 10-21: Detecting search requests in Content Providers
private static int SEARCH = 1;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("com.paad.provider.earthquake", "earthquakes", QUAKES);
uriMatcher.addURI("com.paad.provider.earthquake", "earthquakes/#", QUAKE_ID);
uriMatcher.addURI("com.paad.provider.earthquake", SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH);
uriMatcher.addURI("com.paad.provider.earthquake", SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH);
uriMatcher.addURI("com.paad.provider.earthquake",
SearchManager.SUGGEST_URI_PATH_SHORTCUT, SEARCH);
uriMatcher.addURI("com.paad.provider.earthquake", SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", SEARCH);
}
// *******************************************************************
// ** LISTING 10-22: Returning the correct MIME type for search results
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case QUAKES : return "vnd.android.cursor.dir/vnd.paad.earthquake";
case QUAKE_ID: return "vnd.android.cursor.item/vnd.paad.earthquake";
case SEARCH : return SearchManager.SUGGEST_MIME_TYPE;
default: throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
// *******************************************************************
// ** 10-23: Returning search results from a query
private static final HashMap SEARCH_PROJECTION_MAP;
static {
SEARCH_PROJECTION_MAP = new HashMap();
SEARCH_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_TEXT_1, KEY_SEARCH_COLUMN +
" AS " + SearchManager.SUGGEST_COLUMN_TEXT_1);
SEARCH_PROJECTION_MAP.put("_id", KEY_ID + " AS " + "_id");
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sort) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(MY_TABLE);
switch (uriMatcher.match(uri)) {
case SINGLE_ID: qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
break;
case SEARCH : qb.appendWhere(KEY_SEARCH_COLUMN + " LIKE \"%" + uri.getPathSegments().get(1) + "%\"");
qb.setProjectionMap(SEARCH_PROJECTION_MAP);
break;
default : break;
}
Cursor c = qb.query(MyDB, projection, selection, selectionArgs, null, null, orderBy);
return c;
}
// *******************************************************************
// ** LISTING 10-24: Adding your search result to the Quick Search Box
// ** Live Wallpaper ********************************************** //
// *******************************************************************
// ** LISTING 10-25: Sample Live Wallpaper resource definition
// *******************************************************************
// ** LISTING 10-26: A Live Wallpaper Service
public class MyWallpaperService extends WallpaperService {
@Override
public Engine onCreateEngine() {
return new MyWallpaperServiceEngine();
}
}
// *******************************************************************
// ** LISTING 10-27: Adding a Live Wallpaper Service to the manifest
// *******************************************************************
// ** LISTING 10-28: Wallpaper Service Engine skeleton code
public class MyWallpaperServiceEngine extends WallpaperService.Engine {
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
// TODO Handle initialization.
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xOffsetStep, float yOffsetStep,
int xPixelOffset, int yPixelOffset) {
super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset);
// TODO Handle homescreen offset events.
}
@Override
public void onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
// TODO Handle touch and motion events.
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
// TODO Surface has been created, run the Thread that will
// update the display.
}
}
// *******************************************************************
// **
// ******************************************************************* //