{"id":4807,"url":"https://github.com/netbeast/react-native-android-widget-poc","last_synced_at":"2025-07-12T09:31:36.097Z","repository":{"id":55065107,"uuid":"108921136","full_name":"netbeast/react-native-android-widget-poc","owner":"netbeast","description":" 🤖 React Native Android widgets bridged to JS, a proof of concept ","archived":false,"fork":false,"pushed_at":"2019-03-26T11:32:32.000Z","size":5812,"stargazers_count":207,"open_issues_count":4,"forks_count":21,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-08-16T19:52:59.432Z","etag":null,"topics":["android","android-widget","react-native","react-native-android","widget"],"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/netbeast.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-30T23:47:59.000Z","updated_at":"2024-06-18T03:33:39.000Z","dependencies_parsed_at":"2022-08-14T10:50:28.414Z","dependency_job_id":null,"html_url":"https://github.com/netbeast/react-native-android-widget-poc","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/netbeast%2Freact-native-android-widget-poc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netbeast%2Freact-native-android-widget-poc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netbeast%2Freact-native-android-widget-poc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netbeast%2Freact-native-android-widget-poc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/netbeast","download_url":"https://codeload.github.com/netbeast/react-native-android-widget-poc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225812306,"owners_count":17527970,"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","android-widget","react-native","react-native-android","widget"],"created_at":"2024-01-05T20:17:24.803Z","updated_at":"2024-11-21T22:29:41.570Z","avatar_url":"https://github.com/netbeast.png","language":"Java","readme":"# React Native Android Widget Proof Of Concept\n\n:robot: Using React Native and having Android widgets is possible.\n\n1. Create buttons in Java / Android XML to triggers intents\n2. Process these intents from the Javascript side with all the tools and flexibility\nfrom react-native.\n\n\u003e It is a bit complicated, and we developed it with little knowledge of Android in the beginnings, so I apologize if it feels bad designed.\n\u003e 🚧  Please help us improve the strategy / code layout with Pull Requests.\n\n## Try\n```bash\ngit clone https://github.com/jsdario/react-native-android-widget-poc\ncd react-native-android-widget-poc\nnpm install # or yarn install\nreact-native link react-native-background-timer # to avoid the main thread\nreact-native run-android\n```\n\n### Demo\n\u003cp float=\"left\"\u003e\n\u003cimg src=\"screenshots/listed.png\" width=\"240\" /\u003e\n\u003cimg src=\"screenshots/enabled.png\" width=\"240\" /\u003e\n\u003cimg src=\"screenshots/triggering.png\" width=\"240\" /\u003e\n\u003cimg src=\"screenshots/app.png\" width=\"240\" /\u003e\n\u003c/p\u003e\n\nTo build your own Android Widget, use this project to bootstrap the widget and hack upon or replicate the strategy to make it work.\n\n## How it works\nIt consists in several Android and React Native concepts. Please read with eskepticism, other formulas may be simpler.\n* Your React Native app, bundles all the JS, even the one\ncorresponding to your widget and services. It is the main [Activity](https://developer.android.com/reference/android/app/Activity.html) of the Android realm.\n* A [WidgetProvider](https://developer.android.com/reference/android/appwidget/AppWidgetProvider.html) is meant to render the view onto your Android desktop and also to listen for the events (button presses) that will be sent to your app. It is then, a Broadcast receiver that can process in Java different intents, before it reaches the JS side.\n* A [Headless JS task](https://facebook.github.io/react-native/docs/headless-js-android.html) is the React Native approach to an Android Service. This part will process the intents (events) coming from your WidgetProvider.\n* A custom [Native Module](https://facebook.github.io/react-native/docs/native-modules-android.html) is used to bridge the JS realm with the AppWidgetProvider.\n\nIf you take a look at the AndroidManifest.xml you can see how the Android relevant parts are declared to the system:\n```diff\n\u003cmanifest \n    xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.androidwidgetpoc\" android:versionCode=\"1\" android:versionName=\"1.0\"\u003e\n    \u003cuses-permission android:name=\"android.permission.INTERNET\" /\u003e\n    \u003cuses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/\u003e\n+   \u003cuses-permission android:name=\"android.permission.WAKE_LOCK\" /\u003e\n    \u003cuses-sdk android:minSdkVersion=\"16\" android:targetSdkVersion=\"22\" /\u003e\n    \u003capplication android:name=\".MainApplication\" android:allowBackup=\"true\" android:label=\"@string/app_name\" android:icon=\"@mipmap/ic_launcher\" android:theme=\"@style/AppTheme\"\u003e\n        \u003cactivity android:name=\".MainActivity\" android:label=\"@string/app_name\" android:configChanges=\"keyboard|keyboardHidden|orientation|screenSize\" android:windowSoftInputMode=\"adjustResize\"\u003e\n            \u003cintent-filter\u003e\n                \u003caction android:name=\"android.intent.action.MAIN\" /\u003e\n                \u003ccategory android:name=\"android.intent.category.LAUNCHER\" /\u003e\n            \u003c/intent-filter\u003e\n        \u003c/activity\u003e\n        \u003cactivity android:name=\"com.facebook.react.devsupport.DevSettingsActivity\" /\u003e\n+        \u003creceiver android:name=\"WidgetProvider\"\u003e\n+            \u003cintent-filter\u003e\n+                \u003caction android:name=\"android.appwidget.action.APPWIDGET_UPDATE\" /\u003e\n+            \u003c/intent-filter\u003e\n+            \u003cintent-filter\u003e\n+                \u003caction android:name=\"com.androidwidgetpoc.CHARM_1\" /\u003e\n+                \u003caction android:name=\"com.androidwidgetpoc.CHARM_2\" /\u003e\n+                \u003caction android:name=\"com.androidwidgetpoc.CHARM_3\" /\u003e\n+            \u003c/intent-filter\u003e\n+            \u003cmeta-data android:name=\"android.appwidget.provider\" android:resource=\"@xml/widgetprovider\" /\u003e\n+        \u003c/receiver\u003e\n+        \u003cservice android:name=\".BackgroundTask\" android:enabled=\"true\" android:label=\"BackgroundAdd\" /\u003e\n    \u003c/application\u003e\n\u003c/manifest\u003e\n``` \n\nA step by step guide on how we got here:\n1. We prepared a Headless JS [widgetTask.js](widgetTask.js) to run in the as the declared service of [BackgroundTask.java](android/app/src/main/java/com/androidwidgetpoc/BackgroundTask.java). We started using Android Studio heavily from this point.\n2. We created a Native Module to layout and print a Widget, so [BackgroundTaskBridge.java](android/app/src/main/java/com/androidwidgetpoc/BackgroundTaskBridge.java) and [BackgroundTaskBridgePackage.java](android/app/src/main/java/com/androidwidgetpoc/BackgroundTaskBridgePackage.java) were born, along with the [layout folder](android/app/src/main/res/layout).\n3. The [WidgetProvider](android/app/src/main/java/com/androidwidgetpoc/WidgetProvider.java) became necessary as a proxy between the intents generated by the Widget layout (rendered thanks to the `BackgroundTaskBridge`) and the actual calls to the `widgetTask` service.\n4. Refined and serialised the messages between all the interfaces.\n\nThe hardest part? The whole JS bundle has to be running in a context for the widgetTask to run valid code. In this proof of concept app it's real quick and simple, but it can lead to huge inconsistencies if you need to pull some data from a remote or read from `AsyncStorage`. Be patient. Use redux or other state management to ensure the conditions you want to be running on.\n\n### Can I create widgets _views_ using React Native instead of Java?\nWe haven't done this, but we belive that from this point has to be much easier,\nhaving the strategy laid down, we'd need to create [Native UI Components](https://facebook.github.io/react-native/docs/native-components-android.html)\ncalling methods from the `RemoteView` class and context instead of the `View` class.\nIt is not trivial to us, though.\n\n\n\u003ca href=\"https://getyeti.co\" target=\"_blank\"\u003e\n   \u003cimg alt=\"works with yeti\" src=\"screenshots/works-with-yeti.png\" width=\"100\" /\u003e\n\u003c/a\u003e\n\n\u003e This proof of concept is applied at [Yeti Smart Home](https://getyeti.co) and is used in production. Some of the art is also produced at Netbeast. Follow us in Github or [Twitter](https://twitter.com/netbeast_co).\n","funding_links":[],"categories":["Components","\u003ca name=\"Widget:-Native-Modules\"\u003eWidget: Native Modules\u003c/a\u003e","Tutorials"],"sub_categories":["Extension","Other Platforms"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetbeast%2Freact-native-android-widget-poc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnetbeast%2Freact-native-android-widget-poc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetbeast%2Freact-native-android-widget-poc/lists"}