The official CovPass(-Check) Android apps and SDK.

Related tags

Demo covpass-android
Overview

android-covpass-app

This repo contains the CovPass app and commonly needed modules for Kotlin + Android.

The most important modules are:

  • android-utils: Useful lifecycle-aware helpers for view bindings, ViewPager2, etc.
  • annotations: Useful annotations and marker interfaces, e.g. for preventing R8/ProGuard obfuscation.
  • gradle: Common infrastructure for linters, code coverage, R8/ProGuard.
  • covpass-http: Ktor and OkHttp base clients with correct security configuration.
  • covpass-logging: Simple wrapper (Lumber) around Timber which allows for full R8/ProGuard obfuscation.
  • navigation: A simple, yet flexible activity and fragment based navigation system that uses @Parcelize to safely define arguments easily. This solution is most useful when building SDKs and modularizing your code.
  • covpass-bom: Our BOM - a common set of dependency versions, so there won't be any conflicts.
  • covpass-sdk: The main CovPass SDK for Android.
  • covpass-sdk-demo: Use this to override the SDK settings for the demo environment.

The apps live in these modules:

  • common-app: Code shared between CovPass and CovPass Check.
  • common-app-covpass: The CovPass app's code.
    • app-covpass-demo: The demo variant of the CovPass app.
    • app-covpass-prod: The production variant of the CovPass app.
  • common-app-covpass-check: The CovPass Check app's code.
    • app-covpass-check-demo: The demo variant of the CovPass Check app.
    • app-covpass-check-prod: The production variant of the CovPass Check app.

Note: We explicitly avoid using flavors because they are problematic in many ways. They cause unnecessary Gradle scripts complexity for even non-trivial customizations, they interact badly with module substitution, the variant switcher doesn't work properly in all situations, switching flavors takes time (whereas apps in modules can be switched and launched directly), etc. Our experience at IBM has been much smoother since we threw away all flavors and switched to using modules.

App architecture

The architecture in this project is based on our experience with significantly larger projects at IBM. At a certain project size, you start to see which patterns break down and turn into bug sources and time wasters. So, expect to see some patterns that might look unusual at first sight.

Our project uses a library based architecture. In other words, the internal structure follows the same principle as when utilizing third-party dependencies. We explicitly don't break with the library abstraction within the app by introducing framework hollywood principles.

We avoid unnecessary indirections and abstraction layers as long as a simple combination of the IDE's refactoring operations can trivially introduce those layers later.

We use lifecycle-aware, reactive, demand-driven programming. See UI, reactivity, error handling, events for more details and sample code.

Important architectural concerns and pitfalls that have to be taken care of in the whole codebase are abstracted away instead of plastering the code with error-prone copy-paste logic. This includes error handling, correct lifecycle handling, and avoiding memory leaks - i.e. even trivial things like setting view bindings to null in onDestroyView. Everything is automated as much as possible behind simple APIs, so mistakes become less likely and complexity is kept low outside of these helpful abstractions/APIs. As long as you follow these APIs you're on the safe side, avoiding Android's pitfalls.

Dependency injection

We are explicitly not using Dagger or Koin or any other framework for DI.

  • Dagger is much too complicated and messy and the documentation is almost non-existent.
  • Koin follows the (dynamic) service locator pattern which has been criticized for a very long time.
    • It's only checked at runtime, so it can lead to runtime crashes if dependencies are missing.
    • It's very difficult to navigate the graph because you can't use "go to definition" or "find usages".
    • In practice, in much larger projects at IBM, Koin had to be removed from the whole codebase because of this.
  • Hilt is better than the other two, but still too complicated and limited for our projects.

All of these tools have a non-trivial learning curve in comparison to what they're doing.

What is a DI framework doing, anyway?

  • It's (internally) defining a global variable that holds the dependencies. => That's just a global variable.
  • It provides lazy singletons. => That's just by lazy.
  • It provides factories. => That's just a function.
  • It provides scoped dependencies. => That's just a factory function taking e.g. a Fragment.

In other words, Kotlin already provides everything you need for handling DI. So, we use pure, code-based DI.

  • It's checked at compile-time and even the IDE immediately marks errors for you, so you don't have to wait for the compiler.
  • It works without code generation, so builds are faster and you're never in an inconsistent state (e.g. classes getting marked as red because they can't be found).
  • The error messages are clear and understandable.
  • You can explore the DI graph trivially with your normal IDE (find usages, go to definition, unused deps appear as gray text, etc.).
  • This solution works the same for libraries and internally within the app (we follow the library architecture, see above).
  • The learning curve is minimal and in our experience, every junior developer just "gets it" without much thought.

In our much larger projects at IBM this solution has proven to work significantly better than Koin or Dagger.

UI, reactivity, error handling, events

In order to automatically deal with Android's architecture details and pitfalls we utilize ReactiveState/BaseReactiveState subclasses which can be used for (multiplatform) ViewModels or stateful UseCases. Internally, the instances live on an Android ViewModel (having the desired lifecycle), but they can be composed and tested more easily and in theory they allow reuse in multiplatform projects (though that's just a minor aspect in this app).

