private static ArrayList<String> extractTextFromNotification(Service service, RemoteViews view) { LayoutInflater inflater = (LayoutInflater) service.getSystemService(Context.LAYOUT_INFLATER_SERVICE); ArrayList<String> result = new ArrayList<String>(); if (view == null) { Log.d(TAG, "View is empty"); return null; } try { int layoutid = view.getLayoutId(); ViewGroup localView = (ViewGroup) inflater.inflate(layoutid, null); view.reapply(service.getApplicationContext(), localView); ArrayList<View> outViews = new ArrayList<View>(); extractViewType(outViews, TextView.class, localView); for (View ttv: outViews) { TextView tv = (TextView) ttv; String txt = tv.getText().toString(); if (!TextUtils.isEmpty(txt) && tv.getId() != TIMESTAMPID) { result.add(txt); } } } catch (Exception e) { Log.d(TAG, "FAILED to load notification " + e.toString()); Log.wtf(TAG, e); return null; //notification might have dissapeared by now } Log.d(TAG, "Return result" + result); return result; }
private void updateUI(RemoteViews remoteViews) { int layoutId = getResources().getIdentifier("layout_simulated_notification", "layout", getPackageName()); View view = getLayoutInflater().inflate(layoutId, mRemoteViewsContent, false); remoteViews.reapply(this, view); mRemoteViewsContent.addView(view); }
/** * Process a set of {@link RemoteViews} coming in as an update from the AppWidget provider. Will * animate into these new views as needed */ public void updateAppWidget(RemoteViews remoteViews) { if (LOGD) Log.d(TAG, "updateAppWidget called mOld=" + mOld); boolean recycled = false; View content = null; Exception exception = null; // Capture the old view into a bitmap so we can do the crossfade. if (CROSSFADE) { if (mFadeStartTime < 0) { if (mView != null) { final int width = mView.getWidth(); final int height = mView.getHeight(); try { mOld = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); } catch (OutOfMemoryError e) { // we just won't do the fade mOld = null; } if (mOld != null) { // mView.drawIntoBitmap(mOld); } } } } if (remoteViews == null) { if (mViewMode == VIEW_MODE_DEFAULT) { // We've already done this -- nothing to do. return; } content = getDefaultView(); mLayoutId = -1; mViewMode = VIEW_MODE_DEFAULT; } else { // Prepare a local reference to the remote Context so we're ready to // inflate any requested LayoutParams. mRemoteContext = getRemoteContext(remoteViews); int layoutId = remoteViews.getLayoutId(); // If our stale view has been prepared to match active, and the new // layout matches, try recycling it if (content == null && layoutId == mLayoutId) { try { remoteViews.reapply(mContext, mView, mOnClickHandler); content = mView; recycled = true; if (LOGD) Log.d(TAG, "was able to recycled existing layout"); } catch (RuntimeException e) { exception = e; } } // Try normal RemoteView inflation if (content == null) { try { content = remoteViews.apply(mContext, this, mOnClickHandler); if (LOGD) Log.d(TAG, "had to inflate new layout"); } catch (RuntimeException e) { exception = e; } } mLayoutId = layoutId; mViewMode = VIEW_MODE_CONTENT; } if (content == null) { if (mViewMode == VIEW_MODE_ERROR) { // We've already done this -- nothing to do. return; } Log.w(TAG, "updateAppWidget couldn't find any view, using error view", exception); content = getErrorView(); mViewMode = VIEW_MODE_ERROR; } if (!recycled) { prepareView(content); addView(content); } if (mView != content) { removeView(mView); mView = content; } if (CROSSFADE) { if (mFadeStartTime < 0) { // if there is already an animation in progress, don't do anything -- // the new view will pop in on top of the old one during the cross fade, // and that looks okay. mFadeStartTime = SystemClock.uptimeMillis(); invalidate(); } } }