Bundel is a digital wellbeing Android app, helping you to focus by grouping up notifications and only releasing them in batches

Overview

Bundel logo
GitHub Workflow Status (branch)   Apache 2.0 license   Watch us code on Twitch   Follow us on Twitter

Bundel is a digital wellbeing Android app, helping you to focus by grouping up notifications and only releasing them in batches, at set times. This minimises context switching and improves productivity, while decreasing the impulse to continuously check your phone.

State of the project

The app is in its very early dev stages. It's likely to crash and burn at any time, it's not optimised, it is not even an MVP (minimum viable product) for what it wants to be. It's a work in progress, and you can expect continued development and fixes, horrible temporary design, and all those fun things we all get through when we're prototyping something. But it will get better! Nice things just need time.

Why this app, why open source

This project was born out of an idea Ivan Morgillo and myself had: we wanted to learn using Jetpack Compose, and maybe catch up on some other cool Android stuff. But side projects never really get completed, and at the same time, just putting the code out there wouldn't really give much insight into the how and why things are done a certain way. Open source is a great way to sharing knowledge, and this being a side project for us, that was a given. But making the sources available in and by itself isn't enough: you miss the context, get presented with a final solution to a largely unknown problem. Just think how many times you've wondered why some code you were reading was done in that way and not in another!

