アプリがバックグラウンドになったときにAndroidがスクリーンショットを撮らないようにするにはどうすればよいですか?


146

現在作成しているアプリには、セキュリティ上の理由から、アプリがバックグラウンドにプッシュされるときにOSがアプリのスクリーンショットを撮らないようにする必要があるという要件があります。これにより、アプリを切り替えるときに最後にアクティブだった画面を表示できなくなります。

この機能をアプリケーションクラスのonPauseメソッドに組み込む予定ですが、最初にこの機能を実現する方法を見つける必要があります。

それで、これを修正する方法の手掛かりを持つ誰かがいますか?

回答:


264

試してくださいFLAG_SECURE

public class FlagSecureTestActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
                         WindowManager.LayoutParams.FLAG_SECURE);

    setContentView(R.layout.main);
  }
}

これは、ICSの最近のタスク履歴からの手動のスクリーンショットと自動スクリーンショットから確実に保護されます。また、画面記録(メディアプロジェクションAPIを使用するアプリなど)からも保護されます。

更新:Android 6.0のNow On Tapまたは他のアシスタントに対しても保護されます。ユーザーがアシスタントを起動した場合、UIのウィジェットとコンテナーの詳細にアクセスできません。

更新#2:ただし、アクティビティのすべてが保護されるわけではありません。任意のポップアップウィンドウ- 、DialogSpinnerAutoCompleteTextViewアクションバーのオーバーフローなど-は安全ではないだろう。あなたはそれをDialog呼び出しgetWindow()て設定することによって問題を修正することができますFLAG_SECURE。残りはトリッキーになります。詳細については、このブログ投稿を参照してください。


6
@ Dany's:実際には、それは質問と関係があります。Nexus S(4.0.3)でテストしたところ、期待どおりに動作します-最近のタスクのスクリーンショットが抑制されています。アプリケーション名とアイコンは引き続き表示されますが、スクリーンショットは黒です。ICSハードウェアでお試しください。
CommonsWare 2012年

2
@ StingRay5:FLAG_SECURE最初から存在していた-最近まで意味が限られていた。
CommonsWare 2012年

1
興味深いことに、アクティビティのライフサイクルにはonCreateThumbnail niというメソッドがありますが、これは使用されていません。
Snicolas

2
@PankajKumar:あなたが書いた「スクリーンショットを撮るコード」がその古典的な「ルートとしてフレームバッファをつかむ」トリックFLAG_SECUREである場合、それは低レベルであるため、それを防御しません。同様に、独自のウィジェット階層をBitmap取得しCanvas、それを-backed に描画させた場合、FLAG_SECUREおそらくそれに対して防御しないでしょう。自分のウィジェットの独自のスクリーンショットを撮っているので、おそらくそこに「安全な」ものを望んでいたからです。最近のタスクのサムネイルなどFLAG_SECUREシステムのスクリーンショット用です
CommonsWare 2013年

2
素晴らしくてシンプルな答え!snapchatのようなアプリが、送信された画像のスクリーンショットを撮るのを防ぐためにこれを使用しないのはなぜですか
Shobhit Puri 2013

78

一部のデバイス(Samsung Galaxy ACE、たとえばGT-S5830で検証済み)では、WindowManager.LayoutParams.FLAG_SECUREの使用に注意してください。これにより、ビューがスクランブルになります。Samsung固有のバグのようです。私は以下をお勧めします:

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}

これは、スクランブルされた画面は次のようになります。

スクランブルされた画面イメージ

ただし、これはICS Samsungの電話で正常に機能しているため、問題はジンジャーブレッドデバイス(またはそれ以前)に限定されていると想定しています。


8
まったくその通りです。この問題に遭遇しました。APIレベルを確認する必要があったことは確かです。実際にこれを投稿するのを忘れたので、もう一度取り上げてくれてありがとう。:)
StingRay5

Samsung Gio(ジンジャーブレッド)でも発生しますが、Froyoでは問題ありません。2.3でのみ発生します
ピクセル

この問題にも気付きました。Gingerbreadデバイスのエミュレータで確認できます。
twaddington

この問題はSamsung Gingerbreadデバイスでも発生することを確認できます。
Ernir Erlingsson 2013

7
新しいAndroidバージョンでもFLAG_SECUREが問題になる可能性があります。Android4.3でFLAG_SECUREを使用すると、画面回転アニメーションでアニメーションの問題が発生します。code.google.com/ p / android / issues / detail?id = 58632を参照してください-これはAndroid 4.4で修正されました
Oliver

13

CommonsWareが提供するソリューションは、Lollipopでも引き続き有効です。

アプリ全体の最新のリストにスナップショットを表示しないようにしたい場合は、実装されているすべてのアクティビティでメソッドの 前にフラグを指定する必要がありますonCreate()getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);setContentView();

それ以外の場合、最近のリストのスナップショットには、ユーザーがナビゲートした場合、フラグのない最初のアクティビティが表示されます。


1
私のアプリでは、ユーザー設定に基づいてFLAG_SECUREを設定/クリアする機能があります。KITKATまで問題なく動作し、黒い画面がタスクスイッチャーで表示されます。Lollipopでは、概要にアプリの最後のスナップショット、FLAG_SECUREが設定されなかった(クリアされた)時間が表示されます。
r.bhardwaj

@ r.bhardwajその場合はあまりできないと思いますが、ユーザーにアドバイスするには、変更を完全に有効にするためにアプリを再起動する必要があります;-)これで完了です。
Davideas、2015年

1
スナップショットを撮る前にカスタムビューを膨らませる方法を誰かが見つけたので、それは単なる黒い画面ではありませんか?onPauseでウィンドウマネージャーのビューを膨らませてみましたが、それでは手遅れです。
user1064249 2017

こんにちは@ user1064249何か解決策を見つけましたか?OSがスクリーンショットを撮る前に、Launcher Viewを膨らませたい
Alexiscanny

1

アプリがバックグラウンドに置かれたときに、アプリのコンテンツをスプラッシュスクリーンで覆うことにより、アプリのコンテンツを非表示にするためのソリューションを次に示します。これはFLAG_SECURE手法を使用していません。単に画面のonPauseメソッドとonResumeメソッドをオーバーライドし、ビューを変更してすべてをカバーするビューを表示します。

https://stackoverflow.com/a/52976001/6686912


0
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
            WindowManager.LayoutParams.FLAG_SECURE);

これは私にとってはうまくいきました。スクリーンショットを撮ったり、内蔵またはサードパーティの録音アプリケーションが画面を録音したりするのを防ぎます。


0

これは、すべてのアクティビティのsetContentViewの前にこれらの行をonCreateに追加した後の作業です。

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,     
WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_notification);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.