Androidでスクリーンショットを無効にする方法

※本ページにはプロモーション(広告)が含まれています。
Androidでスクリーンショットを無効にする方法

アプリ画面のスクリーンショットを止めたいけれど方法がわからず困っている方は多いですよね。

ここを読めばFLAG_SECUREを使った実装が短時間でわかりActivityやWebViewでの具体的な実装例と確認時の注意点までしっかり把握できます。

項目内容
独自コンテンツ1実体験に基づく手順と動くサンプルコード。
独自コンテンツ2ActivityとFragmentそれぞれの注意点を実例で解説。
独自コンテンツ3WebViewや動画再生時の落とし穴と対処法。

まずはFLAG_SECUREの仕組みをやさしく理解してから実際のコードを写して試してみましょう。それだけで画面保護の基本が身に付き運用時のトラブルも減らせます。

Android博士

困ったときは気軽に戻ってきてくださいね。順を追って進めれば無理なく設定できますし安心して取り組んでくださいね。

目次

Androidでアプリ側からスクリーンショットをオフにする方法(FLAG_SECURE)

Androidでアプリ側からスクリーンショットをオフにする方法(FLAG_SECURE)

FLAG_SECUREを使えばアプリ側からスクリーンショットと画面録画を防げます。最近表示のサムネイルも通常は空白になるため、機密情報の露出をぐっと減らせます。

実装はWindowにフラグを立てるだけでシンプルです。ただし機種やランチャーによって挙動差が出ることがあるため、必ず実機で動作確認してください。

使いどころはログイン画面や決済画面などスクショを避けたい画面です。次に複数の実装パターンを簡単に示すので、プロジェクトに合う方法を選んでください。

  • Activity単位でFLAG_SECUREを立てる:アクティビティ全体を保護したいときに手っ取り早い方法です。
  • 表示中のみフラグを付け外しする:Fragment表示に合わせて動的に切り替えると部分的な保護ができます。
  • ホストのwindowで制御して特定ビューを守る:WebViewを含む画面でも同じ手順で扱えます。

ActivityでFLAG_SECUREを設定してスクリーンショットを無効にするパターン

ActivityでFLAG_SECUREを設定してスクリーンショットを無効にするパターン

ActivityのonCreateでWindowのフラグにFLAG_SECUREを設定するのがもっともよく使われるパターンです。例えばgetWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,WindowManager.LayoutParams.FLAG_SECURE);を呼べばスクショと録画がブロックされます。

この方法はアクティビティ全体を保護するため実装が楽です。実機で最近アプリのサムネイルや画面録画を使って正しく反映されるか確認してください。

ActivityのonCreateでgetWindow().setFlagsを追加して実機で動作確認する手順

手順
コードを追加する

onCreateでgetWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,WindowManager.LayoutParams.FLAG_SECURE);を追加してください。

手順
実機で起動する

ビルドして実機にインストールし該当のActivityを開いてスクリーンショットと画面録画を試してください。

手順
解除も確認する

必要に応じてonDestroyや適切なタイミングでgetWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);を呼んで解除を確認してください。

FragmentやWebViewを含む画面で部分的にスクリーンショットをオフにするパターン

FragmentやWebViewを含む画面で部分的にスクリーンショットをオフにするパターン

FragmentやWebViewを含む画面ではActivity全体を保護すると過剰になる場合があります。必要な部分だけスクショ禁止にしたいときは表示に合わせてwindowのフラグを付け外しするのが現実的です。

WebView内のコンテンツもWindowフラグに従うため、対象Fragmentを表示するときにFLAG_SECUREをONにし離れたらOFFにする実装が使いやすいです。

ホストActivityのwindowにフラグを設定しFragmentのライフサイクルで動的に切り替える手順

手順
表示時にフラグを付ける

FragmentのonStartでrequireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)を呼んで表示中のスクショを防ぎます。

手順
非表示時にフラグを外す

FragmentのonStopでrequireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)を呼んで他画面への影響を防ぎます。

手順
nullチェックで堅牢にする

遷移中にactivityがnullになるケースがあるためactivityやwindowが存在するかを確認してからフラグ操作を行うと安全です。

Androidで端末管理者機能を使って全体のスクリーンショットをオフにする方法

Androidで端末管理者機能を使って全体のスクリーンショットをオフにする方法

端末全体のスクリーンショットをオフにしたいときは、アプリ単体のFLAG_SECUREだけでは足りないことが多いです。端末管理者権限を持つデバイスオーナーアプリなら、DevicePolicyManagerでシステムレベルに禁止をかけられます。

