Screenshot preventing on mobile apps

Photo by Branden Tate

Recently, at nomtek, we were asked if we could create an app which would be able to block screenshots. Basically there will be some images which should be “protected” — ideally, they should not be visible but it would be enough if we made them blurred or obfuscated in another way.

It was quite an interesting topic, so we’ve started investigating…


Android

Luckily, the Android system provides a built-in mechanism for blocking screenshots which is available from Android Honeycomb (3.0). It literally takes one line of code to put in Activity which you’d like to prevent to be screenshotted, and it totally disables this functionality (instead of a screenshot, the user will see the nice error message). Additionally, it blocks all the screen recording options (only black screen is visible as the output) which is a really great add-on.

package com.nomtek.screenshield
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.WindowManager
class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
}
}

Please note that rooted devices can bypass this mechanism — in this case, you might think of detecting it and disabling your app, but it depends on your target market.

Starting from the left: demo app, screenshot taking result, video capture result.

iOS

iOS is more problematic — it can tell you if the screenshot was taken, but it’ll do it after screen capture:

class ViewController: UIViewController {
  override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
forName: UIApplication.userDidTakeScreenshotNotification,
object: nil, queue: nil) { _ in
print("I see what you did there")
}
}
}

Some chat apps use this to show alerts to chat participants that someone took a screenshot and they can kick him out :-) but it was not enough in our case, so we had to look for something else.

ScreenShieldKit

Firstly we noticed ScreenShieldKit — a really nice looking SDK which should do exactly what we were told to do. Authors released two really nice apps to the App Store (checkout Confide and Blackbox) which we played with for a while, and they appeared really screenshot and video-record proof!

We asked them for a trial version of SDK and we received it very quickly, so we could start checking it out. 
From a technical point of view, SDK will give you a set of UI components (ImageView and Label) which behaves similar to loved and well known UIKit equivalents. Under the hood, text and image are rendered as a video protected by DRM so that’s the reason why it’s not visible in screenshots. Brilliant idea I have to say. It might result in higher CPU usage (and battery drain) but as we had to block single image on screen it was okay for us.

The only con of ScreenShieldKit was a non-transparent pricing model — each license is priced individually based on the type of the app and estimated audience size. Apart from this, everything is great.

Starting from the left: demo app, screenshot taking result, video capture result. A label on top and QR code are protected by ScreenShieldKit.

Blur-obfuscating way

Few years ago, there was an app called D-fence which rendered animated layer above protected image to obfuscate it. Regular users did not see it because the animation was too fast to notice, but it had to be frozen on the screenshot, making it totally unreadable.

I couldn’t find the app itself on the AppStore, but the whole idea is clever and looks easy to implement. Keep in mind that constant animation may affect performance and battery drain, so I’d be careful with putting it into a CollectionView or any scrollable list.

Another problem with this approach is… the law. In this thread on StackOverflow, someone noticed that Yovo claimed to have 300+ patents for their technologies. But because a linked website is not reachable I’d recommend to send them an email to check if you’re not violating any patents.

Conclusion

For Android, the solution is super simple — just add a single line of code and Bob’s your uncle.

For iOS — it all depends. If you need 100% protection against screenshots, just use ScreenShieldKit — it does its job flawlessly and implementing (and maintaining) similar solution from the scratch will still cost you more than buying a license for sure.

But in the end, remember that someone can just take another device with the camera, and take a picture of your app — so your app will never be 100% screenshot proof.