{"id":17688687,"url":"https://github.com/boybeak/easypack","last_synced_at":"2026-02-14T04:08:03.079Z","repository":{"id":87642757,"uuid":"349760557","full_name":"boybeak/EasyPack","owner":"boybeak","description":"My easypack to start a new project.","archived":false,"fork":false,"pushed_at":"2021-04-03T07:33:42.000Z","size":177,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-24T09:51:37.873Z","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/boybeak.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2021-03-20T15:19:23.000Z","updated_at":"2021-05-15T10:33:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"6683362a-e0e6-4637-92f3-d7d7e9d5cf24","html_url":"https://github.com/boybeak/EasyPack","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/boybeak/EasyPack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boybeak%2FEasyPack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boybeak%2FEasyPack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boybeak%2FEasyPack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boybeak%2FEasyPack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boybeak","download_url":"https://codeload.github.com/boybeak/EasyPack/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boybeak%2FEasyPack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273892837,"owners_count":25186562,"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","status":"online","status_checked_at":"2025-09-06T02:00:13.247Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-10-24T11:45:10.009Z","updated_at":"2026-02-14T04:08:03.035Z","avatar_url":"https://github.com/boybeak.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EasyPack ![](https://img.shields.io/badge/EasyPack-v0.1.3-blue)\n## Install\n\nIn your root build.gradle\n\n```groovy\nbuildscript {\n    repositories {\n        google()\n        mavenCentral()\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        mavenCentral()\n    }\n}\n```\n\nIn your module's build.gradle\n\n```groovy\ndependencies {\n  implementation \"com.github.boybeak:easy-safr:$easy_pack_version\"\n  implementation \"com.github.boybeak:easy-fp:$easy_pack_version\"\n  implementation \"com.github.boybeak:easy-picker:$easy_pack_version\"\n}\n```\n\n\n\n## Summary\n\nI create a principle called **WCWC**, means \"Where calls, where callbacks\". Aimed to put calls and callbacks together.\n\nFor example, `startActivityForResult` is a call, but the callback is in another method `onActivityResult`. This breaks **WCWC** principle.\n\n**easy-safr:** SAFR is short for *startActivityForResult*.\n\n**easy-fp:** A helper library for FileProvider.\n\n**easy-picker:** A helper library for get or capture audio, image or video content from recorder, gallery or camera. This library based on easy-safr and easy-fp.\n\n\n\n## Easy-safr\n\n```kotlin\nval it = Intent(this, ResultMakeActivity::class.java)\nEasySAFR.startActivityForResult(applicationContext, it,\n  object : OnResultAdapter {\n    override fun onOk(id: String, requestCode: Int, data: Intent?) {\n      Toast.makeText(this@MainActivity, \"onOk\", Toast.LENGTH_SHORT).show()\n    }\n\n    override fun onCancel(id: String) {\n      Toast.makeText(this@MainActivity, \"onCancel\", Toast.LENGTH_SHORT).show()\n    }\n  }\n)\n```\n\nThere's no need to handle the result in onActivityResult method.\n\n\n\n## Easy-fp\n\nFileProvider is a bit complex. Easy-fp makes it easy to use and provide a uri-to-file access.\n\nMake a paths.xml file in R.xml res folder.\n\n```xml\n\u003c!--R.xml.paths--\u003e\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003cpaths xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n    \u003cfiles-path name=\"files_path\" path=\"images/\"/\u003e\n    \u003ccache-path name=\"my_images\" path=\"images/\" /\u003e\n    \u003cexternal-cache-path\n        name=\"external_cache_path\"\n        path=\"images\"\n        /\u003e\n\u003c/paths\u003e\n```\n\n\u003e **Do not repeat any one of the path items above.**\n\u003e\n\u003e If you make 2 files-path items with the same name or path, this library not suite for you.\n\n```xml\n\u003cprovider\n\tandroid:name=\"androidx.core.content.FileProvider\"\n\tandroid:authorities=\"${applicationId}.fileprovider\"\n\tandroid:exported=\"false\"\n\tandroid:grantUriPermissions=\"true\"\u003e\n  \u003cmeta-data\n\t\tandroid:name=\"android.support.FILE_PROVIDER_PATHS\"\n\t\tandroid:resource=\"@xml/paths\" /\u003e\n\u003c/provider\u003e\n```\n\nGet file from uri.\n\n```kotlin\nval uri = ...\nval file = EasyFP.guess(this, uri)\n```\n\nIn this example, the `uri` must be in the R.xml.paths items.\n\nGet uri by dir and file name.\n\n```kotlin\nEasyFP.withAuthority(this, \"your authority\")\n  .cacheDir()\n  .name(\"xyz.jpg\")\n  .uri()\n//.file() or .uri()\n```\n\nUse a default FileProvider - The first FileProvider listed in manifest file.\n\n```kotlin\nEasyFP.withDefault(this)\n  .cacheDir()\n  .name(\"xyz.jpg\")\n  .pair() \n//.file() or .uri()\n```\n\n`uri()` means return uri, `file` means return file, `pair()`means return both uri and file.\n\n\n\n## Easy-picker\n\n```kotlin\nclass App : Application() {\n    override fun onCreate() {\n        super.onCreate()\n        EasyPicker.init(Config.defaultConfig(this))\n      \t// OR\n        EasyPicker.init(\n          Config.Builder()\n          .copyDir(File(cacheDir, \"easy_picker\"))\n          .noMedia()\n          .outputFactory { cxt -\u003e\n                          EasyFP.withDefault(cxt)\n                            .cacheDir()\n                            .mkdirs(\"easy_picker\")\n                            .name(UUID.randomUUID().toString())\n                            .pair()\n                         }\n          .build()\n    }\n}\n```\n\n\n\n```kotlin\n// Get mutiple images\nEasyPicker.fromGallery(ImageType.any()).multipleGet(this) { uris, files -\u003e\n\tLog.v(TAG, \"multipleGet ${uris.size} ${files.size}\")\n}\n\n// Record an audio\nEasyPicker.captureAudio().capture(this) { uri, file -\u003e\n\tLog.v(TAG, \"uri=$uri file=$file\")\n}\n\n// Capture an image\nEasyPicker.captureImage()\n.output(somePair) // If you do not provide somePair, it will auto generate in OutputFactory\n.capture(this) { uri, file -\u003e\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboybeak%2Feasypack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fboybeak%2Feasypack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboybeak%2Feasypack/lists"}