So, we decided we'd share the entire process. We stream ourselves, and some awesome guests, coding on the app, learning as we go, making mistakes and fixing them. We've rather unoriginally named this project Code with the Italians, as both Ivan and myself come from the country that brought you pizza (oh, and by the way, you're welcome!).

This app, Bundel, is our first in this live coding project of ours — who knows what will come next.

Code with the Italians logo

I want to watch y'all crazies code

The good news is, it's really easy to do! To keep up to date with all that's happening, you should follow @codewiththeita on Twitter. If Twitter isn't your thing — we understand! — we also make announcements on Telegram.

We live stream on Twitch and on YouTube. You can also find the whole archive of previous streams over on YouTube.

We regularly stream ourselves coding on this app. We are generally live at these times:

  • Wednesdays, at 18:30 CEST / 12:30 PM EST / 9:30 AM PST
  • Sundays, at 17:00 CEST / 11 AM EST / 8 AM PST

Dates and times may vary though, so watch out for announcements. Or, you know, add this nifty iCal subscription to your calendar. You can find some instructions here.

I want to contribute

Find the guide to contributing here

Acknowledgements

While ourselves, Ivan and Seb, are the two main authors of this app and the hosts of the streams, we need to acknowledge that we're standing on the shoulders of giants.

We need to thank all our friendly guests, each bringing their invaluable experience and patience towards our bs to the streams and app. Thank you, thank you, thank you! You folks are 💛

We also want to thank everyone that helped us behind the scenes with our oddly specific questions and doubts, saving us countless hours of swearing and hacking away at tough problems.

Lastly, we thank everyone who's following us, watching us code, donating to the cause, and spreading the word. Y'all are the reason we're doing this!

I know it says "lastly" right above this, but I feel we should also really thank the fine folks at Google Developers who have done us the honour of featuring us in their brand new DevLibrary.

License

Bundel is licensed under the Apache 2.0 license.

   Copyright 2021 the Bundel contributors

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
Comments
  • Optimize DatabaseModule DI setup

    Optimize DatabaseModule DI setup

    I annotated the provideDatabase method with @Singleton annotation to avoid creating a new database instance for every injection. I also marked the DataRepository with @Singleton for similar reasons. Although DatabaseModule is installed in a singleton component, you still have to scope its bindings. See the following for more info: https://dagger.dev/hilt/components

    I replaced the provide method with constructor injection to bind the DiskImagesStorage. However, one thing to note is that the ImagesStorage from DI is never used.

    opened by ZianeA 2
  • Something is off with WEBP_LOSSLESS support

    Something is off with WEBP_LOSSLESS support

    Describe the bug App crashing after giving access to notifications

    To Reproduce Steps to reproduce the behavior:

    1. Give permissions
    2. Go back to the app

    Expected behavior I would expect to reach the main screen.

    Screenshots N.A.

    Smartphone (please complete the following information):

    • Device: S9
    • OS: Android 10

    Additional context

    java.lang.NoSuchFieldError: No static field WEBP_LOSSLESS of type Landroid/graphics/Bitmap$CompressFormat; in class Landroid/graphics/Bitmap$CompressFormat; or its superclasses (declaration of 'android.graphics.Bitmap$CompressFormat' appears in /system/framework/framework.jar)
            at dev.sebastiano.bundel.storage.DiskImagesStorage$ImageFormat.<clinit>(DiskImagesStorage.kt:109)
            at dev.sebastiano.bundel.storage.DiskImagesStorage.getCachedImageFormat(DiskImagesStorage.kt:99)
            at dev.sebastiano.bundel.storage.DiskImagesStorage.getIconFile(DiskImagesStorage.kt:59)
            at dev.sebastiano.bundel.storage.DiskImagesStorage.saveIcon(DiskImagesStorage.kt:37)
            at dev.sebastiano.bundel.storage.DiskImagesStorage.saveIconsFrom(DiskImagesStorage.kt:24)
            at dev.sebastiano.bundel.storage.RobertoRepository.saveNotification(RobertoRepository.kt:15)
            at dev.sebastiano.bundel.storage.RobertoRepository$saveNotification$1.invokeSuspend(Unknown Source:15)
            at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
            at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
            at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
            at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:84)
            at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
            at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
            at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
            at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1)
            at dev.sebastiano.bundel.notifications.BundelNotificationListenerService.onListenerConnected(BundelNotificationListenerService.kt:30)
            at android.service.notification.NotificationListenerService$MyHandler.handleMessage(NotificationListenerService.java:2076)
            at android.os.Handler.dispatchMessage(Handler.java:107)
            at android.os.Looper.loop(Looper.java:237)
            at android.app.ActivityThread.main(ActivityThread.java:8167)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
    
    bug 
    opened by hamen 2
  • Crash on giving notification access

    Crash on giving notification access

    Describe the bug App crashes on giving notification access

    To Reproduce Steps to reproduce the behavior:

    1. Open project in Android Studio.
    2. Run it on Emulator API 29 or API 30
    3. Give notification access to the app on device
    4. App Crashes

    Error via logcat:

    2021-05-14 14:38:24.583 11014-11014/dev.sebastiano.bundel E/AndroidRuntime: FATAL EXCEPTION: main
        Process: dev.sebastiano.bundel, PID: 11014
        java.lang.RuntimeException: Tried to marshall a Parcel that contained Binder objects.
            at android.os.Parcel.nativeMarshall(Native Method)
            at android.os.Parcel.marshall(Parcel.java:552)
            at dev.sebastiano.bundel.storage.NotificationsCache.toByteArray(NotificationsCache.kt:53)
            at dev.sebastiano.bundel.storage.NotificationsCache.writeToFile(NotificationsCache.kt:44)
            at dev.sebastiano.bundel.storage.NotificationsCache.storeStatusBarNotification(NotificationsCache.kt:36)
            at dev.sebastiano.bundel.storage.RobertoRepository$saveNotification$2.invokeSuspend(RobertoRepository.kt:24)
    

    Expected behavior To not crash

    bug 
    opened by shipsywor 2
  • Don't auto update Kotlin version + KSP

    Don't auto update Kotlin version + KSP

    Add component selection rules rejecting any Kotlin version that does not match the version in the libs.version.toml file. The effect of this is that the Kotlin version will always require a manual version bump and will not be updated with ./gradlew versionCatalogUpdate, which is probably the safest since Compose is also tied to a specific Kotlin version.

    For KSP any version that does not match the specified Kotlin version is rejected so that the KSP and Kotlin versions should always match.

    opened by hvisser 1
  • App crashes at startup

    App crashes at startup

    Describe the bug The app crashes on startup with the following exception:

    java.lang.NullPointerException: getString(context.contentResolver, "enabled_notification_listeners") must not be null
    at dev.sebastiano.bundel.notifications.NotificationServiceHelpersKt.needsNotificationsPermission(NotificationServiceHelpers.kt:9)
    

    To Reproduce I was able to get the app to start by making the following changes:

    internal fun needsNotificationsPermission(context: Context): Boolean {
        val pkgName = context.packageName
        val enabledListeners = Settings.Secure.getString(context.contentResolver, "enabled_notification_listeners")
            ?.split(":")
        if (enabledListeners != null && enabledListeners.isEmpty()) return false
    
        return enabledListeners == null || enabledListeners
            .map { listenerPackageName -> ComponentName.unflattenFromString(listenerPackageName) }
            .none { pkgName == it?.packageName }
    }
    

    However, after the fix, I couldn't reproduce the error by simply uninstalling the app. I had to wipe the device data for the error to recur.

    Desktop (please complete the following information):

    • OS: Windows 10

    Smartphone (please complete the following information):

    • Device: Emulator
    • OS: Android API 30
    bug 
    opened by ZianeA 1
  • Add workflow to periodically check for dependency updates

    Add workflow to periodically check for dependency updates

    This adds a workflow to run ./gradlew versionCatalogUpdate and, if the catalog is updated, create a PR with the diffs. The workflow is scheduled to run once a week, and can be triggered manually too.

    The heavy lifting is in the peter-evans/create-pull-request action that will manage creating and updating the PR when changes are detected. Because during the build gradlew is also changed, that change is reverted before creating the PR.

    The PR does not give a comprehensive description of the changed dependencies, it merely produces a new branch and a diff. The created branch can be used to verify the dependency updates or do adjustments before merging, mainly serving as a reminder that updates are available.

    The initial run will update the formatting of the catalog so that will be a bit noisy :)

    opened by hvisser 0
  • Add documentation to properly run the app locally

    Add documentation to properly run the app locally

    The app requires a google-services.json to run; we need to document it and explain how users can generate it, and also how they can make do with the dummy one in build-config/ if they only need to run tests or static analysis.

    documentation 
    opened by hamen 0
  • Add Crashlytics

    Add Crashlytics

    • [x] Add basic dependency
    • [x] Disable it by default
    • [x] Provide the user with a way to enable it during the onboarding
    • [ ] Provide the user with a way to disable/enable it in the Settings screen
    In Progress 
    opened by hamen 0
  • Add Settings screen PoC

    Add Settings screen PoC

    Let's create a Settings screen to setup the navigation infrastructure in the app.

    • [ ] Create a Settings screen
    • [ ] Setup Navigation Components for Compose
    • [ ] Add a button on Main screen to navigate to Settings
    opened by hamen 0
