{"id":18982310,"url":"https://github.com/profusion/android-sdk-addon-example","last_synced_at":"2025-11-11T16:02:38.386Z","repository":{"id":44277164,"uuid":"305482253","full_name":"profusion/android-sdk-addon-example","owner":"profusion","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-13T20:04:46.000Z","size":3134,"stargazers_count":24,"open_issues_count":5,"forks_count":7,"subscribers_count":31,"default_branch":"main","last_synced_at":"2025-02-13T20:36:08.155Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Makefile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/profusion.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-19T18:45:53.000Z","updated_at":"2025-02-13T19:56:57.000Z","dependencies_parsed_at":"2024-12-10T19:18:58.935Z","dependency_job_id":"813185b2-260f-431c-9cc6-8a1f528d8079","html_url":"https://github.com/profusion/android-sdk-addon-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profusion%2Fandroid-sdk-addon-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profusion%2Fandroid-sdk-addon-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profusion%2Fandroid-sdk-addon-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profusion%2Fandroid-sdk-addon-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/profusion","download_url":"https://codeload.github.com/profusion/android-sdk-addon-example/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239986958,"owners_count":19729712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T16:13:05.567Z","updated_at":"2025-11-11T16:02:38.310Z","avatar_url":"https://github.com/profusion.png","language":"Makefile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# How to build and use an SDK Add-on\n\nWhether you are an OEM company or a developer customizing the Android Open Source Project, you might have come across the issue where you developed a feature and you would like for App developers to use it. That's when the SDK Add-on comes in handy.\n\nThe Android Software Development Kit (SDK) is a collection of libraries and tools that enables and makes it easier to develop Android applications. SDK Add-ons allow third-party actors to extend the Android SDK to add interfaces to their features without changing the Android SDK. According to the Android Compatibility Definition Document (CDD), OEMs are not allowed to change the Android public APIs - namely those in the protected namespaces: `java.*`, `javax.*`, `sun.*`, `android.*`, `com.android.*`. Therefore, by using add-ons, OEMs can add libraries in their namespaces, providing functionalities that can be exported without infringing the CDD. Having to build only the add-on is also a great advantage that might save a lot of development time.\n\nIn this post, we will build an SDK Add-on containing an example service - for which we will cover all the necessary config files. We will also learn how to connect an application to our example service using the add-on. Here, we are assuming you already have access to the Android source code and that you can build and deploy these changes. The code and configuration files were made with Android 10 (API level 30) in mind but they can be easily modifiable to work with other versions.\n\n## Setting up the AOSP source tree\n\nThe source code of AOSP and all necessary tools can be downloaded following the [instruction on this link](https://source.android.com/setup/build/downloading).\n\nThis tutorial was written to be build with Android 14 (API 34). When pulling the code with `repo init`, specify the latest Android 14 code:\n\n```bash\nrepo init -b android-14.0.0_r75 -u https://android.googlesource.com/platform/manifest\nrepo sync\n```\n\n### The content of this repository\n\nThis repository contains the code to build an emulator image containing the **hello-world-service**, the SDK add-on containing the **hello-world-service** service libraries that apps that use the **hello-world-service** will use on theirs build process, and a sample app that will use the SDK add-on. The summary of the code follows:\n\n* `device/profusion/profusion_sdk_addon`: contains the configuration and manifest files for the SDK add-on. The `profusion_sdk_addon.mk` includes the **helloworld** product as part of this add-on;\n* `pacakges/services/profusion/hello-world-service`: contains the service itself, that will be run in the emulator and serve the applications. The service will be part of the framework;\n* `target`: contains files related to the emulator that will be created. Instead of creating a new device, we just modified the `sdk_car_x86_64.mk` and `car_generic_system.mk` to include our add-on.\n\n\nWe supply a shell script `add_to_aosp.sh` to automatically copy all code to the correct place in the AOSP source tree. Pass to the script the path to where the AOSP repo is:\n\n```bash\n./add_to_aosp.sh /pathTo/aosp\n```\n\nIf you use VSCode, you can use [Run on Save](https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave) to automatically update the files with this script on save.\n\n\n\n## Hello World System Service\n\nTo facilitate the understanding of how to build and extract your own SDK Add-on, we will create a simple \"hello world\" service so that later we can use an application to connect to it.\n\n##### `HelloWorldService.java`\n\n```java\npackage com.profusion.helloworld;\n\nimport android.app.Service;\nimport android.content.Intent;\nimport android.os.Binder;\nimport android.os.IBinder;\nimport android.util.Log;\n\npublic class HelloWorldService extends Service {\n    private static final String TAG = \"HelloWorldService\";\n    private IHelloWorldService.Stub mBinder;\n\n    @Override\n    public IBinder onBind(final Intent intent) {\n        if (mBinder == null) {\n            mBinder = new HelloWorld();\n        }\n        return mBinder;\n    }\n\n    private class HelloWorld extends IHelloWorldService.Stub {\n\n        public HelloWorld() {\n        }\n\n        public void printHelloWorld() {\n            Log.d(TAG, \"Hello World.\");\n        }\n    }\n}\n\n```\n\nAn [AIDL](https://source.android.com/devices/architecture/aidl/overview) interface is needed for a client app to connect to.\n\n##### `IHelloWorldService.aidl`\n\n```java\npackage com.profusion.helloworld;\n\ninterface IHelloWorldService {\n    void printHelloWorld();\n}\n```\n\nThe service also needs a set of permissions that will be installed on the `/system/etc` directory. When the client app is installed, it will look for this file to determine if the HelloWorld library exists. The service library is installed in the `/system/framework` directory.\n\n##### `helloworld-permissions.xml`\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cpermissions\u003e\n    \u003clibrary name=\"helloworld\" file=\"/system/framework/helloworld.jar\"/\u003e\n\u003c/permissions\u003e\n```\n\nIf `helloworld-permissions.xml` does not exist, then the app will not be installed and `adb install` will return an error such as:\n```\nFailure [INSTALL_FAILED_MISSING_SHARED_LIBRARY: Package couldn't be installed...]\n```\n\nAlso, `AndroidManifest.xml` needs to define the service interface.\n##### `AndroidManifest.xml`\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cmanifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      package=\"com.profusion.helloworld\"\n      android:versionCode=\"1\"\n      android:versionName=\"1.0\"\n      android:sharedUserId=\"android.uid.system\"\u003e\n\n    \u003capplication android:label=\"Hello World Service\"\n                 android:directBootAware=\"true\"\u003e\n        \u003cservice android:name=\".HelloWorldService\"\n                 android:enabled=\"true\"\n                 android:exported=\"true\" \u003e\n        \u003c/service\u003e\n    \u003c/application\u003e\n\u003c/manifest\u003e\n\n```\n\n##### `hello-world-service/Android.bp`\n\nThe `android_app` entry is used to create the app. It tells Soong where the sources are, the [VINF](https://source.android.com/devices/architecture/vintf) manifest, and do other configurations to compile the service.\n\nThe `prebuilt_etc` entry tells the Soong to copy the `helloworld-permissions.xml` to the `/etc` directory.\n\nThe `java_sdk_library` entry specifies the sources to build an SDK library. This is used when creating the SDK. When you add the SDK to Android Studio, the application that you are developing will have access to this library.\n\nThe `javadoc` entry is used to create documentation for given sources. Text wrapped in `/* **/` is then included in the documentation. Check [javadoc](https://www.jetbrains.com/help/idea/viewing-reference-information.html) for more infos.\n\n##### `hello-world-service/Android.mk`\n\nShould contain commands that the blueprint cannot support. Since Android 11, the build system can create the `.jar` file with the Android blueprint. Checkout a previous commit in this repo to see how the Android make file was written to built the `.jar` file into Android 9.\n\n## SDK Add-on configs\nIf you already have a service, then this is the interesting part:\nYou need a `.mk` file that defines the name and properties of your SDK Add-on, and several other files that define miscellaneous properties such as the API level being used, the revision version, and the libraries contained in the add-on. During the Android build, these files are bundled into a `.zip` containing the add-on to be distributed. In the next sections, I will go into further detail into each of the included files.\n\n##### `profusion_sdk_addon.mk`\n\n```make\n# The name of this add-on (for the SDK)\nPRODUCT_SDK_ADDON_NAME := profusion_sdk_addon\n\nINTERNAL_SDK_HOST_OS_NAME := $(HOST_OS)\n\nPRODUCT_PACKAGES := \\\n    helloworld\n\n# Copy the manifest and properties files for the SDK add-on.\nPRODUCT_SDK_ADDON_COPY_FILES := \\\n $(LOCAL_PATH)/manifest.ini:manifest.ini \\\n $(LOCAL_PATH)/source.properties:source.properties \\\n $(LOCAL_PATH)/package.xml:package.xml\n\n# Define the IMAGE PROPERTY (emulator related, but needed to build)\nPRODUCT_SDK_ADDON_SYS_IMG_SOURCE_PROP := $(LOCAL_PATH)/source.properties\n\n# Copy the jar files for the optional libraries that are exposed as APIs.\nPRODUCT_SDK_ADDON_COPY_MODULES := \\\n    helloworld:libs/helloworld.jar\n\n# Rules for public APIs\nPRODUCT_SDK_ADDON_STUB_DEFS := $(LOCAL_PATH)/sdk_addon_stub_defs.txt\n```\n\nThe `profusion_sdk_addon.mk` provides all the information needed to build the add-on, like the modules that will be included. In this case, we want to include our helloworld.jar, so we need to specify the module to be built in the `PRODUCT_PACKAGES` variable and copy it to the add-on using the `PRODUCT_SDK_ADDON_COPY_MODULES` variable. The `PRODUCT_SDK_ADDON_COPY_FILES` is used to copy the config files that will be used in Android Studio to build the application.\n\n##### `manifest.ini`\n```code\n# SDK Add-on Manifest\n\nname=ProfusionAddOn\nname-id=profusionaddon\nvendor=Profusion\nvendor-id=profusion\ndescription=Profusion SDK Add-On\n\napi=34\nrevision=1\nlibraries=helloworld\nhelloworld=helloworld.jar\n```\nThe `manifest.ini` file contains the properties of the add-on, including the Android API Level, the libraries included, and the revision number. If there is more than one library, they must be separated by a semicolon (;) and also be defined below in a new line containing the library name and its `.jar` file name.\n\n##### `source.properties`\n```code\nAddon.NameId=profusionaddon\nAddon.NameDisplay=ProfusionAddOn\nAddon.VendorId=profusion\nAddon.VendorDisplay=Profusion\nPkg.Desc=Profusion SDK Addon\nPkg.Revision=1\nPkg.UserSrc=false\nArchive.Arch=ANY\nArchive.Os=ANY\n\nAndroidVersion.ApiLevel=34\nSystemImage.TagDisplay=Profusion SDK Add-On\nSystemImage.TagId=profusionaddon\nSystemImage.Abi=${TARGET_CPU_ABI}\n```\nThe `source.properties` defines add-on properties used for the built image, which can be distributed along with the SDK Add-on.\n\n##### `package.xml`\n\n```xml\n\u003cns2:repository xmlns:ns2=\"http://schemas.android.com/repository/android/common/01\" xmlns:ns3=\"http://schemas.android.com/repository/android/generic/01\" xmlns:ns4=\"http://schemas.android.com/sdk/android/repo/addon2/01\" xmlns:ns5=\"http://schemas.android.com/sdk/android/repo/repository2/01\" xmlns:ns6=\"http://schemas.android.com/sdk/android/repo/sys-img2/01\"\u003e\n  \u003clicense id=\"license-CC939D3F\" type=\"text\"/\u003e\n  \u003clocalPackage path=\"add-ons;addon-profusionaddon-profusion-30\" obsolete=\"false\"\u003e\n    \u003ctype-details xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"ns4:addonDetailsType\"\u003e\n      \u003capi-level\u003e34\u003c/api-level\u003e\n      \u003cvendor\u003e\n        \u003cid\u003eprofusion\u003c/id\u003e\n        \u003cdisplay\u003eProfusion\u003c/display\u003e\n      \u003c/vendor\u003e\n      \u003ctag\u003e\n        \u003cid\u003eprofusionaddon\u003c/id\u003e\n        \u003cdisplay\u003eProfusionAddOn\u003c/display\u003e\n      \u003c/tag\u003e\n      \u003clibraries\u003e\n        \u003clibrary localJarPath=\"helloworld.jar\" name=\"helloworld\"\u003e\n          \u003cdescription\u003eHello World Library\u003c/description\u003e\n        \u003c/library\u003e\n      \u003c/libraries\u003e\n    \u003c/type-details\u003e\n    \u003crevision\u003e\n      \u003cmajor\u003e1\u003c/major\u003e\n      \u003cminor\u003e0\u003c/minor\u003e\n      \u003cmicro\u003e0\u003c/micro\u003e\n    \u003c/revision\u003e\n    \u003cdisplay-name\u003eProfusionAddOn, Android 34, rev 75\u003c/display-name\u003e\n    \u003cuses-license ref=\"license-CC939D3F\"/\u003e\n  \u003c/localPackage\u003e\n\u003c/ns2:repository\u003e\n```\nThe `package.xml` file makes it easier for Android Studio to import the add-on.\n\n##### `sdk_addon_stub_defs.txt`\n\n```code\n+com.profusion.helloworld.*\n```\nThe `sdk_addon_stub_defs.txt` file contains the rules for public APIs.\n\nFor these tests, I was using `lunch sdk_car_x86_64-trunk_staging-eng`, so I decided to add the reference to `profusion_sdk_addon.mk` in the `/device/generic/car/sdk_car_x86_64.mk`, but you may add it to whichever device you are using. Simply add:\n\n```make\n$(call inherit-product, $(SRC_TARGET_DIR)/product/profusion_sdk_addon/profusion_sdk_addon.mk)\n```\n\n### Building the SDK addon\nThe SDK Add-on is all set. Now we only have to build it. Notice, again, that I'm using `sdk_car_x86_64`:\n\n```bash\n. build/envsetup.sh\nexport TARGET=profusion_sdk_addon\nlunch sdk_car_x86_64-trunk_staging-eng\nmake sdk_addon\n```\n\nWhen the compilation succeeds, you will see two `.zip` files at `out/host/linux-x86/sdk_addon`. `profusion_sdk_addon-linux.zip` will contain the addon itself, which will be used to develop and compile our app. `profusion_sdk_addon-linux-img.zip` will contain a set of files to run the emulator outside the AOSP file tree.\n\n### Building Android\n\nTo build Android containing the library that we want to supply, do\n\n```bash\n# . build/envsetup.sh if you are doing it on a new shell\nlunch sdk_car_x86_64-trunk_staging-eng\nm\n```\n\n## Adding the SDK Add-on to Android Studio\n\nCheck the environment variable that points to Android's Sdk root.\n\n```bash\necho $ANDROID_SDK_ROOT\n```\n\nIf the variable is empty, you must define the path to your `Android/Sdk` directory. It is usually under your $HOME:\n\n```\nexport ANDROID_SDK_ROOT=~/Android/Sdk # default location\n```\n\nThen, create a folder on your Android SDK for the add-ons. Afterward, extract the content of `profusion_sdk_addon-linux.zip` to a directory that matches the name defined at \"localPackage\" property of `packages.xml`.\n\n```bash\nmkdir -p \"$ANDROID_SDK_ROOT\"/add-ons # or ~/Android/Sdk/add-ons\nunzip out/host/linux-x86/sdk_addon/profusion_sdk_addon-linux.zip -d \"$ANDROID_SDK_ROOT\"/add-ons\nmv \"$ANDROID_SDK_ROOT\"/add-ons/profusion_sdk_addon-linux/ \"$ANDROID_SDK_ROOT\"/add-ons/addon-profusionaddon-profusion-34/\nrm -rf \"$ANDROID_SDK_ROOT\"/add-ons/profusion_sdk_addon-linux # delete intermediate folder\n```\n\nOpen Android Studio and go to Tools -\u003e SDK Manager. Check the \"Show Package Details\" checkbox then you will be able to see the SDK Add-on for the API level configured.\n![SDK Manager containing the SDK Add-on](assets/sdkmanager.png)\n\n## Using the SDK Add-on in an application\n\nAccording to Android Studio, the correct way of using a custom SDK is to pass it as a String to `compileSdkVersion` property following this format: `\"vendorName:addonName:api\"`, so in our case it should be `\"Profusion:ProfusionAddOn:34\"`. But I wasn't able to use the addon this way, so I found a 'workaround' on StackOverflow that consists in: you must first use a `compileSdk` on the `build.gradle` that matches the API level of your addon (in our case, 34). Then you need to add the path to the add-ons folder on the `dependencies` block\n```code\n...\n  compileOnly(fileTree(mapOf(\"dir\" to \"${android.sdkDirectory.path}/add-ons/addon-profusionaddon-profusion-34\", \"include\" to listOf(\"**/*.jar\"))))\n...\n```\n\nImport the class from the SDK you'd like to use. In our case, it's `com.profusion.helloworld.IHelloWorldService`.\nSometimes Android Studio will not recognize the package, so I recommend you go to Tools -\u003e SDK Manager and on the \"SDK Location\" click on `Edit` and don't change anything, but click `Next` until it finishes. This will force Android Studio to reparse the `package.xml` from the add-on.\n\nBelow is an example of an application using the HelloWorldService:\n##### `MainActivity.kt`\n\n```kotlin\npackage com.example.helloworldapp\n...\nimport com.profusion.helloworld.IHelloWorldService\n\nconst val HELLO_WORLD_SERVICE_PACKAGE = \"com.profusion.helloworld\"\nconst val HELLO_WORLD_SERVICE = \"$HELLO_WORLD_SERVICE_PACKAGE.HelloWorldService\"\nconst val TAG = \"HelloWorldApplication\"\n\nclass MainActivity : ComponentActivity() {\n    private var helloWorldService: IHelloWorldService? = null\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        enableEdgeToEdge()\n        setContent {\n            HelloWorldAppTheme {\n                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -\u003e\n                    MainContent(\n                        modifier = Modifier.padding(innerPadding),\n                        onButtonClick = {\n                            helloWorldService?.printHelloWorld()\n                        }\n                    )\n                }\n            }\n        }\n    }\n\n    override fun onStart() {\n        super.onStart()\n        val intent = Intent()\n        intent.component = ComponentName(HELLO_WORLD_SERVICE_PACKAGE, HELLO_WORLD_SERVICE)\n        try {\n            this.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)\n        } catch (e: Exception) {\n            Log.e(TAG, \"Unable to bind HelloWorldService\", e)\n        }\n    }\n\n    private val serviceConnection = object : ServiceConnection {\n        override fun onServiceConnected(className: ComponentName, service: IBinder) {\n            helloWorldService = IHelloWorldService.Stub.asInterface(service)\n        }\n\n        override fun onServiceDisconnected(className: ComponentName) {\n            helloWorldService = null\n        }\n    }\n}\n\n@Composable\nfun MainContent(modifier: Modifier = Modifier, onButtonClick: () -\u003e Unit) {\n    Column(\n        modifier = modifier.fillMaxSize(),\n        verticalArrangement = Arrangement.Center,\n        horizontalAlignment = Alignment.CenterHorizontally,\n    ) {\n        Button(\n            onClick = onButtonClick,\n        ) {\n            Text(\n                stringResource(R.string.helloWorldButtonText),\n                fontSize = 32.sp,\n            )\n        }\n    }\n}\n```\n\nMake sure to include the following in your `AndroidManifest.xml` under the application tag:\n\n```xml\n    \u003capplication\n        \u003e\n        ...\n        \u003cuses-library android:name=\"helloworld\"\n            android:required=\"true\" /\u003e\n        ...\n    \u003c/application\u003e\n```\n\nAnd that's it!\n\n## Running on the emulator\n### Inside the AOSP tree\n\nAfter build, you can run the emulator in the terminal where you set up the environment variables with\n\n```\nemulator\n```\n\n### Outside the AOSP tree\n\nIf you use a remote server to build your addon (It could be a good idea. Building the AOSP right now could be a really really hard job for some hardware) you will probably want to extract the emulator to your local machine. Actually, that's very easy and you already have all you need.\n\nGo to your Android Studio and create an emulator using the *Device Manager* tool. Since we builded to a Automotive TARGET, select an hardware under the _Automotive_ category as well. For the _system image_, select (or download first if you don't have it yet) the API 34 image.\n\nBefore launching the emulator, extract the content of `profusion_sdk_addon-linux-img.zip` to the API 34 image folder:\n\n```bash\nunzip out/host/linux-x86/sdk_addon/profusion_sdk_addon-linux-img.zip -d $ANDROID_SDK_ROOT/system-images/android-34-ext9/android-automotive\n```\n\n---\nNote: If you choose to build a different TARGET like `aosp_x86_64` or another, you will need to extract the content to a different path and the `profusion_sdk_addon-linux-img.zip` could not work as expected. In that case, you could use `make emu_img_zip` to generate a similar `sdk-repo-linux-system-images.zip` under `$PRODUCT_OUT` folder.\n\n---\n\n### Build and install the App\n\nAfter including the SDK Addon that we created in the correct directory under your `$ANDROID_SDK_HOME`, you can build the app with Android Studio _Build \u003e Make Project_, or with command line:\n\n```bash\ncd app/HelloWorldApp\n./gradlew installDebug\n```\n\nor\n\n```bash\ncd app/HelloWorldApp\n./gradlew build\nadb install app/build/outputs/apk/debug/app-debug.apk\n```\n\n### Running the app\n\nIf you run the application and then check the `logcat` searching for \"HelloWorldService,\" then you will be able to see the service printing \"Hello World.\"\n\n```bash\nadb shell\n# logcat | grep -i HelloWorldService\n6002  6020 D HelloWorldService: Hello World.\n```\n\n![Android emulator running the helloworld app and helloword service](assets/running_app.png \"Helloworld App\")\n\n### HAL example\n\nThere is an example on this repository of how to implement a HAL and expose a Manager through the SDK Add-on. If you want to see more about this, take a look at the [hal_example](https://github.com/profusion/android-sdk-addon-example/tree/hal_example) branch.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprofusion%2Fandroid-sdk-addon-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprofusion%2Fandroid-sdk-addon-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprofusion%2Fandroid-sdk-addon-example/lists"}