setScreenCaptureDisabledを有効にするとスクリーンショットと画面収録の両方が制限され、ユーザーのボタン操作やAPI経由での取得を防げます。全アプリに効くため機密情報の保護には有効です。

ただしデバイスオーナー化には端末の初期化やプロビジョニングが必要になります。開発や検証ではadbで一時的に設定して挙動を確認し、運用ではEMMやMDMで展開するのがおすすめです。

  • DeviceOwnerでDevicePolicyManager.setScreenCaptureDisabledを使う。端末全体に効く方法です。
  • EMMや管理コンソールでデバイス管理を行う。運用向けに安定した方法です。
  • アプリ内でFLAG_SECUREを使う。個別アプリだけを保護したいときに手軽です。
Android博士

管理者権限は強力なので慎重に扱ってくださいね。まずはテスト端末でじっくり試してから本番に移すと安心です。

DevicePolicyManagerでスクリーンキャプチャを無効にする実装パターン(device owner)

DevicePolicyManagerでスクリーンキャプチャを無効にする実装パターン(device owner)

DeviceOwnerとして実装する場合、アプリ側でDevicePolicyManagerのインスタンスを取得してsetScreenCaptureDisabled(adminComponentName,true)を呼び出します。呼び出しはDeviceAdminReceiverや管理用サービス内で行い、ユーザー操作に応じて切り替えると扱いやすいです。

重要なのはアプリが本当にデバイスオーナーになっていることと正しいComponentNameを使うことです。権限不足や間違ったコンポーネントだと無視されるのでログやdumpsysで状態を確認しながら進めると失敗が減ります。

DevicePolicyManagerのsetScreenCaptureDisabledを管理者コンポーネントから呼び出しadbで確認する手順

手順
管理者コンポーネントでAPIを呼ぶ

DevicePolicyManagerのインスタンスを取得しdpm.setScreenCaptureDisabled(adminComponentName,true)を呼び出します。呼び出しはDeviceAdminReceiverやサービスの管理操作画面から行うとわかりやすいです。

手順
adbでDeviceOwnerに設定

テスト端末ではADBを使ってデバイスオーナーに設定します。例:adb shell dpm set-device-owner com.example/.AdminReceiver。端末が初期化されるので事前にバックアップしてください。

手順
動作確認と追加チェック

スクリーンショットを試して取得できないことを確認します。必要ならadb shell dumpsys device_policyで状態を確認し、ログにエラーがないかチェックしてください。

Androidでスクリーンショットが勝手にオフになる問題を調べて元に戻す方法

Androidでスクリーンショットが勝手にオフになる問題を調べて元に戻す方法

スクリーンショットが急に撮れなくなって慌てた経験は誰にでもあります。原因は大きく分けてアプリ側で画面を保護している場合と、端末ポリシーで撮影を禁止している場合の二つです。

まずは落ち着いて原因を絞り込むことが重要です。前景で動いているアプリを特定し、必要ならログやダンプでフラグやポリシーを確認していきます。

このあとに紹介する手順でFLAG_SECUREによる保護かDevicePolicyによる制限かを判別できます。判別できれば対処の方向も分かりやすくなりますので焦らず進めてください。

スクリーンショット不可の原因を特定する手順(FLAG_SECUREか端末ポリシーかの判別)

スクリーンショット不可の原因を特定する手順(FLAG_SECUREか端末ポリシーかの判別)

まずは簡易チェックを行います。他のアプリでスクリーンショットが撮れるか試して、問題が特定のアプリだけか端末全体かを確認してください。

アプリ固有ならFLAG_SECUREが使われている可能性が高いです。端末全体ならDevicePolicyがスクリーンショットを無効にしていることが多いので、管理者設定や端末管理アプリを確認してください。

adbでウィンドウフラグやDevicePolicyの状態を確認するコマンドと出力の見方

項目内容
前景アクティビティを確認するコマンドadb shell dumpsys activity activities | grep mResumedActivity で最前面のパッケージ名とアクティビティを確認できます。問題のアプリが分かれば対象を絞れます。
ウィンドウフラグを確認するコマンドadb shell dumpsys window windows | grep -E “mCurrentFocus|mSecure” でウィンドウのsecureフラグや現在表示中のウィンドウ情報が見えます。mSecure=trueやFLAG_SECURE相当の表示を探してください。
端末ポリシーの状態を確認するコマンドadb shell dumpsys device_policy でDevicePolicyManagerの状態を取得できます。出力中に screenCaptureDisabled や ActiveAdmins の記載があればポリシーが関係している手がかりになります。