Owner
Sebastiano Poggi
🇮🇹 Android GDE since 2014, currently bashing on his keyboard really hard at @JetBrains. Claim to fame: you are reading this? I guess. Whatever.
Sebastiano Poggi
This app aims at helping people keep track of their job applications, and remind them regularly about the same.

Applications Tracker Lately I have been applying for many roles, and it has become a hard task to keep track of all the applications. Spreadsheets are

Kartik Pant 4 Feb 20, 2022
Open Super dApp - Your gateway to the new digital commons. Integrated mobile messenger, Ethereum wallet, and Web 3.0 browser built on open, decentralized, and encrypted protocols.

A fully open source, open standard, decentralized "super app" including a secure, encrypted Matrix compatible messenger based off of the Element Messenger, and an Ethereum crypto wallet and web3 browser based off of Alpha Wallet.

2Gather 6 Jul 25, 2022
EU Digital COVID Certificate Wallet App - Android

This repository contains the source code of the EU Digital COVID Certificate Wallet App for Android.

null 57 Oct 6, 2022
An unofficial companion app for DJI's Digital FPV System.

fpv-dvca An unofficial companion app for DJI's Digital FPV System for Android devices. Plug your Android device into your Googles and watch a live fee

Matthias Urhahn 73 Dec 12, 2022
Firefox Focus: The privacy browser - Browse like no one’s watching.

