{"id":15288344,"url":"https://github.com/canelmas/let","last_synced_at":"2025-04-05T23:09:56.069Z","repository":{"id":57718104,"uuid":"44735189","full_name":"canelmas/let","owner":"canelmas","description":"Annotation based simple API flavored with AOP to handle new Android runtime permission model","archived":false,"fork":false,"pushed_at":"2018-02-11T11:35:10.000Z","size":2807,"stargazers_count":530,"open_issues_count":20,"forks_count":37,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-29T22:07:37.914Z","etag":null,"topics":["android","aop","aop-aspectj","gradle","gradle-plugin","kotlin","kotlin-android","library","runtime-permissions"],"latest_commit_sha":null,"homepage":"","language":"Java","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/canelmas.png","metadata":{"files":{"readme":"README.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}},"created_at":"2015-10-22T09:24:28.000Z","updated_at":"2024-05-18T19:15:24.000Z","dependencies_parsed_at":"2022-08-24T13:38:14.193Z","dependency_job_id":null,"html_url":"https://github.com/canelmas/let","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canelmas%2Flet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canelmas%2Flet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canelmas%2Flet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canelmas%2Flet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/canelmas","download_url":"https://codeload.github.com/canelmas/let/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247411235,"owners_count":20934653,"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":["android","aop","aop-aspectj","gradle","gradle-plugin","kotlin","kotlin-android","library","runtime-permissions"],"created_at":"2024-09-30T15:47:47.184Z","updated_at":"2025-04-05T23:09:56.048Z","avatar_url":"https://github.com/canelmas.png","language":"Java","readme":"Let\n====\n\n[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Let-green.svg?style=true)](https://android-arsenal.com/details/1/2843) [![](https://img.shields.io/badge/AndroidWeekly-%23182-red.svg)](http://androidweekly.net/issues/issue-182)\n[![Join the chat at https://gitter.im/canelmas/let](https://badges.gitter.im/canelmas/let.svg)](https://gitter.im/canelmas/let?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nAnnotation based simple API flavoured with [AOP](https://en.wikipedia.org/wiki/Aspect-oriented_programming) to handle new Android runtime permission model.\n\nIf you check [Google's Samples](https://github.com/googlesamples/android-RuntimePermissions/blob/master/Application/src/main/java/com/example/android/system/runtimepermissions/MainActivity.java)\nabout the new permission model, you'll see a lot of boiler plate code for requesting, handling\nand retrying the request for required permissions.\n\nLet will minimize the boiler plate code you have to write for requesting and handling permissions and hence \nhelp you keep your code more readable.  \n  \nLet let Handle\n====\n\nAnnotate your methods requiring permissions with `@AskPermission` and let Let handle the rest.\n \n```java\n@AskPermission(ACCESS_FINE_LOCATION)\nprivate void getUserLocationAndDoSomething() {\n    Toast.makeText(\n        SampleActivity.this, \n        \"Now that I have the permission I need, I'll get your location and do something with it\", \n        Toast.LENGTH_SHORT\n    ).show();\n    ...\n}\n```\n\n```java\n@AskPermission({\n            Manifest.permission.READ_CONTACTS,\n            Manifest.permission.CALL_PHONE,\n            Manifest.permission.CAMERA\n})\nprivate void skipTutorial() {\n    // permissions needed for the best app experience are granted; let's go to the app's home screen\n    startActivity(new Intent(this, HomeActivity.class));\n}\n```\n\nLet will check these annotated methods and execute them unless the permissions required are granted;\notherwise Let will put on hold the method execution and request these permissions at runtime. After examining \nthe permission request result, Let will execute the method already put on hold only if the permissions are granted by user.\n  \nLet will also inform about the rationales before making any permission request\nand tell about denied permissions; whether they're simply denied or with 'Never Ask Again' checked.   \n \nJust make sure to override the `onRequestPermissionsResult` in your Activity or Fragment, where your\n`@AskPermission` annotated methods are located:\n\n```java\n@Override\npublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {\n    Let.handle(this, requestCode, permissions, grantResults);\n}\n```\n\nAnd make sure your Activity or Fragment implements `RuntimePermissionListener` in order to get notified \nabout denied permissions and rationales:\n\n```java\npublic class SampleActivity extends AppCompatActivity implements RuntimePermissionListener {\n    \n    // ....\n    \n    @Override\n    public void onShowPermissionRationale(List\u003cString\u003e permissions, final RuntimePermissionRequest request) {\n        /**\n        * you may show permission rationales in a dialog, wait for user confirmation and retry the permission \n        * request by calling request.retry()    \n        */               \n    }\n  \n    @Override\n    public void onPermissionDenied(List\u003cDeniedPermission\u003e deniedPermissionList) {\n        /**\n        * Do whatever you need to do about denied permissions:\n        *   - update UI\n        *   - if permission is denied with 'Never Ask Again', prompt a dialog to tell user\n        *   to go to the app settings screen in order to grant again the permission denied \n        */              \n    }\n    \n    //  ...\n}\n```\n\nUsage\n====\n\nAdd it to your project today!\n\n```groovy\n\nbuildscript {\n    repositories {                    \n        jcenter()        \n    }\n\n    dependencies {        \n        classpath 'com.canelmas.let:let-plugin:0.1.11'\n    }\n}\n\napply plugin: 'com.android.application'\napply plugin: 'let'\n\nrepositories {        \n    jcenter()\n}\n```\n\nFor kotlin :\n```groovy\n\nbuildscript {\n    repositories {\n        jcenter()\n    }\n\n    dependencies {\n        classpath 'com.canelmas.let:let-plugin:1.0.0-beta1'\n    }\n}\n\napply plugin: 'com.android.application'\napply plugin: 'let'\n\nrepositories {\n    jcenter()\n}\n```\n\n\nProguard\n====\n\nMake sure your proguard rule set includes following lines: \n\n    -keep class com.canelmas.let.** { *; }\n    -keepnames class * implements com.canelmas.let.RuntimePermissionListener\n\n    -keepclassmembers class * implements com.canelmas.let.RuntimePermissionListener {\n        public void onRequestPermissionsResult(***);\n    }\n\n    -keepclasseswithmembernames class * {\n        @com.canelmas.let.* \u003cmethods\u003e;\n    }\n\nLicense\n====\n\n    Copyright 2016 Can Elmas\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","funding_links":[],"categories":["Libs"],"sub_categories":["\u003cA NAME=\"Tools\"\u003e\u003c/A\u003eTools"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanelmas%2Flet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcanelmas%2Flet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanelmas%2Flet/lists"}