A ReactiveState comes with an eventNotifier to communicate events out-of-band (e.g. outside of the Fragment's lifecycle). Also, ReactiveState provides a launch method to launch coroutines with automatic error handling. Any errors are automatically forwarded to the UI via eventNotifier and trigger the Fragment's onError(error: Throwable) method. Typically you'd use MutableStateFlow (or the mutation-optimized MutableValueFlow) in order to provide observable values.

A ViewModel / ReactiveState implementation can be attached to a Fragment using by reactiveState which is lifecycle-aware.

Simple example:

// BaseEvents defines our always-available events. Currently this only contains
// onError(error: Throwable).
// We use interfaces instead of sealed classes to represent events because that is more
// composable (almost like union types) and results in less boilerplate.
interface MyEvents : BaseEvents {
    fun onSomethingHappened(result: String)
}

// Usually the scope is passed from outside (in our case this will be the viewModelScope).
class MyViewModel(scope: CoroutineScope) : BaseReactiveState<MyEvents>(scope) {
    val data = MutableStateFlow<List<Entity>>(emptyList())

    fun refreshData() {
        // This launches a coroutine, catches any exceptions and forwards them via
        // eventNotifier { onError(error) }
        // and activates the `loading` state (unless you pass withLoading = null).
        launch {
            // If an exception is thrown here it'll automatically get caught and trigger
            // MyFragment.onError(exception)
            data.value = requestLatestData()
        }
    }

    // You can also compose states. The otherState.eventNotifier and otherState.loading
    // will get merged into MyViewModel.
    val otherState by childReactiveState { OtherReactiveState(scope) }

    // A contrived event example to get the point across
    fun doSomething() {
        launch {
            val result: String = someBackendCommunication()

            // Tell UI the result of doSomething (let's pretend this must be a one-time
            // executed event e.g. showing a dialog)
            eventNotifier { onSomethingHappened(result) }
        }
    }
}

// The fragment has to implement the events interface.
class MyFragment : BaseFragment(), MyEvents {
    // "by reactiveState" internally creates an Android ViewModel to hold the MyViewModel instance.
    // MyViewModel's eventNotifier and loading are automatically processed in a
    // lifecycle-aware way during the >= STARTED state.
    // The events are triggered as method calls on this fragment - e.g. onError(throwable).
    // Whenever `loading` changes, this triggers setLoading(isLoading: Boolean).
    val viewModel by reactiveState { MyViewModel(scope) }  // here, scope is an alias for viewModelScope

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // Here we observe the data and update the UI whenever it changes by using autoRun.
        // The autoRun block will re-execute whenever viewModel.data is changed.
        // The get() call tells autoRun to get the viewModel.data.value and marks viewModel.data
        // as a dependency of the autoRun block.
        // This principle also works with multiple get() calls and can even be
        // used together with if/when-branches to track some dependencies only under certain
        // conditions (we even utilize this in our app - avoiding complicated Flow constructs).
        // Moreover, autoRun is lifecycle-aware and only executes in the >= STARTED state.
        autoRun {
            updateUI(get(viewModel.data))
        }
    }

    private fun updateUI(data: List<Entity>) {
        // ...
    }

    override fun onSomethingHappened(result: String) {
        // handle result event
    }
}

Note, the equivalent of

autoRun {
    updateUI(get(viewModel.data))
}

is more or less this block of code:

lifecycleScope.launchWhenStarted {
    viewModel.data.collect {
        try {
            updateUI(it)
        } catch (e: CancellationException) {
            throw e
        } catch (e: Throwable) {
            onError(e)
        }
    }
}

This was just the trivial case with a single StateFlow. Imagine how complex things can become in the multi-StateFlow case combined with if/when and demand-driven resource allocation. We want to avoid this repetitive complexity/boilerplate and prevent common mistakes like forgetting to give CancellationException a special treat.

View Bindings

Use the by viewBinding helper which takes care of the whole lifecycle handling for you:

class DetailFragment : BaseFragment() {
    private val binding by viewBinding(DetailBinding::inflate)
}

With a single line of code, the binding is automatically inflated in onCreateView and cleared in onDestroyView, so you can avoid the whole boilerplate.

Custom FragmentStateAdapter

Use BaseFragmentStateAdapter which automatically avoids memory leaks. If that doesn't work for you, at least use Fragment.attachViewPager.

Custom Toolbars

Use Fragment.attachToolbar to have automatically correct lifecycle handling and to avoid memory leaks.

Screen navigation

Some of the modules in this repo were taken from our internal IBM projects. The code-based navigation system is one of them. Among the IBM developers who have worked with Android's Navigation component the experience was more on the negative side. Especially when creating SDKs and modularizing your code, the Navigation component can have its pitfalls, runtime crashes and it can get in your way. So, instead of using the Navigation components, we created a very simple code-based navigation system.

In this project we don't utilize the full flexibility of the navigation system. When we started out we simply wanted to build on the same infrastructure that we were already most familiar with and not risk regretting the decision to use the Navigation components. Moreover, this project is supposed to become a set of SDKs - one of them providing flexible, partial integration of the UI and navigation subgraphs.

This is how you define a navigation point and access the arguments:

@Parcelize
class DetailFragmentNav(val certId: String) : FragmentNav(DetailFragment::class)

class DetailFragment : BaseFragment() {
    private val args: DetailFragmentNav by lazy { getArgs() }

    // ...

    // Within Fragments you can optionally customize the back button behavior
    override fun onBackPressed(): Abortable {
        if (something) {
            customBackPressLogic()
            return Abort  // aborts the default behavior
        }
        return Continue  // continue with default back behavior
    }
}

This is how you navigate:

findNavigator().push(DetailFragmentNav(args.certId))
findNavigator().pop()
findNavigator().popAll()
findNavigator().popUntil(SomeFragment::class)

// For passing results you define an interface and popUntil a fragment that
// implements the interface
interface DetailFragmentListener { fun onDetailResult(value: String) }
findNavigator().popUntil<DetailFragmentListener>()?.onDetailResult(someValue)

// triggers onBackPressed()
triggerBackPress()

So, the API is similar to the Navigation component, but everything is code-based (no XML) and thus easier to reason about and you get more control.

