0

I have a custom View that is extending ImageView (called PieView) and since this is one of the allowed views to be included in RemoteViews, this should theoretically work.

I am sending a Notification to the device's notification bar using NotificationCompat.Builder with a custom View, which includes a blank ImageView, which I want to replace with my custom class (which is a descendant of ImageView).

Here's what I use to build the Notification:

    final PieView pie = new PieView(c);

    // My own method that redraws the View using this.invalidate()
    pie.setRam(totalRam, freeRam);

    pie.setDrawingCacheEnabled(true);
    pie.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
    pie.layout(0, 0, pie.getMeasuredWidth(), pie.getMeasuredHeight());
    pie.buildDrawingCache(true);

    Bitmap bitmap = Bitmap.createBitmap(pie.getDrawingCache());

    pie.setDrawingCacheEnabled(false);

    remoteViews.setImageViewBitmap(R.id.ivPie, bitmap);

    mBuilder.setContent(remoteViews);

However, this results in java.lang.NullPointerException on the following line:

Bitmap bitmap = Bitmap.createBitmap(pie.getDrawingCache());

I am assuming the View is not drawn yet since it's not placed anywhere in the layout. How to work around this issue? I am familiar that only a portion of Views are supported to be included in the Notification's body, but there must surely be a way to pre-create my custom View as a static image and add it to the (allowed) ImageView using RemoteViews.

Dzhuneyt
  • 8,437
  • 14
  • 64
  • 118

1 Answers1

2

I have a custom View that is extending ImageView (called PieView) and since this is one of the allowed views to be included in RemoteViews, this should theoretically work.

Since there is no PieView in Android, it cannot be "one of the allowed views to be included in RemoteViews", and it will not work, in theory or in practice. While ImageView is allowed, subclasses are not.

How to work around this issue?

Draw your pie to a Bitmap, perhaps via a Bitmap-backed Canvas, and apply the Bitmap using setImageViewBitmap() on RemoteViews. However, bear in mind that the overall RemoteViews structure needs to be reasonably small (under 1MB), so do not make your bitmap too big.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I've tried that, but everytime I try to built a `Bitmap` using `Bitmap.createBitmap(pie.getWidth(), pie.getHeight().....)` out of my `PieView` the getWidth and getHeight methods always return 0, so `createBitmap` fails (I am guessing the PieView is not ready/rendered). So the real question is, how to force the PieView to be rendered programmatically, get its Bitman and use it as a value for `setImageViewBitmap`? – Dzhuneyt Sep 22 '13 at 18:26
  • 1
    @WordPressDeveloper: Get rid of `PieView` and draw the pie to a `Bitmap`-backed `Canvas` of your desired size (http://madandroid.blogspot.com/2011/05/drawing-on-widget-canvas.html). Or, you can try creating a standalone `PieView` (i.e., not a child of anything) and call `measure()` and `layout()` on it yourself, and see if that works. – CommonsWare Sep 22 '13 at 18:42
  • This sounds like a good idea, although I am not sure if it will work, because I don't know if we'll know how large the Notification will be, and in turn - how big we should create the Canvas/Bitmap to draw on. I'll ponder over it and try to implement it and post back. Thanks for the suggestion! – Dzhuneyt Sep 22 '13 at 18:59
  • @WordPressDeveloper: "because I don't know if we'll know how large the Notification will be" -- you definitely will not know how large the `Notification` will be, as details of the drawer can vary by device manufacturer. – CommonsWare Sep 22 '13 at 19:02
  • So you are suggesting I draw a fixed-size canvas (e.g. 150dp x 150dp) and position it inside the ImageView using XML (e.g. stretch/skew/centerFit/gravity/etc)? – Dzhuneyt Sep 22 '13 at 19:17
  • @WordPressDeveloper: Personally, I just wouldn't put a pie chart in a `Notification`. :-) That being said, it's possible that what you are describing will work -- I have never tried that. – CommonsWare Sep 22 '13 at 19:20