Firefox Focus for Android Browse like no one’s watching. The new Firefox Focus automatically blocks a wide range of online trackers — from the moment

Mozilla Mobile 2.1k Dec 28, 2022
Social media app but with new features like translate messages and posts , support video & images as posts , chat and notifications , etc...

social-media-app Social media app but with new features like translate messages and posts , support video & images as posts , chat and notifications ,

Kareem Aboelatta 15 Dec 13, 2022
Demo app demonstrating how to create and manage notifications locally using a combination of Jetpacks Worker Manager and Broadcast Receiver.

Worker Notification Demo app demonstrating how to create and manage notifications locally using a combination of Jetpacks Worker Manager and Broadcast

Ayia 1 Sep 19, 2022
Money Manager app that helps you to add your daily small incomes and expenses and track them easily.

Simple Money Manager This app is a simple money manager app which helps you to add your daily small incomes and expenses and track them easily. Screen

Yash Bansal 2 Nov 21, 2021
The only wallpaper app you need. No ads, Completely free ! I promise

WallUp An awesome app to download wallpapers for your phone. No ads ! I promise. Explore the docs » Report Bug · Request Feature Table of Contents Abo

Divyansh Dwivedi 6 Dec 3, 2022
Dose a Android app that reminds you medications exactly when your body needs them, building entirely using Kotlin and Jetpack Compose with MVVM + Clean Architecture

??⏰ Dose is a work-in-progress Android app that reminds you medications exactly when your body needs them, building entirely using Kotlin and Jetpack Compose with MVVM + Clean Architecture

Waseef Akhtar 195 Jan 1, 2023
To Do List App is built in Kotlin using Material 3, Data Binding, Navigation Component Graphs, Room persistence library, Kotlin coroutines, LiveData, Dagger Hilt, and Notifications following MVVM Architecture.

ToDoListApp ToDoList App demonstrates modern Android development with Hilt, Coroutines, LiveData, Jetpack (Room, ViewModel), and Material 3 Design bas

Naman Garg 10 Jan 8, 2023
You can store all your password, bank details, card details in one place and remember only one master PIN. The application works totally offline.

Keep Password An application where you can store all your password, bank details, card details in one place and remember only one master PIN. The appl

rıdvan 4 Apr 18, 2022
A Jetpack Compose-based app to exhibit all the beautiful GLSL Fragment shaders I have ever written, where you can set them as Live Wallpaper.

?? Shader Showcase Shader Showcase is a minimal Android app made with Jetpack Compose, to showcase all the beautiful OpenGL* based Fragment shaders I

Piyush Pradeepkumar 198 Dec 28, 2022
Saikou - An anilist only client, which lets you stream & download Anime & Manga

Saikou Saikou is crafted based on simplistic yet out-of-state elegancy. It is an

null 2.9k Jan 3, 2023
Be notified of new AndroidX (Jetpack) library versions and their changelog by GitHub notifications

Image credits: Android Developers This repository publishes release notes of And

Mahdi Hosseinzadeh 4 Oct 5, 2022
TMDbHub - Listing movies using the TMDb API. You can filter results, view details, and save them to a collection

TMDb Hub Listing movies using the TMDb API. You can filter results, view details

David Varga 4 Dec 30, 2021
Push Notifications Android

Push Notifications Android This repository shows how to use Huawei or Google services for Push-notification in different flavors. Preparations You nee

MobileUp 3 Oct 3, 2022
A simple sample showing the different types of notifications on Andoid

Notification example Simple notification. Expandable notification Progress notification Action button notification Notifications: MainActivity: Refs h

Saul Molinero 191 Nov 29, 2022