package mobi.urika.android.widget; import mobi.urika.android.content.LauncherIntent; import android.app.Activity; import android.appwidget.AppWidgetManager; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.BitmapFactory; import android.net.Uri; import android.text.Html; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.widget.CursorAdapter; import android.widget.ImageView; import android.widget.TextView; /** * * @author Bo & Koxx * */ public class WidgetCursorAdapter extends CursorAdapter { static final String LOG_TAG = "LauncherPP_WCA"; static final int IMPOSSIBLE_INDEX = -100; final LayoutInflater mInflater; final int mItemLayoutId; final int mAppWidgetId; final int mListViewId; ItemMapping[] mItemMappings; boolean mAllowRequery = true; class ItemMapping { int type; int layoutId; int defaultResource; int index; boolean clickable; /** * * @param t * view type * @param l * layout id * @param i * index * @param r * default resource * @param u * clickable */ ItemMapping(int t, int l, int i, int r, boolean u) { type = t; layoutId = l; defaultResource = r; index = i; clickable = u; } ItemMapping(int t, int l, int i) { type = t; layoutId = l; index = i; defaultResource = -1; clickable = false; } } public final boolean mItemChildrenClickable; final int mItemActionUriIndex; ComponentName mAppWidgetProvider; /** * * @param context * remote context * @param c * cursor for reading data * @param intent * broadcast intent initiated the replacement, don't save it * @param appWidgetId * @param listViewId */ public WidgetCursorAdapter(Activity a, Context context, Cursor c, Intent intent, ComponentName provider, int appWidgetId, int listViewId) throws IllegalArgumentException { super(context, c); mAppWidgetId = appWidgetId; mListViewId = listViewId; mAppWidgetProvider = provider; mInflater = LayoutInflater.from(context); // mActivity = a; // verify is contentProvider requery is allowed mAllowRequery = intent.getBooleanExtra( LauncherIntent.Extra.Scroll.EXTRA_DATA_PROVIDER_ALLOW_REQUERY, false); // Get the layout if for items mItemLayoutId = intent.getIntExtra(LauncherIntent.Extra.Scroll.EXTRA_ITEM_LAYOUT_ID, -1); if (mItemLayoutId <= 0) throw (new IllegalArgumentException("The passed layout id is illegal")); mItemChildrenClickable = intent.getBooleanExtra( LauncherIntent.Extra.Scroll.EXTRA_ITEM_CHILDREN_CLICKABLE, false); mItemActionUriIndex = intent.getIntExtra( LauncherIntent.Extra.Scroll.EXTRA_ITEM_ACTION_VIEW_URI_INDEX, -1); // Generate generateItemMapping(intent); } /** * Collect arrays and put them together * * @param t * @param ids * @param c * @param u * uri indices; could be zero, IMPOSSIBLE_INDEX will be used */ private void generateItemMapping(Intent intent) { // Read the mapping data int[] viewTypes = intent .getIntArrayExtra(LauncherIntent.Extra.Scroll.Mapping.EXTRA_VIEW_TYPES); int[] viewIds = intent.getIntArrayExtra(LauncherIntent.Extra.Scroll.Mapping.EXTRA_VIEW_IDS); int[] cursorIndices = intent .getIntArrayExtra(LauncherIntent.Extra.Scroll.Mapping.EXTRA_CURSOR_INDICES); int[] defaultResources = intent .getIntArrayExtra(LauncherIntent.Extra.Scroll.Mapping.EXTRA_DEFAULT_RESOURCES); boolean[] viewClickable = intent .getBooleanArrayExtra(LauncherIntent.Extra.Scroll.Mapping.EXTRA_VIEW_CLICKABLE); // Check if (viewTypes == null || viewIds == null || cursorIndices == null) throw (new IllegalArgumentException("A mapping component is missing")); if (viewTypes.length == viewIds.length && viewTypes.length == cursorIndices.length) { } else throw (new IllegalArgumentException("Mapping inconsistent")); // Init mapping array final int size = viewTypes.length; mItemMappings = new ItemMapping[size]; for (int i = size - 1; i >= 0; i--) mItemMappings[i] = new ItemMapping(viewTypes[i], viewIds[i], cursorIndices[i]); // Put extra data in if they are available if (viewClickable != null && viewClickable.length == size) for (int i = size - 1; i >= 0; i--) mItemMappings[i].clickable = viewClickable[i]; if (defaultResources != null && defaultResources.length == size) for (int i = size - 1; i >= 0; i--) mItemMappings[i].defaultResource = defaultResources[i]; } @Override public void bindView(View view, Context context, Cursor cursor) { if (mItemMappings == null) return; final int size = mItemMappings.length; ItemMapping itemMapping; View child; ImageView iv; try { // bind children views for (int i = size - 1; i >= 0; i--) { itemMapping = mItemMappings[i]; child = view.findViewById(itemMapping.layoutId); switch (itemMapping.type) { case LauncherIntent.Extra.Scroll.Types.TEXTVIEW: if (!(child instanceof TextView)) break; String text = cursor.getString(itemMapping.index); if (text != null) ((TextView) child).setText(cursor.getString(itemMapping.index)); else ((TextView) child).setText(itemMapping.defaultResource); break; case LauncherIntent.Extra.Scroll.Types.TEXTVIEWHTML: if (!(child instanceof TextView)) break; String textHtml = cursor.getString(itemMapping.index); if (textHtml != null) ((TextView) child).setText(Html.fromHtml(cursor .getString(itemMapping.index))); else ((TextView) child).setText(itemMapping.defaultResource); break; case LauncherIntent.Extra.Scroll.Types.IMAGEBLOB: if (!(child instanceof ImageView)) break; iv = (ImageView) child; byte[] data = cursor.getBlob(itemMapping.index); if (data != null) iv.setImageBitmap(BitmapFactory.decodeByteArray(data, 0, data.length)); else if (itemMapping.defaultResource > 0) iv.setImageResource(itemMapping.defaultResource); else iv.setImageDrawable(null); break; case LauncherIntent.Extra.Scroll.Types.IMAGEURI: if (!(child instanceof ImageView)) break; iv = (ImageView) child; String uriStr = cursor.getString(itemMapping.index); if ((uriStr != null) && (!uriStr.equals(""))) iv.setImageURI(Uri.parse(uriStr)); else iv.setImageDrawable(null); break; case LauncherIntent.Extra.Scroll.Types.IMAGERESOURCE: if (!(child instanceof ImageView)) break; iv = (ImageView) child; int res = cursor.getInt(itemMapping.index); if (res > 0) iv.setImageResource(res); else if (itemMapping.defaultResource > 0) iv.setImageResource(itemMapping.defaultResource); else iv.setImageDrawable(null); break; } // Prepare tag view.setTag(null); if (mItemChildrenClickable && itemMapping.clickable) { if (mItemActionUriIndex >= 0) child.setTag(cursor.getString(mItemActionUriIndex)); else child.setTag(Integer.toString(cursor.getPosition())); child.setOnClickListener(new ItemViewClickListener()); } else { if (mItemActionUriIndex >= 0) { view.setTag(cursor.getString(mItemActionUriIndex)); } } } } catch (Exception e) { e.printStackTrace(); } } @Override public View newView(Context context, Cursor c, ViewGroup parent) { return mInflater.inflate(mItemLayoutId, parent, false); } class ItemViewClickListener implements OnClickListener { public void onClick(View v) { try { String pos = (String) v.getTag(); Intent intent = new Intent(LauncherIntent.Action.ACTION_VIEW_CLICK); intent.setComponent(mAppWidgetProvider); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId).putExtra( LauncherIntent.Extra.EXTRA_APPWIDGET_ID, mAppWidgetId); intent.putExtra(LauncherIntent.Extra.EXTRA_VIEW_ID, v.getId()); intent.putExtra(LauncherIntent.Extra.Scroll.EXTRA_LISTVIEW_ID, mListViewId); intent.putExtra(LauncherIntent.Extra.Scroll.EXTRA_ITEM_POS, pos); v.getContext().sendBroadcast(intent); } catch (Exception e) { e.printStackTrace(); } } } public static Cursor queryForNewContent(Activity a, ContentResolver cr, Intent intent) { Cursor cursor = null; if ((intent != null) && (a != null)) { cursor = a.managedQuery(Uri.parse(intent .getStringExtra(LauncherIntent.Extra.Scroll.EXTRA_DATA_URI)), intent .getStringArrayExtra(LauncherIntent.Extra.Scroll.EXTRA_PROJECTION), intent .getStringExtra(LauncherIntent.Extra.Scroll.EXTRA_SELECTION), intent .getStringArrayExtra(LauncherIntent.Extra.Scroll.EXTRA_SELECTION_ARGUMENTS), intent.getStringExtra(LauncherIntent.Extra.Scroll.EXTRA_SORT_ORDER)); if (cursor != null) cursor.setNotificationUri(cr, Uri.parse(intent .getStringExtra(LauncherIntent.Extra.Scroll.EXTRA_DATA_URI))); else Log.d(LOG_TAG, "cursor null"); } else { Log.d(LOG_TAG, "intent or activity null"); } return cursor; } // @Override // protected void onContentChanged() { // // Log.i(LOG_TAG, "onContentChanged"); // // if (getCursor() != null && !getCursor().isClosed()) { // if (mAllowRequery) { // getCursor().requery(); // } else { // Cursor newCursor = queryForNewContent(mActivity, mContentResolver, // mIntent); // if (newCursor != null) { // Log.i(LOG_TAG, "newCursor = " + newCursor + " / count = " + // newCursor.getCount()); // changeCursor(newCursor); // } // } // // notifyDataSetChanged(); // // } else { // Log.v(LOG_TAG, "cursor closed or null"); // } // } }