Android SDK
Offline Operation

Offline Operation

When your app needs to operate in a network-free environment, you need to pre-package some files into the app to ensure the SDK runs smoothly.

Download Configuration Files

curl --location --request GET 'https://api.gizwits.com/app/datapoint?product_key={{productKey}}'
 
// Replace productKey, the interface will return data point configuration
// Save it as {{productKey}}.json

Create Bundle

  • Create the main/assets/productConfig directory
  • Copy the data point file into it

Copy to Cache

Add code at the entry of the app

import android.os.Bundle
import android.util.Log
import dagger.hilt.android.AndroidEntryPoint
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
 
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        copyAssetsToCustomDirectories();
        ...
    }
 
    private fun copyAssetsToCustomDirectories() {
        val assetManager = assets
        val directories = arrayOf("api.gizwits.com", "usapi.gizwits.com", "euapi.gizwits.com")
        val files: Array<String>? = try {
            assetManager.list("productConfig")
        } catch (e: IOException) {
            e.printStackTrace()
            null
        }
        for (directory in directories) {
            if (files != null) {
                for (filename in files) {
                    val fileDirectory = File(filesDir.path + "/productConfig/$directory")
                    val inPath = "productConfig/$filename"
                    val outFile = File(fileDirectory, filename)
                    copyFileWithPath(inPath, outFile)
                }
            }
        }
    }
 
    private fun copyFileWithPath(assetPath: String, targetFile: File) {
        val assetManager = assets
 
        if (targetFile.exists()) {
            // File already exists, log it
            Log.d("copyFileWithPath", "File already exists: ${targetFile.absolutePath}")
            return
        }
 
        try {
            // Create directory
            val parentDir = targetFile.parentFile
            if (parentDir?.exists() == false) {
                parentDir?.mkdirs()
            }
 
            val `in` = assetManager.open(assetPath)
            val out = FileOutputStream(targetFile)
 
            val buffer = ByteArray(1024)
            var read: Int
            while (`in`.read(buffer).also { read = it } != -1) {
                out.write(buffer, 0, read)
            }
 
            `in`.close()
            out.flush()
            out.close()
 
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
 
    fun copyAssets(assetDir: String, targetDir: File) {
        val assetManager = assets
 
        try {
            // Get all files and subfolders in the assets directory
            val assets = assetManager.list(assetDir)
            Log.d("Start CopyAssets", assets.toString())
            if (assets != null) {
                for (asset in assets) {
                    val assetPath = "$assetDir${File.separator}$asset"
                    val targetPath = "${targetDir.absolutePath}${File.separator}$asset"
                    // If it's a directory, copy recursively
                    if (assetManager.list(assetPath)!!.isNotEmpty()) {
                        copyAssets(assetPath, File(targetPath))
                    } else {
                        copyFileWithPath(assetPath, File(targetPath))
                    }
                }
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
 
}