応用:機密情報表示時だけスクリーンショットをオフにして普段は許可する方法

応用:機密情報表示時だけスクリーンショットをオフにして普段は許可する方法

機密情報を表示する画面だけスクリーンショットを無効にして普段は許可するのは現場でよくある要求です。FLAG_SECUREを必要なタイミングだけ付け外すことで実現できます。まずはどの画面を機密扱いにするかを明確にしておくと安心です。

実装パターンとしてはActivity単位で常時付ける方法と、Fragmentや一時的な処理で切り替える方法があります。多くの現場ではonResume/onPauseでaddFlags/clearFlagsを呼んで切り替えるやり方が扱いやすくて事故が少ないと感じます。

ユーザーがなぜスクリーンショットできないか分かるように小さな説明をUIに入れておくと混乱が減ります。端末やAndroid11以降での挙動差は実機で確認しておくとトラブルが減ります。

Android博士

機密画面だけ一時的にスクリーンショットを止めるのはユーザーの安心につながります。切り替えはシンプルにして実装ミスを減らしましょう。

表示条件に応じてFLAG_SECUREを切り替える実装パターン

表示条件に応じてFLAG_SECUREを切り替える実装パターン

表示条件に応じてFLAG_SECUREを切り替える代表的なパターンは次の3つです。1.Activityで常時FLAG_SECUREを付ける。2.機密FragmentだけonResumeで有効化する。3.ボタン操作やダイアログ表示で一時的に切り替える。用途に合わせて選ぶと良いです。

運用面ではLifecycleに合わせて切り替えるのが安全です。Navigationの遷移先で有効化して戻るときに解除するか、LifecycleObserverで共通化するとコードがすっきりして忘れにくくなります。

ユーザー操作や画面遷移でFLAG_SECUREをON/OFFするコードを置く箇所と説明の書き方

手順
Activityのライフサイクルに置く

onResumeでgetWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE)を呼び、onPauseでgetWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE)を呼ぶ。

手順
Fragmentで制御する

機密表示のFragmentではonResume/onPauseに同様の切替処理を置く。ナビゲーション遷移時に自然に働きます。

手順
共通化して管理する

複数画面で使うならLifecycleObserverやユーティリティにまとめる。コメントは機密表示のための切替である旨を短く書いておくと親切です。

よくある質問

よくある質問
FLAG_SECUREだけでスクリーンショットを完全に防げますか

FLAG_SECUREを設定すると、通常のスクリーンショットや画面録画はほとんど防げます。とはいえ、外部カメラでの撮影やroot化した端末、特殊なツールには対応できないことがあるので、特に重要なデータはサーバー側で暗号化するなど別の対策も考えてください。

どのタイミングでFLAG_SECUREを設定すればいいですか

ActivityではonCreateの早い段階でwindowにFLAG_SECUREを付けると確実です。FragmentやJetpack Composeを使う場合は、ホストするActivityで管理するかライフサイクルに合わせて設定と解除を行ってください。

FLAG_SECUREを使うとユーザー操作にどんな影響がありますか

スクリーンショットや録画ができなくなるため、共有機能や画面録画を前提とした操作が期待通りに動かなくなります。必要な画面だけに限定して使い、画面上で撮影不可であることをわかりやすく伝えるとユーザーにやさしいです。

開発中やテストで一時的に無効にする方法はありますか

デバッグビルドだけ無効化するためにBuildConfig.DEBUGで条件分岐するのが安全で便利です。実機で一時解除したいときはgetWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE)を使えば簡単に戻せます。

まとめ

まとめ

アプリ側でスクリーンショットを防ぐにはFLAG_SECUREを使うのが手っ取り早いです。ActivityやWindowにフラグを立てるだけでスクリーンショットと画面録画が制限されリセントのサムネイルも保護されます。

使いどころは最小限に絞るのがコツです。ログインや決済など秘密情報のある画面だけに設定するとユーザーに優しいです。

注意点として物理的なカメラ撮影までは防げない点を忘れないでください。必要なら説明文や共有の代替を用意しておくと親切です。

Android博士

まずは一画面だけFLAG_SECUREを試して動作を確かめてみましょう。確認後に段階的に広げると安心して実装できます。

注意:端末やOSのバージョンで挙動が異なる場合があるので実機での確認は必ず行ってください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次