{"id":19139930,"url":"https://github.com/arcblock/arcblock-android-sdk","last_synced_at":"2025-05-06T23:16:26.073Z","repository":{"id":96024745,"uuid":"137827452","full_name":"ArcBlock/arcblock-android-sdk","owner":"ArcBlock","description":"Used to integrate Android apps with ArcBlock Platform.","archived":false,"fork":false,"pushed_at":"2020-05-18T04:15:20.000Z","size":1996,"stargazers_count":8,"open_issues_count":1,"forks_count":2,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-05-06T23:15:32.523Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ArcBlock.png","metadata":{"files":{"readme":"README-0.2.3.md","changelog":"CHANGELOG.md","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,"zenodo":null}},"created_at":"2018-06-19T01:58:40.000Z","updated_at":"2021-05-25T18:16:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"6a76de5b-8d00-4c06-83c8-233575db028d","html_url":"https://github.com/ArcBlock/arcblock-android-sdk","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcBlock%2Farcblock-android-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcBlock%2Farcblock-android-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcBlock%2Farcblock-android-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArcBlock%2Farcblock-android-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ArcBlock","download_url":"https://codeload.github.com/ArcBlock/arcblock-android-sdk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252782835,"owners_count":21803410,"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-09T07:15:40.479Z","updated_at":"2025-05-06T23:16:26.066Z","avatar_url":"https://github.com/ArcBlock.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ArcBlock Android SDK\n\n[![license](https://img.shields.io/badge/API-15+-green.svg?longCache=true\u0026style=flat)](https://android-arsenal.com/api?level=15)  [![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/ArcBlock/arcblock-android-sdk/blob/master/LICENSE)\n\n[中文 README](https://github.com/ArcBlock/arcblock-android-sdk/blob/master/README-CN.md)\n\n\u003e Developers need to have basic [GraphQL](https://graphql.org/) capabilities before accessing the ArcBlock Android SDK. We also provide a fully functional [ArcBlock OCAP Playground](https://ocap.arcblock.io/) where developers can use it to write and test the GraphQL statements they want.\n\n## Absdkcorekit Library\n\nAbsdkcorekit Library is on the basis of the [apollo-android](https://github.com/apollographql/apollo-android) encapsulated ` Data ` layer core Library, we introduced the Android's latest ` Architecture Components `, among them the ` LiveData ` and ` ViewModel ` and ` Apollo - android Library ` combined with encapsulated into `CoreKitQueryViewModel`, `CoreKitPagedQueryViewModel`, `CoreKitSubscriptionViewModel`.\n\n#### 1. Import Absdkcorekit Library\n\nAdd the following code to the project root directory `build.gradle` file:\n\n``` groovy\nbuildscript {\n  dependencies {\n    //...\n    classpath 'com.apollographql.apollo:apollo-gradle-plugin:1.0.0-alpha'\n  }\n}\n\nallprojects {\n   repositories {\n\t//...\n\tmaven { url \"http://android-docs.arcblock.io/release\" }\n   }\n}\n```\n\nAdd the following code into the app module `build.gradle` file:\n\n``` groovy\napply plugin: 'com.apollographql.android'\n\napollo {\n    useJavaBeansSemanticNaming = true\n}\n\n//......\ndependencies {\n  // x.x.x =\u003e release version\n  def absdkcorekitversion = \"x.x.x\" \n  implementation(\"com.arcblock.corekit:absdkcorekit:$absdkcorekitversion:release@aar\"){\n\ttransitive = true\n  }\n}\n```\n\n#### 2. Create graphql directory and download add `schema.json` and create `.graphql` file\n\n\u003e Recommend to create a directory which is the same as app module package name, such as sample code of `arcblock-android-sdk/app/src/main/graphql/com/arcblock/sdk/demo/`，`arcblock-android-sdk/app/src/main/graphql/` behind relatively catalogue and sample project package name is consistent, Of course, you can also specify directory correlation, please refer to the [explicit-schema-location](https://github.com/apollographql/apollo-android#explicit-schema-location) .\n\n1. `schema.json` download address: [bitcoin.json](https://ocap.arcblock.io/doc/bitcoin.json) download later renamed `schema.json`, you can be in the sample project of `arcblock-android-sdk/app/src/main/graphql/com/arcblock/sdk/demo/` directory to find this file, you can directly copy to use. \n2. Using [ArcBlock OCAP Playground](https://ocap.arcblock.io/)  write and test by GraphQL statements, and make a copy of it to a `.graphql` file, you can be in the sample project of `arcblock-android-sdk/app/src/main/graphql/com/arcblock/sdk/demo/` directory to find similar sample files.\n3. Build your project, after successful compilation, will you be in `build` found directory compiled automatically generated `Java` code, you can be in the sample project of `arcblock-android-sdk/app/build/generated/source/apollo/` directory to see the generated code, you don't need to modify the automatically generated code.\n\n#### 3. Implement common query function\n\n1. First, to customize a class inherited from the `CoreKitQuery` abstract class, you need to implement three parts:\n\t- **Constructor:** Implement a constructor that matches the current usage, depending on whether the Query is used in FragmentActivity or Fragment and whether the currently passed in is a custom ABCoreKitClient or the default ABCoreKitClient\n\t- **map(...) method:** The method for CoreKitBeanMapperInterface interface implementation, provide CoreKitQueryViewModel internal use, is used to return the Response into the final desired data format\n\t- **getQuery() method:** Initialize and return a current Query object to implement a concrete business Query\n\n\tSample code:\n\n\t```java\n\t/**\n     * AccountByAddressQueryHelper for AccountByAddressQuery\n     */\n    private class AccountByAddressQueryHelper extends CoreKitQuery\u003cAccountByAddressQuery.Data, AccountByAddressQuery.AccountByAddress\u003e {\n\n        public AccountByAddressQueryHelper(FragmentActivity activity, LifecycleOwner lifecycleOwner, ABCoreKitClient client) {\n            super(activity, lifecycleOwner, client);\n        }\n\n        @Override\n        public AccountByAddressQuery.AccountByAddress map(Response\u003cAccountByAddressQuery.Data\u003e dataResponse) {\n            if (dataResponse != null) {\n                return dataResponse.data().getAccountByAddress();\n            }\n            return null;\n        }\n\n        @Override\n        public Query getQuery() {\n            return AccountByAddressQuery.builder().address(address).build();\n        }\n    }\n\t```\n\n\t\u003e Class naming a proposal to the corresponding `Query`, `Mutaition`, `Subscription` name plus `-Helper` end, such as the above AccountByAddressQuery corresponding AccountByAddressQueryHelper\n\n2. The second step, create a `xxxHelper` query help the object of the class, and set the Observe object\n\n\t- Create a `xxxHelper` class object:\n\t\n\t\t```java\n\t\tAccountByAddressQueryHelper accountByAddressQueryHelper = new AccountByAddressQueryHelper(this, this, DemoApplication.getInstance().abCoreKitClientBtc());\n\t\t```\n\n\t\tAs mentioned above, there are four different implementations to choose from.\n\n\t- Set the Observe object:\n\t\n\t\t```java\n\t\taccountByAddressQueryHelper.setObserve(new Observer\u003cCoreKitBean\u003cAccountByAddressQuery.AccountByAddress\u003e\u003e() {\n\t\t\t\t@Override\n\t\t\t\tpublic void onChanged(@Nullable CoreKitBean\u003cAccountByAddressQuery.AccountByAddress\u003e coreKitBean) {\n\t\t\t\t\tif (coreKitBean.getStatus() == CoreKitBean.SUCCESS_CODE) {\n\t\t\t\t\t\tAccountByAddressQuery.AccountByAddress accountByAddress = coreKitBean.getData();\n\t\t\t\t\t\t// get data and set data to view here.\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// show error msg.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t```\n\t\n#### 4. Implement paged Query function\n\n1. First, to customize a class inherited from the `CoreKitPagedQuery` abstract class, you need to implement five parts:\n\t- **Constructor:** Implement a constructor that matches the current usage, depending on whether the paged query is used in FragmentActivity or Fragment and whether the currently passed in is a custom ABCoreKitClient or the default ABCoreKitClient\n\t- **map(...) method:** The method for CoreKitBeanMapperInterface interface implementation, provide CoreKitPagedQueryViewModel internal use, is used to return the Response into the final desired data format\n\t\t\n\t\t\u003e The difference here is that the map(...) approach, the need to manually set `setHasMore(boolean hasMore)` and `setCursor(String cursor)`, these two parameters is the basis of the underlying determine whether paging request\n\t\t\n\t- **getInitialQuery() method:** Initialize and return an initial Query object for a paged query\n\t- **getLoadMoreQuery() method:** Initialize and return a Query object for more queries\n\t- **getRefreshQuery() method:** Initialize and return a Query object for the paging Query refresh Query, which is generally the same as the Query object returned by getInitialQuery()\n\n\tSample code:\n\n\t```java\n\t/**\n     *  BlocksByHeightQueryHelper for BlocksByHeightQuery\n     */\n    private class BlocksByHeightQueryHelper extends CoreKitPagedQuery\u003cBlocksByHeightQuery.Data, BlocksByHeightQuery.Datum\u003e {\n\n        public BlocksByHeightQueryHelper(FragmentActivity activity, LifecycleOwner lifecycleOwner, ABCoreKitClient client) {\n            super(activity, lifecycleOwner, client);\n        }\n\n        @Override\n        public List\u003cBlocksByHeightQuery.Datum\u003e map(Response\u003cBlocksByHeightQuery.Data\u003e dataResponse) {\n            if (dataResponse != null \u0026\u0026 dataResponse.data().getBlocksByHeight() != null) {\n                // set page info to CoreKitPagedQuery\n                if (dataResponse.data().getBlocksByHeight().getPage() != null) {\n                    // set is have next flag to CoreKitPagedQuery\n                    setHasMore(dataResponse.data().getBlocksByHeight().getPage().isNext());\n                    // set new cursor to CoreKitPagedQuery\n                    setCursor(dataResponse.data().getBlocksByHeight().getPage().getCursor());\n                }\n                return dataResponse.data().getBlocksByHeight().getData();\n            }\n            return null;\n        }\n\n        @Override\n        public Query getInitialQuery() {\n            return BlocksByHeightQuery.builder().fromHeight(startIndex).toHeight(endIndex).build();\n        }\n\n        @Override\n        public Query getLoadMoreQuery() {\n            PageInput pageInput = null;\n            if (!TextUtils.isEmpty(getCursor())) {\n                pageInput = PageInput.builder().cursor(getCursor()).build();\n            }\n            return BlocksByHeightQuery.builder().fromHeight(startIndex).toHeight(endIndex).paging(pageInput).build();\n        }\n\n        @Override\n        public Query getRefreshQuery() {\n            return BlocksByHeightQuery.builder().fromHeight(startIndex).toHeight(endIndex).build();\n        }\n    }\n\t```\n\n\t\u003e Class naming a proposal to the corresponding `Query`, `Mutaition`, `Subscription` concrete class name plus `-Helper` end, such as the above BlocksByHeightQuery corresponding BlocksByHeightQueryHelper\n\n2. The second step, create a `xxxHelper` query help the object of the class, and set the Observe object, request and get the data\n\n\t- Create a `xxxHelper` class object:\n\t\n\t\t```java\n\t\tmBlocksByHeightQueryHelper = new BlocksByHeightQueryHelper(this, this, DemoApplication.getInstance().abCoreKitClientBtc());\n\t\t```\n\n\t\tAs mentioned above, there are four different implementations to choose from.\n\t\n\t- Set the Observe object:\n\n\t\t```java\n\t\tmBlocksByHeightQueryHelper.setObserve(new Observer\u003cCoreKitPagedBean\u003cList\u003cBlocksByHeightQuery.Datum\u003e\u003e\u003e() {\n\t\t\t\t@Override\n\t\t\t\tpublic void onChanged(@Nullable CoreKitPagedBean\u003cList\u003cBlocksByHeightQuery.Datum\u003e\u003e coreKitPagedBean) {\n\t\t\t\t\tif (coreKitPagedBean.getStatus() == CoreKitBean.SUCCESS_CODE) {\n\t\t\t\t\t\tif (coreKitPagedBean.getData() != null) {\n\t\t\t\t\t\t// get data and set data to view here.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t```\n\n\t- Call the refresh method to refresh\n\n\t\t```java\n\t\tmBlocksByHeightQueryHelper.refresh();\n\t\t```\n\n\t- Call the loadMore method to load the next page of data\n\n\t\t```java\n\t\tmBlocksByHeightQueryHelper.loadMore();\n\t\t```\n\n#### 5. Implement data subscription function\n\n1. Open the socket switch when init the ABCoreClient :\n\n\t```java\n\tABCoreKitClient.xxx\n\t\t\t.xxxx\n\t\t\t.setOpenSocket(true) // the socket switch\n\t\t\t.xxxx\n\t\t\t.build();\n\t```\n\n2. The second step, customize a class to inherit from the `CoreKitSubscription` abstract class, and you need to implement three sections:\n\n\t- **Constructor:** Implement a constructor that matches the current usage, depending on whether the subscription is used in FragmentActivity or Fragment and whether the currently passed in is a custom ABCoreKitClient or the default ABCoreKitClient\n\t- **getSubscription() method:** Initialize and return a Subscription object\n\t- **getResultDataClass() method:** Return the desired Data type of the Class, eventually for CoreKitSubscriptionViewModel in json parsing\n\n\tSample code:\n\n\t```java\n\t/**\n     * NewBlockMinedSubscriptionHelper for NewBlockMinedSubscription\n     */\n    private class NewBlockMinedSubscriptionHelper extends CoreKitSubscription\u003cNewBlockMinedSubscription.Data, NewBlockMinedSubscription\u003e {\n\n        public NewBlockMinedSubscriptionHelper(FragmentActivity activity, ABCoreKitClient client) {\n            super(activity, client);\n        }\n\n        @Override\n        public NewBlockMinedSubscription getSubscription() {\n            return new NewBlockMinedSubscription();\n        }\n\n        @Override\n        public Class\u003cNewBlockMinedSubscription.Data\u003e getResultDataClass() {\n            return NewBlockMinedSubscription.Data.class;\n        }\n    }\n\t```\n\n\t\u003e Class naming a proposal to the corresponding `Query`, `Mutaition`, `Subscription` concrete class name plus `-Helper` end, such as the above NewBlockMinedSubscription corresponding NewBlockMinedSubscriptionHelper\n\n3. The third step, create a `xxxHelper` class object and set CoreKitSubCallBack, CoreKitSocketStatusCallBack\n    \n\t- Create a `xxxHelper` class object:\n\n\t\t```java\n\t\tmNewBlockMinedSubscriptionHelper = new NewBlockMinedSubscriptionHelper(this, DemoApplication.getInstance().abCoreKitClientEth());\n\t\t```\n\n\t\tAs mentioned above, there are four different implementations to choose from.\n\n\t- Set the CoreKitSubCallBack\n\n\t\t```java\n\t\t// add data callback\n\t\tmNewBlockMinedSubscriptionHelper.setCoreKitSubCallBack(new CoreKitSubscriptionViewModel.CoreKitSubCallBack\u003cNewBlockMinedSubscription.Data\u003e() {\n\t\t\t@Override\n\t\t\tpublic void onNewData(CoreKitBean\u003cNewBlockMinedSubscription.Data\u003e coreKitBean) {\n\t\t\t\tif (coreKitBean != null \u0026\u0026 coreKitBean.getStatus() == CoreKitBean.SUCCESS_CODE) {\n\t\t\t\t\t// get data and set data to view here.\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t```\n\t- Set the CoreKitSocketStatusCallBack\n\n\t\t```java\n\t\t// add status callback\n\t\tmNewBlockMinedSubscriptionHelper.setCoreKitSocketStatusCallBack(new CoreKitSocketStatusCallBack() {\n\t\t\t@Override\n\t\t\tpublic void onOpen() {\n\t\t\t    // do something here when socket on open\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic void onClose() {\n\t\t\t    // do something here when socket on close\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic void onError() {\n\t\t\t    // do something here when on error\n\t\t\t}\n\t\t});\n\t\t```\n\n#### 6. Other Settings\n\n1. `CustomType` Setting：\n\t1. First, add `customTypeMapping` in the `build.gradle` file of `app module`:\n\t\t\n\t\t```groovy\n\t\tapollo {\n\t\t  customTypeMapping['DateTime'] = \"java.util.Date\"\n\t\t}\n\t\t```\n\t\t\n\t2. Create the corresponding `CustomTypeAdapter` used to resolve the corresponding `CustomType` :\n\t\n\t\t```java\n\t\tCustomTypeAdapter dateCustomTypeAdapter = new CustomTypeAdapter\u003cDate\u003e() {\n\t\t\n\t\t@Override\n\t\tpublic Date decode(CustomTypeValue value) {\n\t\t\ttry {\n\t\t\t\tSimpleDateFormat utcFormat = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss.000000'Z'\");\n\t\t\t\tutcFormat.setTimeZone(TimeZone.getTimeZone(\"UTC\"));\n\t\t\t\tDate gpsUTCDate = utcFormat.parse(value.value.toString());\n\t\t\t\treturn gpsUTCDate;\n\t\t\t} catch (ParseException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\t@Override\n\t\tpublic CustomTypeValue encode(Date value) {\n\t\t\tSimpleDateFormat sdf = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss.000000'Z'\");\n\t\t\treturn new CustomTypeValue.GraphQLString(sdf.format(value));\n\t\t}\n\t\t};\n\t\t```\n\t\t\n2. `ABCoreKitClient` initialization:\n\t\n\tRecommended in the main process of ` Application onCreate ` method initializes a global singleton ` ABCoreKitClient ` object:\n\t\n\t```java\n\tmABCoreClientBtc = ABCoreKitClient.builder(this, CoreKitConfig.ApiType.API_TYPE_BTC)\n                    .addCustomTypeAdapter(CustomType.DATETIME, dateCustomTypeAdapter)\n                    .setOpenOkHttpLog(true)\n                    .setDefaultResponseFetcher(ApolloResponseFetchers.CACHE_AND_NETWORK)\n                    .build();\n\t```\n\t\n\tAt the time of initialization, you can pass in custom `okHttpClient`, `CustomTypeAdapter`, `ResponseFetcher` parameters.\n\n## License\n\nArcBlockSDK is available under the MIT license. See the [LICENSE file](https://github.com/ArcBlock/arcblock-android-sdk/blob/master/LICENSE) for more info.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcblock%2Farcblock-android-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farcblock%2Farcblock-android-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcblock%2Farcblock-android-sdk/lists"}