makeImageRequest fails in background of watchface on 4.0 device

Hi,everyone,I create a watch face,using makeImageRequest in background service。it can successfully save image on devices before CIQ4.0,such as fenix5plus or fenix6.

but on device with CIQ4.0 such as VENU2 or VENU2s,it throws an error。I searched the forum with no answer.please help。the attachment is a simple project

makeImageRequestTEST.zip

Error: Permission Required
Details: Module 'Toybox.Graphics' not available to 'Background'
Stack:
- getType() at D:\grmn\prj\di\connectiq\toolchain\mbsimulator\submodules\technology\monkeybrains\virtual-machine\api\WatchUi.mb:4098 0x300043d6
- initialize() at D:\grmn\prj\di\connectiq\toolchain\mbsimulator\submodules\technology\monkeybrains\virtual-machine\api\Graphics.mb:919 0x300013fb
- <Toybox_Graphics_BitmapReference_>>initialize>() at D:\grmn\prj\di\connectiq\toolchain\mbsimulator\submodules\technology\monkeybrains\virtual-machine\api\Graphics.mb:998 0x30001551

the code is below

using Toybox.Background as Bg;
using Toybox.System as Sys;
using Toybox.Communications as Comm;
using Toybox.Application.Storage as AS;


(:background)
class BackgroundService extends Sys.ServiceDelegate {
	function initialize() {
			Sys.ServiceDelegate.initialize();
	}   

	function onTemporalEvent() {
			Comm.makeImageRequest("https://t1.picb.cc/uploads/2021/11/13/wYuQxt.png",null,{:palette =>[0xff0000],:maxWidth => 100,:maxHeight => 100,:dithering => 1}, method(:OnReceiveimg));
 	}
	function OnReceiveimg(responseCode, data){
			if(responseCode == 200){
				AS.setValue(4,data);
			}			
			Bg.exit(responseCode);
	}
}

  • The issue you are running into with the Venu2/2s is the data returned is a Graphics.BitmapReference as a pointer to the graphics pool.  On devices prior to 4.0 the raw image was passed into the device memory as a WatchUi.BitmapResource.  Because the Graphics module is all about "drawing" items on the view, it is not available for background processes.

    There are a number of changes in how graphics are handled with the new graphics pool in the 4.0 devices.  This appears to be one of the limits is that background image downloads are not possible.

    See the description of graphics pools in this Announcement article.  forums.garmin.com/.../a-whole-new-world-of-graphics-with-connect-iq-4

  • does it mean that makeImageRequest  in background service of a watch face will not be available on CIQ 4.0 devices?

  • I don't know.  It is probably worth it to open a bug report as I can see the value of downloading an image update in the background as long as the image is not too large.  It would works fine on the older devices because you are saving the raw image data.  With the graphics pool, you have no option to ensure the reference from the background process even still exists once you get to the main app.  I am guessing this was not a use case that was intended when the graphics pools were introduced.

  • thank you。in the simulator,I can successfully download and save the img in fenix6.

    and then I  switch to venu2  in simulator the saved img can be directly used without problem。the error only comes when making this request in venu2.

  • That has to do with the new graphics pools implemented in the Venu2 vs using the heap memory on the Fenix6.  In truth you can miss some gotchas like this because the simulator does not clear the app storage when you change devices.  So your code will be able to load a resource that in the real device you can never save on a fresh install on a real device due to the makeImageRequest limitation.

  • you are right。the error comes from the background service。and the document doesn't mention anything different  when making  makeImageRequest    in background services  between CIQ 4.0 devices and old devices。

  • to get to the bitmap with CIQ 4.x devices, you need to use "get()" with the graphics pool  Look at the blog post sabeard linked to.

    there's also a difference with BufferedBitmaps with CIQ4 and pre CIQ4 devices.

  • I think  the error  comes when making makeImageRequest    in background service of  watch face。because normally after  AS.setValue(4,data);  the img will be saved。but it is not saved.

  • I think  the error  comes when making makeImageRequest    in background service of  watch face。because normally after  AS.setValue(4,data);  the img will be saved。but it is not saved.

  • If the response code is 200, try using a get() on data

    data.get()