Skip to content

Client Resources

The ClientResources module allows you to download resources associated with an application to a byte array. This module also provides APIs to download the resource content to a file. SAP Mobile Services allows administrators to assign various resources to an application.

With Android SDK 3.2, a new model class, ClientResourceBundle, has been introduced and all APIs will now be based on it.

Retrieving Client Resource Bundles

Two APIs are provided to load client resource bundles from the mobile server.

suspend fun retrieveResourceBundles(): ServiceResult<List<ClientResourceBundle>> = withContext(IO) { ... }
fun retrieveResourceBundles(listener: ServiceListener<List<ClientResourceBundle>>) { ... }

The first API will run on the IO thread and return the result using ServiceResult. The second one will notify the result with ServiceListener on the UI thread.

Sample usage:

ClientResourceService service = new ClientResourceService();
service.retrieveResourceBundles(serviceResult -> {
        if (serviceResult instanceof ServiceResult.SUCCESS) {
            List<ClientResourceBundle> bundles =
                    ((ServiceResult.SUCCESS<List<ClientResourceBundle>>) serviceResult)
                            .getData();
            if (bundles != null && !bundles.isEmpty()) {
                Log.d("TEST", bundles.get(0).toString());
            }
        } else {
            String error = ((ServiceResult.FAILURE<List<ClientResourceBundle>>) serviceResult)
                    .getMessage();
            Log.e("TEST", error);
        }
    });
MainScope().launch {
    when(val result = ClientResourceService().retrieveResourceBundles()) {
        is ServiceResult.SUCCESS -> {
            result.data?.also { bundles ->
                //'bundles' is List<ClientResourceBundle>
                Log.d("TEST", "Bundle count: ${bundles.size}")
            }
        }
        is ServiceResult.FAILURE -> Log.e("TEST", result.message)
    }
}

Downloading Client Resource Bundles

There are also two APIs to download client bundles.

suspend fun downloadClientResource(bundle: ClientResourceBundle? = null): ServiceResult<ByteArray> =
        withContext(IO) { ... }
fun downloadClientResource(
        listener: ServiceListener<ByteArray>,
        bundle: ClientResourceBundle? = null
    ) { ... }

To download the default resource bundle, set bundle to null. The result is a byte array. The 'suspend' function will run on the IO thread and return ServiceResult. The second function will get a byte array from the IO thread and notify the result with ServiceListener on the UI thread.

Sample usage:

new ClientResourceService().downloadClientResource(result -> {
        if(result instanceof ServiceResult.SUCCESS) {
            byte[] bytes = ((ServiceResult.SUCCESS<byte[]>) result).getData();
            ...
        }
    }, null);
MainScope().launch {
        when(val result = ClientResourceService().downloadClientResource()) {
            is ServiceResult.SUCCESS -> {
                result.data?.also { bytes ->
                    ...
                }
            }
            is ServiceResult.FAILURE -> Log.e("TEST", result.message)
        }
    }

Downloading and Saving Client Resource Bundles

The following API downloads the client resource and saves the content to the specified file on the IO thread, then notifies the result with ServiceListener on the UI thread.

fun downloadResourceToFile(
        listener: ServiceListener<String>,
        fileName: String,
        bundleClient: ClientResourceBundle? = null,
        overwrite: Boolean = true
    ) { ... }

If the API succeeds, the saved file is stored to the internal storage of this mobile application.

Sample usage:

new ClientResourceService().downloadResourceToFile(result -> {
        if( result instanceof ServiceResult.SUCCESS) {
            String fileName = ((ServiceResult.SUCCESS<String>) result).getData();
            File file = new File(getApplicationContext().getFilesDir(), fileName);
            ...
        }
    }, "Hello.jpg", null, true);
MainScope().launch {
        ClientResourceService().downloadResourceToFile( object: ServiceListener<String> {
            override fun onServiceDone(result: ServiceResult<String>) {
                when(result) {
                    is SUCCESS -> {
                        val fileName = result.data!!
                        val file = File(applicationContext.filesDir, fileName)
                        ...
                    }
                }
            }
        }, "Hello.jpg", null, true)

Client code can also download the client resource in a byte array and then save it to a file.

Downloading the Default Resource Bundle Automatically

To download the default resource bundle in the byte array format, client code can create an instance of ClientResourceService with the autoDownloadListener in the constructor, then start it with SDKInitializer.

List<MobileService> services = new ArrayList<>();
ClientResourceService autoClientResourceService = new ClientResourceService( result -> {
        if(result instanceof ServiceResult.SUCCESS) {
            byte[] bytes = ((ServiceResult.SUCCESS<byte[]>) result).getData();
            //handle the bytes
        }
    });
services.add(autoClientResourceService);
SDKInitializer.INSTANCE.start(this, services.toArray(new MobileService[0]), null);
val services = mutableListOf<MobileService>()
services.add(ClientResourceService(object : ServiceListener<ByteArray> {
        override fun onServiceDone(result: ServiceResult<ByteArray>) {
            when (result) {
                is ServiceResult.SUCCESS -> {
                    Log.d("TEST", "From worker, client resource bytes: " + result.data?.size)
                }
                is ServiceResult.FAILURE -> {
                    Log.e("TEST", result.message)
                }
            }
        }
    }))
SDKInitializer.start(this, * services.toTypedArray())

Last update: April 14, 2021