License

Copyright (C) 2021 IBM Deutschland GmbH

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
  • IMPORTANT (CovPassCheck): Add a 'Booster'-Info to the

    IMPORTANT (CovPassCheck): Add a 'Booster'-Info to the "Certificate valid"-Screen...

    Avoid duplicates

    Current Implementation

    If vaccination certificates are scanned with CovPassCheck (v1.13.3), the current situation is as follows: A scan of a vaccination certificate (e.g. BionTech 2 of 3) delivers "Certificate valid". A scan of a vaccination certificate (e.g. BionTech 3 of 3) from the same person also provides "certificate valid". That is correct so far.

    Suggested Enhancement

    Against the background of the new regulation, which has already been partially introduced, that 'boosted' people no longer need an additional corona test, this 'boosted' information must be displayed as additional information in CovPassCheck (and CWA).

    According to current information, the above-mentioned regulation - i.e. no additional tests for 'boosted' / people with a booster vaccination - should be decided in the coming week for all of Germany.

    Expected Benefits

    This is the only way to determine at a glance whether an additional corona test is actually necessary or not during an access control, for example.

    E.g.:

    Screenshot_20211212-132710_21

    "Booster #1" is an idea to count boosters when more than one booster (i.e. a second, third, ...) booster is needed.

    Additional context

    When making the solution, it must certainly be taken into account that further booster vaccinations will be necessary for the future and of course all vaccine combinations must be taken into account when determining the 'booster'.

    enhancement 
    opened by Jo-Achim 105
  • Distribute the app via F-Droid too

    Distribute the app via F-Droid too

    This is kind of a followup to Digitaler-Impfnachweis/documentation#8. I started to track the integration of this app into the F-Droid repository over at their issue tracker.

    For now I would like to know if this is generally supported by RKI and/or IBM? And if yes, could you provide a short summary of the app (max 80 chars) and a longer description which should/could appear on the F-Droid site?

    opened by jugendhacker 31
  • CovPass shows the date of a booster vaccination as

    CovPass shows the date of a booster vaccination as "Vollständig seit dd.mm.yyyy" and not the date of the last required vaccination

    This bug report applies to iOS and Android.

    Avoid duplicates

    • [X] Bug is not mentioned in the FAQ
    • [X] Bug is not already reported in another issue

    Technical details

    • Device name: not relevant
    • OS version: not relevant
    • App version: 1.11

    Describe the bug

    On the main screen CovPass shows since when the vaccination protection is complete. This should always be the date of the las required shot and not the date of a booster vaccination, as it is not required. However, CovPass actually does exactly this, it show the date of a booster vaccination as the date of since when the vaccination protection is complete.

    Here are some screenshots:

    | Main screen | Stored certificates | |---|---| | d0v3SWaH jpg-mediumyeqKoixj jpg-medium |

    Steps to reproduce the issue

    1. Add a certificate of a booster vaccination to the app
    2. See that the date on the start screen "Vollständig geimpft seit dd.mm.yyyy" shows that the vaccination protection is complete since your booster shot.

    Expected behaviour

    The "Vollständig geimpft seit http://dd.mm.yyyy" should always be the date of the las required shot and not the date of a booster vaccination, as it is not required.... Last reqd date +14d (+28d on J&J).

    bug 
    opened by Ein-Tim 25
  • QR-SCAN fail for specific smartphones and or settings [persistent]

    QR-SCAN fail for specific smartphones and or settings [persistent]

    we have several android-smartphones with failure on QR-code scanning. "Impfzertifikat enthält keine gültige Signatur"

    our test permutations:

    • Devices: Huawei P30lite, Samsung Galaxy S6, Samsung J5
    • Android versions: 10, 7, 6
    • PIN-lockscreen: on/off
    • Developer Options: on/off
    • Developer Options: Stay Awake: on/off
    • Developer Options: Screen Lock - Require to be unlocked: on/off
    • internet: blocked (LAN/router NTP always active)
    • playstore: blocked/enabled
    • region/language: english/german
    • REAL QR code ("Impfzertifikat" sheet)
    • SAMPLE QR code ("Erika Musterfrau") => FAIL always

    results are persistent, INDEPENDENT from conditions above:

    • CovPass v0.160.7 => FAIL => [update] PASS after reinstall + internet access enabled (why?)
    • CovPassCheck v0.160.7 => FAIL => [update] PASS after reinstall + internet access enabled (why?)
    • CoronaWarnApp v2.3.4 => PASS (any case)
    • CoronaWarnApp v2.4.2 => PASS (any case)

    developers, please check & publish REASON/CONDITION/failuremode asap! (WA if possible) please confirm if specific "keychain attributes" (see also iOS bug) are relevant (e.g. specific android settings) asap!

    QR-codes can by copied by concept. it is a severe development-flaw, to add specific background-checks (e.g. for pin-screenlock) that are NOT known and NOT clearly shown in case of failure mode.

    regards, llouc

    [update] https://github.com/Digitaler-Impfnachweis/covpass-android/issues/18#issuecomment-870424413

    opened by llouc 20
  • Error 902: at

    Error 902: at "Update entry rules" ("Einreiseregeln aktualisieren") ...

    Avoid duplicates

    • [X] Bug is not mentioned in the FAQ
    • [X] Bug is not already reported in another issue

    Technical details

    • Device name: Samsung Galaxy Note 10, SM-N970F/DS
    • OS version: Android 12 (One UI 4.0)
    • App version: 1.21.0

    Describe the bug

    After tapping "Update" under "Update Entry Rules", the entry rules appear to be updated. At least that's what the data under "Last Update" suggests. The data displayed there correspond exactly to the current date and time.

    However, immediately followed by the message:

    Sorry An unexpected error has occurred. Please try again later. (Error 902)

    However, trying "try again later" gives the same result. Updating the data under "Last update" followed by the error message "Error 902".

    Steps to reproduce the issue

    1. Open the app
    2. Goto 'Information'
    3. Tab on 'Update Entry Rules'
    4. Tab on 'Update'

    Expected behaviour

    Is the error message correct? If so, it probably shouldn't appear.

    Additional context

    The error message has been appearing for over an hour. Restarting the app does not solve the problem.

    bug 
    opened by Jo-Achim 19
  • App Crash by opening camera for import Cert

    App Crash by opening camera for import Cert

    Covpass V 1.12.0 Source Playstore Device: Samsung Galaxy Z Fold3 5G - SM-F926B/DS Android 11, Patchlevel October 2021

    After press "Scan QR Code" the App crashes on both screens. Same issue in CovPass Check App. It happens everytime, i cant import vacation certificates

    Its a new Device, can't say if this happend on other softwareversions.

    opened by CrazyOlli 18
  • Generated QRCodes don't work.

    Generated QRCodes don't work.

    Avoid duplicates

    • [x] Bug is not mentioned in the FAQ
    • [x] Bug is not already reported in another issue

    Technical details

    • Device name: Samsung S7
    • OS version: 8.0
    • App version: 1.11.1

    Describe the bug

    We're generating new QR codes from the raw data to print them on plastic cards. Our codes worked in previous versions of covpass/covpasscheck and also coronawarnapp. With one of the last updates our codes don't work and we can't figure out why. They are still working in coronawarnapp! And i can scan it in any other QR code app and the raw data are fine (exactly the same data is in my original qr code). And i can still scan my original QRcode just fine. Confusing.

    Steps to reproduce the issue

    Try to scan the attached qr code.

    Just to clarify: This is my own QR code, so i can share it.

    Expected behaviour

    It should scan.

    Possible Fix

    Workaround: Can you give me the parameters (version, error correction, ...) to generate QR codes that are working in the app?

    Additional context

    My generated QR-Code:

    (Removed)

    My original QR-Code that is still working in Covpass:

    (Removed)

    bug 
    opened by Netzvamp 18
  • [CovPassCheck] 2G+ & (recent) Boosters: Introduce optional serial scanning of multiple DCCs per user

    [CovPassCheck] 2G+ & (recent) Boosters: Introduce optional serial scanning of multiple DCCs per user

    THIS ENHANCEMENT REQUEST FOR COVPASSCHECK AFFECTS BOTH ANDROID & iOS

    Avoid duplicates

    • [x] This enhancement request has not already been raised before - searched all repos, couldn't find anything.

    Current Implementation

    Currently CovPassCheck scans 1 EU DCC per user/use case. Combining multiple EU DCCs of one user for a single result/check is not implemented yet.

    Suggested Enhancement

    Please implement an optional serial scanning mode to CovPassCheck that makes it possible to scan multiple EU DCCs of one user, combine them and validate them to a single result. This would make it possible to easily check in situations, where 2G+ or Boosters (probably in the future) are required to enter a venue.

    Use Case: 2G+

    Whenever the proof of the status 2G+ ([vaccinated OR recovered] AND tested negative) is required to enter a venue, it will be necessary to scan two independent EU DCCs: vaccination/recovery certificate and test certificate (if available). In the current implementation a gate keeper would first need to scan one v/r-certificate, check whether it's valid, and then scan again the test-certificate (if available as DCC). Gate keeper then needs to combine both results in his mind and decide, whether entry to the venue can be granted for the holder. This sounds a simple task at a glance, not necessarily needing a serial scanning mode. But try to imagine bigger events with many people, hectic, rush and distraction: how often it could happen, that the gate keeper accidently scans twice the same DCC (e.g., twice the same test, or twice the v-DCC)? He just sees 2 times "green" and checks the holder in. A serial scanning mode can support the gate keeper in this case: After the first DCC is scanned, CovPassCheck prompts (displays a message to) the gate keeper, which certificate is next to scan from the holder, then combine both certificates to a single PASS or FAIL and request the gate keeper to now scan the next guest. In case the necessary proofs have different formats (e.g., one is paper, the other EU DCC) the current scan then would need an option (button) to skip the second scan and switch to the next guest.

    Use Case: Recent Booster Vaccination

    Booster vaccination is a complex thing to validate, because it needs to be determined whether the presented EU DCC is a (recent) booster after a completed vaccination series ([a] 2x AstraZeneca, Biontech, Moderna: booster -> 3/3; [b] 1x J&J: booster -> 2/2), or a single vaccination after a recovery ([c] vaccination -> 1/1), or a booster after a vaccination after a recovery ([d] booster -> 2/2). Currently, when holders present their EU DCC, it's critical to determine whether it's a booster or a vaccination, when the booster has been received less than 14 days ago, but according to legislation a booster is already valid and granting access to the venue. With today's CovPassCheck, a single certificate with a 2/2 booster received less than 14 days ago would be rejected. Because in this case different DCCs would need to be taken into account for people of the groups [b] and [d], the CovPassCheck today can't give a valid result for this use case, so it will likely need high awareness of the gate keeper and discussion/questions with holders to decide whether access can be granted. This is error prone and slowing down the check-in. It will become even more difficult for gate keepers with current CovPassCheck, if one day boosters are mandatory to gain access to a venue, because then in many cases (groups [b] and [d] it's a must that multiple proofs need to be checked (at least for recovered and J&J-jabbed people). We are far away from that scenario in these days, but it's not completely unrealistic that this may happen one day... CovPassCheck could support the gate keeper in a serial mode, when after scanning a 2/2 v-DCC that was issued <14 days ago (current days) or when a booster is mandatory (possible future days) the gate keeper is prompted to ask for/scan for a second proof that reflects that the 2/2 v-DCC is actually a booster, and after the scan of the necessary document display a PASS or FAIL.

    Use Case: 2G+ together with Boosters

    Already today, when 2G+ will need to be checked, people will present their booster certificates together with a test result. For the reasons described above, this will become even more complex for gate keepers. A serial mode of CovPassCheck could take care of it, reducing errors and speeding up the check-in.

    Expected Benefits

    As described above: Reducing complexity and errors, speeding up checks/check-in when handling 2G+ and Booster DCCs.

    How to implement

    Basically, the multiple DCCs that have been scanned (and have been validated against their digital signature each) can be then combined internally, and then be checked using CertLogic against special crafted Booster Notification Rules (BNR). Corona-Warn-App is using this mechanism already to detect booster certificates stored in its wallet, see https://github.com/corona-warn-app/cwa-app-android/pull/4001 for details. For 2G+, this can easily be extended with test certificates.

    CovPassCheck's scan logic would need to be extended accordingly to allow for multiple scans per holder, using BNR's would most likely need to be adapted/extended, UI would need to represent options to turn on serial mode and to present results accordingly. It would also be nice when gate keepers can choose to use presets (2G with booster support, 2G+, 3G with booster support...) or the presets could also determine whether a serial mode is to be switched on automatically.

    enhancement 
    opened by vaubaehn 16
  • [BUG]

    [BUG] "Travel rules not up to date" / "Reiseregeln nicht aktuell": Unfortunately the last update failed…

    Avoid duplicates

    • [X] Bug is not mentioned in the FAQ
    • [X] Bug is not already reported in another issue
    • [X] OS: Android. iOS not affected; see: https://github.com/Digitaler-Impfnachweis/covpass-android/issues/98#issuecomment-960642531.

    Technical details

    • Device name: Not relevant. (CovPass v1.12.0: Samsung Galaxy Note 10, SM-N970F/DS /// CovPass v 1.11.1: Nokia 7.2, TA-1196)
    • OS version: Not relevant. (Samsung: Android 11 (One UI 3.1) with Android security update: 01. Oktober 2021 /// Nokia: Android 10 with Android security update: September 1st, 2021)
    • App version: 1.12.0

    Describe the bug

    When calling CovPass v1.12.0 and calling "Check validity >", the following message is displayed in the "Check validity" dialog:

    "Travel rules not up to date" ... Screenshot_20211103-232151_CovPass_2

    It seems to me that the app makes no attempt to update, because the notice is displayed immediately, despite the presence of WiFi.

    In comparison to the previous version 1.11.1, the following is initially displayed if the above procedure is the same: Screenshot_20211104-004356_2

    and then a few seconds later: Screenshot_20211104-004409_2

    Steps to reproduce the issue

    Make sure that the smartphone has an internet connection - in my case only via WLAN! (One smartphone (Samsung) is not allowed to access the internet via mobile phone provider, the second one (Nokia) does not have a SIM card.)

    1. Start CovPass v1.12.0
    2. Tap on "Check Validity >"
    3. The v1.12.0 dialog shown above is displayed - without any time delay.

    Expected behaviour

    Ensuring that every time CovPass v1.12.0 is started, the 'out of date data for the entry rules' are updated via the existing Internet.

    Cross reference: ["CovPass Check": Offline mode & WLAN]: "Internet connection required" although available .... (Please do not be surprised about the version numbers of CovPass / CovPassCheck mentioned in the cross-reference, which are 'normal'; see Repeated version jumps / incomprehensible numbering of the versions in CovPass & CovPassCheck ....)

    Possible Fix

    Implementation of the update mechanism for the travel rules from version 1.11.1 or other corrections in the next version of CovPass.

    Additional context

    Open / not tested: similar behavior in CovPassCheck v 1.12.0.


    PS: If helpful, a supplement for the above Samsung data:

    CovPassCheck v.1.12.0 shows:

    • Offline mode available
    • List of certificate issuers: 11/03/2021 6:09 pm
    • Inspection rules: 11/02/2021 6:15 pm.
    bug 
    opened by Jo-Achim 16
  • The app is totally useless for providing the certificate to the

    The app is totally useless for providing the certificate to the "Digital Registration on Entry"

    The app actively prevents screenshots, so it does not allow the required upload of installed certificates.

    This defeats the whole purpose of the the app: You need another (analog) prove of vaccination for entry.

    opened by rjungbeck 16
  • Linking/deduplicating certificates of the same person does not use the normalized name

    Linking/deduplicating certificates of the same person does not use the normalized name

    Avoid duplicates

    • [x] Bug is not mentioned in the FAQ
    • [x] Bug is not already reported in another issue

    Technical details

    • Device name: Google Pixel 5
    • OS version: Android 12
    • App version: 1.13.2

    Describe the bug

    I just imported my dad's booster certificate in the app, and for the first two shots the name was like "Emil Mueller" (real name changed, since dummy names are fine here). For this booster shot they spelled the umlaut correctly, so it's "Emil Müller" now. However, in both certificates the normalized version of the name is "EMIL MUELLER". The birth dates are obviously the same as well.

    I would expect the three vaccinations to show up for a single person in the app, but I now have two entries, one with the umlaut version and one without.

    Steps to reproduce the issue

    Import multiple certificates for the same person that only differ in diacritics but have the same normalized name,

    Expected behaviour

    Only a single entry for him.

    Possible Fix

    Use the normalized name (+ birth date?) to group certificates together.

    Additional context

    I can provide the real certificate QR codes to a maintainer if necessary, but I think it should be easily reproducible with dummy certificates which you almost certainly have for testing purposes anyway.

    bug 
    opened by ThiefMaster 15
  • Release notes for CovPass 1.38

    Release notes for CovPass 1.38

    Happy New Year!

    Please publish release notes for CovPass / CovPass Check 1.38!

    The last release documented in https://github.com/Digitaler-Impfnachweis/covpass-android/releases is v.1.37.0.

    opened by MikeMcC399 0
  • Message says certificate can be renewed even if expiry more than 90 days ago

    Message says certificate can be renewed even if expiry more than 90 days ago

    Avoid duplicates

    • [X] Bug is not mentioned in the FAQ
    • [X] Bug is not already reported in another issue

    Technical details

    • Device name: Samsung Galaxy A5 (2017)
    • OS version: Android 8.0.0
    • App version: CovPass 1.36.0

    Describe the bug

    If the only certificate stored has expired more than 90 days ago then the information displayed that the certificate can be renewed is incorrect.

    Steps to reproduce the issue

    1. Delete any existing stored certificates

    2. Press "+" and "Add certificate" to scan a vaccination certificate which expired more than 90 days ago.

    3. Scroll down to "Certificate expired" and note the text:
      " ... You can conveniently renew this certificate in the CovPass app. ... To do so, use the renewal function in the overview of your certificates ..." certificate expired

    4. Look for some button to renew the certificate - there is none!

    Expected behaviour

    CovPass should only say that a certificate can be renewed if this is possible.

    Possible Fix

    • Change the text to specify the 90 day limitation for renewal or
    • Change the logic so that the app only says that a certificate can be renewed if this is actually possible
    bug 
    opened by MikeMcC399 2
  • Enable screenshots (Follow up to #62)

    Enable screenshots (Follow up to #62)

    Avoid duplicates

    • [ ] This enhancement request has not already been raised before - This is a follow up to #62

    Current Implementation

    CovPass does not allow to take screenshots. Attempting to take a screenshot results in an error message from the OS.

    Suggested Enhancement

    Allow taking screenshots of CovPass.

    Expected Benefits

    Easier for debugging purposes and more. Also, the screenshot restriction can easily be bypassed, without root or anything, by saying "OK Google, take a screenshot". This screenshot protection does not add any security to the app, as there is literally a certificate export feature in the app. Why would you restrict a user to store a screenshot of the QR code of the certificate, but allow to export the whole certificate? You see, this makes no sense. If you have any points where the screenshot restriction actually adds security, please share them in this issue.

    enhancement 
    opened by Ein-Tim 6
  • "Renew vaccination certificate" button only displayed after app restart

    Avoid duplicates

    • [X] Bug is not mentioned in the FAQ
      ~~The FAQ are not yet adjusted to cover the functionality in CovPass 1.26.0~~
    • [ ] Bug is not already reported in another issue The problem is also mentioned in https://github.com/Digitaler-Impfnachweis/covpass-android/issues/207#issuecomment-1149806209

    Technical details

    • OS version: Android 12
    • First reported in App version: 1.26.0
    • Reproducible also in App version: 1.36.0

    Describe the bug

    • When a 1/2 vaccination certificate with technical expiry date less than 28 days in the future is scanned, the app displays the text "You can easily replace the certificate in the CovPass app by using the renewal function in the overview of your certificates or by scanning a newly issued certificate" however there is no button "Renew vaccination certificate" available to carry out that function unless the app is stopped and restarted. (App version 1.26.0).

    • When a 1/2 vaccination certificate with technical expiry date less than 28 days in the future is scanned, the app displays the text "You can easily renew your latest certificate in the CovPass app. Previous certificates will not be renewed. To do so, use the renewal function in the overview of your certificates or scan a newly issued certificate." however there is no button "Renew vaccination certificate" available to carry out that function unless the app is stopped and restarted. (App version 1.26.1 and later).

    Steps to reproduce the issue

    1. Install CovPass
    2. Go through onboarding
    3. Scan a 1/2 vaccination certificate with technical expiry date less than 28 days in the future
    4. Note the text information:
      "Current certificate expires on ...
      You can easily replace the certificate in the CovPass app by using the renewal function in the overview of your certificates or by scanning a newly issued certificate". (1.26.0) or "You can easily renew your latest certificate in the CovPass app. Previous certificates will not be renewed. To do so, use the renewal function in the overview of your certificates or scan a newly issued certificate." (1.26.1 & later)
    5. Click on back arrow
    6. Click on "Display certificates"
    7. Click on "Manage certificates"
    8. Note that there is no button "Renew vaccination certificate" displayed yet
    9. Exit the app and use Android to Close all apps
    10. Restart the app
    11. Note pop-up:
      "Check the validity of your certificates
      If you can renew this certificate in the app, you will receive a notification. You can find more information about replacing expired certificates in our FAQs."
    12. Tap "OK"
    13. Note for app versions before 1.28.0 the previous pop-up repeats:
      "Check the validity of your certificates
      If you can renew this certificate in the app, you will receive a notification. You can find more information about replacing expired certificates in our FAQs."
    14. Tap "OK"
    15. Tap "Display certificates" > Tap "Manage certificates"
    16. Note that a new tile appears:
      "Renewal needed
      The technical expiry date of your vaccination certificate is coming up. Renew the certificate to continue using it." (1.26.0) or "Renewal needed
      The technical validity of your vaccination certificate is about to expire or has already expired. Renew the certificate to continue using it." (1.26.1 and later) with the button "Renew vaccination certificate"

    Expected behaviour

    The app should only display the text "You can easily replace the certificate in the CovPass app by using the renewal function in the overview of your certificates or by scanning a newly issued certificate" (1.26.0) or "You can easily renew your latest certificate in the CovPass app. Previous certificates will not be renewed. To do so, use the renewal function in the overview of your certificates or scan a newly issued certificate." (1.26.1 and later) if the button "Renew vaccination certificate" is also available.

    bug 
    opened by MikeMcC399 7
  • No option for certificate renewal in Version 1.26

    No option for certificate renewal in Version 1.26

    Avoid duplicates

    • [x] Bug is not mentioned in the FAQ
    • [x] Bug is not already reported in another issue

    Technical details

    • Device name: Samsung S10+
    • OS version: Android 12
    • App version: 1.26.0

    Describe the bug

    Version 1.26 should contain the functionality for certificate renewal. In https://github.com/Digitaler-Impfnachweis/covpass-android/issues/207#issuecomment-1149806209 already was observed that after update to 1.26 there is no "Renew vaccination certificate" button.

    However, killing the app and restarting the phone does not do the trick on my device. So, even after complete restart, CovPass 1.26 has no certificate renewal functionality on my device.

    I have two certificates which expire soon and need to be renewed. My third one is valid for a longer period. Maybe, this is the reason for the bug, i.e. the valid certificate may block the two other ones for renewal?

    bug 
    opened by T-F-S 29
  • Certificate widget

    Certificate widget

    Avoid duplicates

    • [x] This enhancement request has not already been raised before

    Current Implementation

    You have to open the app every time to show your main certificate, which is especially under 2G rules not comfortable.

    Suggested Enhancement

    A widget could be added on the home screen that shows the main certificate of a given person. When a widget is placed, a holdername can be selected.

    Expected Benefits

    The user don't have to open the app every time to show the main certificate.

    I already implemented a prototype on the branch certificateWidget https://github.com/TillJohanndeiter/covpass-android

    enhancement 
    opened by TillJohanndeiter 2
Releases(v-1.629.2)
  • v-1.629.2(Dec 6, 2022)

    Release Notes CovPass(Check) Version 1.37

    Main Features CovPass: 💉

    • If state-specific mask rules apply, the start of validity of these rules is now referenced
    • To avoid missunderstandings and potential mistakes, we don't show the "valid since" date anymore for reaching the vaccination status based on IfSG § 22a
    • #226

    Main Features CovPassCheck: 💉

    • It is now possible to choose whether to check vaccination protection within Germany or when entering Germany. The entry rules to Germany are based on the Corona entry regulation. Checking rules within Germany or for entry to Germany can be changed in the settings
    • If state-specific mask rules apply, the start of validity of these rules is now referenced
    • #236
    • #237

    Thank you all for you support and feedback! Stay safe everyone 👍 🎊

    Team CovPass and CovPassCheck! 🧑‍⚕️ 👩‍⚕️

    Source code(tar.gz)
    Source code(zip)
  • v-1.605.3(Nov 24, 2022)

    Release Notes CovPass(Check) Version 1.36

    Release 1.35 was skipped due to project internal reasons.

    Main Features CovPass: 💉

    • Accessibility: We improved many accessibility features, such as landscape mode and screen reader to make our app more accessible.

    Main Features CovPassCheck: 💉

    • The vaccination status can be checked again with the CovPassCheck app. According to the German Infection Protection Act (IfSG), people are considered fully vaccinated if they are vaccinated at least three times or alternatively are vaccinated two times in addition to being recovered from COVID19 at least once.

    Thank you all for you support and feedback! Stay safe everyone 👍 🎊

    Team CovPass and CovPassCheck! 🧑‍⚕️ 👩‍⚕️

    Source code(tar.gz)
    Source code(zip)
  • v-1.588.1(Nov 24, 2022)

    Release Notes CovPass(Check) Version 1.34

    Release 1.33 and 1.34 were merged due to project internal reasons.

    Main Features CovPass: 💉

    • Mask Status: If the certificates stored in the CovPass app are sufficient to exempt you from extended mask rules in your federal state, the certificate will turn green and you will see a new mask status. Details to those exemptions can be found within the detail view.

    Main Features CovPassCheck: 💉

    • Matching the update of the CovPass App, there is now a secure and simple mask check for verifiers. An additional immunity status check based on the new German Infection Protection Act (IfSG) is being prepared for Release 1.35.

    Thank you all for you support and feedback! Stay safe everyone 👍 🎊

    Team CovPass and CovPassCheck! 🧑‍⚕️ 👩‍⚕️

    Source code(tar.gz)
    Source code(zip)
  • v-1.552.3(Nov 24, 2022)

    Release Notes CovPass(Check) Version 1.32

    Release 1.32 is released

    Main Features CovPass: 💉

    • Immunization Status: From October 1, 2022, according to Section 22a of the Infection Protection Act, a person is considered fully vaccinated if the person has received at least three doses of vaccine or can provide evidence of two vaccinations and recovery. A corresponding visual adjustment informing users about the new values of their certificates has been implemented.

    • Mask Status: (Already prepared and soon available in the app) If the certificates stored in the CovPass app are sufficient to exempt you from extended mask rules in your federal state, the certificate will turn green and you will see a new mask status. Details to those exemptions can be found within the detail view.

    • Data Privacy on the start screen: In the interest of data privacy, information on the certificate type and the associated date (vaccination date, date of the underlying test, date of test collection) was removed from the startscreen. Once your state places an expanded mask rule, the mask status will be visible to you on the start screen.


    Main Features CovPassCheck: 💉

    • With the upcoming releases the CovPassCheck will provide a secure and simple mask check for verifiers. A additional immunity status check is in discussion. Expect the first changes in version 1.33.

    Thank you all for you support and feedback! Stay safe everyone 👍 🎊

    Team CovPass and CovPassCheck! 🧑‍⚕️ 👩‍⚕️

    Source code(tar.gz)
    Source code(zip)
Check out the new style for App Design aims for the Online Plant Shop Service...😉😀😁😎

PlantShopUI-Android Check out the new style for App Design aims for Online Plant Shop Service... ?? ?? ?? ?? Screenshots Please click the image below

Shashank Singhal 162 Dec 8, 2022
Check out the new style for App Design aims for the Vegetable Order Service using jetpack compose...😉😀😁😎

VegetableOrderUI-Android Check out the new style for App Design aims for the Vegetable Order Service using jetpack compose... ?? ?? ?? ?? Screenshots

Shashank Singhal 330 Dec 19, 2022
Non-official Library Genesis (Libgen) Android mobile client.

Aurora If my noble work has helped you, consider becoming a . This is a non-official Library Genesis mobile client. The project is completely independ

null 318 Dec 23, 2022
This repo demonstrates how to work on CI/CD for Mobile Apps 📱 using Github Actions 💊 + Firebase Distribution 🎉

Android-CICD This repo demonstrates how to work on CI/CD for Mobile Apps ?? using Github Actions ?? + Firebase Distribution ?? Getting Started We are

Mohamed Elsharkawy 50 Nov 29, 2022
Viacheslav Veselov 0 Jul 8, 2022
Android sample app following best practices: Kotlin, Compose, Coroutines and Flow, Hilt, JetPack Navigation, ViewModel, MVVM and MVI, Retrofit, Coil

Foodies - Modern Android Architecture Foodies is a sample project that presents a modern 2021 approach to Android app development. The project tries t

null 362 Jan 2, 2023
🧸 A demo Disney app using Jetpack Compose and Hilt based on modern Android tech stacks and MVVM architecture.

DisneyCompose A demo Disney app using compose and Hilt based on modern Android tech-stacks and MVVM architecture. Fetching data from the network and i

Jaewoong Eum 791 Dec 30, 2022
A sample Android application with a strong focus on a clean architecture, automated unit and UI testing and continuous integration.

Android playground This is a sample Android application with a strong focus on a clean architecture, automated unit and UI testing and continuous inte

null 6 Jun 4, 2022
OpenPacketSniffer - Monitors and handles network packets sent and received to/from a host

Packet Sniffer Monitors network activity and logs all packets that have been sent/received by the client's host. Settings In Main.kt, the PcapHandler

Neel 0 Jan 5, 2022
A simple app to showcase Androids Material Design and some of the cool new cool stuff in Android Lollipop. RecyclerView, CardView, ActionBarDrawerToggle, DrawerLayout, Animations, Android Compat Design, Toolbar

#Android-LollipopShowcase This is a simple showcase to show off Android's all new Material Design and some other cool new stuff which is (new) in Andr

Mike Penz 1.8k Nov 10, 2022
A simple app to showcase Androids Material Design and some of the cool new cool stuff in Android Lollipop. RecyclerView, CardView, ActionBarDrawerToggle, DrawerLayout, Animations, Android Compat Design, Toolbar

#Android-LollipopShowcase This is a simple showcase to show off Android's all new Material Design and some other cool new stuff which is (new) in Andr

Mike Penz 1.8k Nov 10, 2022
simple android grocery app using kotlin and android studio

Project Idea The idea of this project is to make a grocery android app that users can use to order the groceries they want. It doesn't contain any bac

null 0 Nov 29, 2021
Beetlebug is an open source insecure Android application with CTF challenges built for Android Penetration Testers and Bug Bounty hunters.

Beetlebug Beetlebug is a beginner-friendly Capture the Flag Android application that aims to inspire interest in Mobile Application Security. It is ge

Hafiz Abdulaziz 60 Oct 11, 2022
Do's and Don'ts for Android development, by Futurice developers

Best practices in Android development Avoid reinventing the wheel by following these guidelines. Lessons learned from Android developers in Futurice.

Futurice 20.2k Dec 31, 2022
A simple chat demo for socket.io and Android

socket.io-android-chat This is a simple chat demo for socket.io and Android. You can connect to https://socket-io-chat.now.sh using this app. Installa

Naoyuki Kanezawa 1.9k Dec 30, 2022
Android common lib demo, include ImageCache, HttpCache, DropDownListView, DownloadManager, install apk silent and so on, you can find description

android-demo 关于我,欢迎关注 微博:Trinea 主页:trinea.cn 邮箱:trinea.cn#gmail.com 微信:codek2 依赖:trinea-android-common android-auto-scroll-view-pager viewpager-indica

Trinea 1.1k Nov 10, 2022
📚 Sample Android Components Architecture on a modular word focused on the scalability, testability and maintainability written in Kotlin, following best practices using Jetpack.

Android Components Architecture in a Modular Word Android Components Architecture in a Modular Word is a sample project that presents modern, 2020 app

Madalin Valceleanu 2.3k Dec 30, 2022
Sample application demonstrating Android design and animation

android-movies-demo This is a sample application showing off some interesting design/development interactions for a talk given at Droidcon 2013. As it

Daniel Lew 359 Jan 1, 2023
This repo contains example code for O'Reilly's "Programming Android" by Zigured Mednieks, Laird Dornin, Blake Meike and Masumi Nakamura

This repo contains working code for the example in O'Reilly's _Programming Android, 2nd Edition_; Mednieks, Dornin, Meike, Nakamura (http://shop.orei

G. Blake Meike 214 Nov 25, 2022