Securing Your Flutter App: Implementing a Privacy Screen

Ribesh Basnet
wesionaryTEAM
Published in
5 min readJul 24, 2023

--

Introduction

In today’s technology-driven world, privacy is a paramount concern for app developers. Whether it’s sensitive personal information, secure transaction details, or confidential corporate data, apps often handle data that should be protected from prying eyes.

One often overlooked privacy aspect is the snapshot of your app shown in the task switcher or taken when a screenshot is triggered. Unintentional exposure of sensitive data in these snapshots can lead to dire consequences.

As Flutter developers, we have the power to minimize these risks by implementing a simple yet effective feature — the “Privacy Screen.”

What is a Privacy Screen?

A privacy screen, also known as a security screen or app shield, is essentially a protective layer that covers your app’s visible interface when it’s in the background or when the task switcher is invoked. The shield prevents unauthorized users from viewing sensitive information, either deliberately or accidentally, thereby adding an additional layer of security.

Why is a Privacy Screen Important?

Though operating systems like Android and iOS provide inherent mechanisms to manage app lifecycles, it’s the developer’s responsibility to manage the app’s data and states. This becomes crucial when dealing with sensitive data.

A banking app, for instance, might show account details, transaction history, or other sensitive data. if a user switches to another app without logging out, this data could be seen in the app switcher. Implementing a privacy screen mitigates such risks by concealing this data when the app is not actively in use.

When to Use a Privacy Screen?

You should consider implementing a privacy screen for apps that:

  1. Handle sensitive user data such as financial information, personal health data, or proprietary business data.
  2. Are likely to be used in shared or public environments, where over-the-shoulder snooping could be a risk.

Implementing a Privacy Screen in Flutter

In flutter, the implementation of a privacy screen involves platform-specific code, as the process varies between Android and iOS.

For android:

Android provides a built-in mechanism to secure the screen content by using the WindowManager.LayoutParams.FLAG_SECURE . This flag treats the content of the window as secure, preventing it from appearing in screenshot or from being viewed on non-secure displays.

In the context of our flutter app, we can harness this feature by writing some Kotlin code to enable or disable it when needed.

Let’s dive into code:

The class MainActivity inherits from FlutterActivity , and we’re overriding the configureFlutterEngine function to set up a method channel. This method channel allows communication between Flutter and Android. We’re listening to two methods from flutter, “enableAppSecurity” and “disableAppSecurity”, to toggle the secure flag.

The toggleAppSecurity function checks whether the app has window focus or not. if it has focus, we’re disabling the security flag, otherwise we’re enabling it. We also call enableAppSecurity in the onPause function and disableAppSecurity in the onResume function. This ensures that the app content is secure when the app is not on the foregroung and visible again when the app comes to the foreground.

By implementing this, the screen content of our app will be secured when it’s not in the foreground, enhancing the privacy of our app and protecting sensitive data.

For iOS:

Like Android, iOS also allows us to protect the privacy of our app screen by using blur effect. However, the approach is slightly different due to the difference in iOS and Android platforms.

Let’s break down the iOS implementation:

We are using UIApplicationMain to denote the entry point of our iOS app. This is similar to the main() function in a C or C++ program. The AppDelegate class inherits from FlutterAppDelegate which gives us access to the app lifecycle callbacks and the main UIWindow .

In the application(_:didFinishLaunchingWithOptions:) method, we initialize the FlutterMethodChannel to communicate with Flutter. We use the setMethodCallHanlder(_:) to handle flutter method calls.

When the application enters the background, we set the isInBackground flag and enable the security feature. This is done in the applicationDidEnterBackground(_:) method.

On the other hand, when the application becomes active, we check if it was in the background before becoming active. If so, we disable the app security and reset the isInBackground flag.

The enableAppSecurity() function creates a blur effect and applies it to a UIVisualEffectView, which is then added to the window. This effectively obscures the app's UI when viewed from the app switcher or a screenshot.

The disableAppSecurity() function simply removes the UIVisualEffectView from the window, revealing the app's UI.

By adopting this approach, we ensure that our app’s UI is protected when it is not in use, enhancing the privacy of the user’s data and adhering to best practices for app security.

Flutter Integration

For apps developed using the cross-platform framework Flutter, MethodChannels can be used to interact with native Android and iOS features.

Let’s see how to use Flutter to interact with the screen privacy functions we defined in our native code:

We start by defining an abstract class IAppScreenPrivacy with two methods, enableScreenPrivacy() and disableScreenPrivacy(). The AppScreenPrivacyService class, which extends IAppScreenPrivacy, implements these methods.

Each method makes an attempt to invoke its respective function in the native code. The invokeMethod function of the MethodChannel class is used for this, with the method name we wish to invoke being passed as an argument. It is crucial that these names match the ones defined in our native code, hence we use 'enableAppSecurity' and 'disableAppSecurity'.

If the function call is successful, the screen privacy setting will be applied. However, if there’s an issue, the invokeMethod call will throw a PlatformException. This exception is caught and logged for debugging purposes.

By making use of this setup, we can control our native app security features directly from our Flutter code. This enables us to leverage the control and power of native development while still benefiting from the productivity and ease-of-use that Flutter provides.

Through integrating these security practices into our application, we can better protect sensitive user information from being inadvertently exposed via the app switcher or screenshots, ensuring enhanced privacy for our users.

Conclusion

By adding a privacy screen to your Flutter application, you’re taking an important step to enhance your app’s privacy and security. While this technique doesn’t secure your app against all types of threats, it plays a crucial role in protecting your users from casual snooping. Remember, handling sensitive data with care and adhering to the best security practices is not an option but a necessity in modern app development.

Please note: This article is a general guide, and depending on your app’s specific needs, you may need to use more sophisticated methods to protect sensitive data. Always remember to follow the necessary laws and regulations related to data privacy in your region.

--

--