Làm cách nào để ngăn Android chụp ảnh màn hình khi ứng dụng của tôi chạy nền?


146

Ứng dụng tôi hiện đang xây dựng có yêu cầu ứng dụng phải ngăn hệ điều hành chụp ảnh màn hình của ứng dụng khi ứng dụng bị đẩy xuống nền vì lý do bảo mật. Bằng cách này, nó sẽ không thể nhìn thấy màn hình hoạt động cuối cùng khi chuyển đổi giữa các ứng dụng.

Tôi dự định đưa chức năng này vào phương thức onPause của lớp ứng dụng, nhưng trước tiên tôi cần tìm hiểu làm thế nào tôi có thể đạt được chức năng này.

Vì vậy, có ai ngoài đó, có một đầu mối làm thế nào để khắc phục điều này?

Câu trả lời:


264

Hãy thử 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);
  }
}

Điều này chắc chắn bảo vệ chống lại các ảnh chụp màn hình thủ công và ảnh chụp màn hình tự động từ lịch sử các nhiệm vụ gần đây của ICS. Nó cũng bảo vệ chống lại việc ghi lại màn hình (ví dụ: các ứng dụng sử dụng API trình chiếu phương tiện).

CẬP NHẬT : nó cũng bảo mật với Now On Tap hoặc các trợ lý khác trên Android 6.0; họ sẽ không có quyền truy cập vào các chi tiết của widget và container trong UI của bạn nếu người dùng đưa trợ lý lên.

CẬP NHẬT # 2 : tuy nhiên, không phải mọi thứ trong hoạt động sẽ được bảo vệ. Bất kỳ cửa sổ pop-up - Dialog, Spinner, AutoCompleteTextView, hành động thanh tràn, vv - sẽ không an toàn. Bạn có thể khắc phục sự Dialogcố bằng cách gọi getWindow()vào nó và cài đặt FLAG_SECURE. Phần còn lại ... trở nên khó khăn. Xem bài đăng blog này để biết thêm.


6
@ Dany's: Thật ra, nó có mọi thứ để làm với câu hỏi. Tôi vừa thử nghiệm nó trên Nexus S (4.0.3) và nó hoạt động như mong đợi - ảnh chụp màn hình của các tác vụ gần đây bị loại bỏ. Bạn vẫn thấy tên ứng dụng và biểu tượng, nhưng ảnh chụp màn hình là màu đen. Bạn được chào đón để thử nó trên phần cứng ICS.
CommonsWare

2
@ StingRay5: FLAG_SECUREđã tồn tại từ đầu - nó chỉ có ý nghĩa hạn chế cho đến gần đây.
CommonsWare

1
Thật thú vị khi lưu ý rằng có một phương thức gọi là onCreateThumbnail ni vòng đời hoạt động, nhưng nó không bao giờ được sử dụng.
Snicolas

2
@PankajKumar: Nếu "mã để chụp ảnh màn hình" mà bạn đã viết là trò lừa "lấy bộ đệm khung làm gốc" cổ điển, FLAG_SECUREthì bạn sẽ không chống lại điều đó, vì mức độ quá thấp. Tương tự, nếu bạn mất thứ bậc phụ tùng của riêng bạn và đã có nó vẽ một Bitmap-backed Canvas, FLAG_SECUREcó lẽ sẽ không bảo vệ chống lại rằng, khi bạn đang dùng ảnh chụp màn hình của riêng bạn của widget riêng của bạn và do đó có lẽ muốn sự "an toàn" những người trong đó. FLAG_SECUREdành cho ảnh chụp màn hình hệ thống , chẳng hạn như hình thu nhỏ của các tác vụ gần đây.
CommonsWare

2
Câu trả lời tuyệt vời và đơn giản! Tôi tự hỏi tại sao các ứng dụng như snapchat không sử dụng điều này để ngăn người khác chụp ảnh màn hình của hình ảnh được gửi.
Shobhit Puri

78

Hãy cẩn thận về việc sử dụng WindowManager.LayoutParams.FLAG_SECURE, trên một số thiết bị (đã được xác minh trên Samsung Galaxy ACE, ví dụ GT-S5830), điều này sẽ khiến chế độ xem bị xáo trộn. Trông giống như một lỗi cụ thể của Samsung. Tôi khuyên bạn nên như sau:

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

Đây là màn hình được xáo trộn trông như thế nào:

Ảnh màn hình bị xáo trộn

Tuy nhiên, điều này đang hoạt động tốt trên điện thoại ICS của Samsung, vì vậy tôi cho rằng vấn đề được tách biệt với các thiết bị Gingerbread (hoặc cũ hơn).


8
Bạn hoàn toàn đúng, chúng tôi đã gặp vấn đề này và chắc chắn cần phải kiểm tra mức API. Trên thực tế đã quên đăng bài này, vì vậy cảm ơn bạn đã đưa nó lên một lần nữa. :)
StingRay5

Nó cũng xảy ra trên Samsung Gio (Gingerbread) nhưng trên Froyo thì không sao - vì vậy nó chỉ xảy ra trên 2,3
pixel

Chúng tôi nhận thấy vấn đề này là tốt. Bạn có thể xác minh trong Trình mô phỏng trên các thiết bị Gingerbread.
twaddington

Tôi cũng có thể xác nhận rằng sự cố này xuất hiện trên các thiết bị Samsung Gingerbread.
Ernir Erlingsson

7
Ngay cả trên các phiên bản Android mới hơn, FLAG_SECURE có thể gặp sự cố: trên Android 4.3 FLAG_SECURE gây ra sự cố hoạt hình trong hoạt hình xoay màn hình, hãy xem code.google.com/p/android/issues/detail?id=58632 - điều này đã được khắc phục trên Android 4.4
Oliver

13

Giải pháp được cung cấp bởi CommonsWare tiếp tục có hiệu lực trong Lollipop.

Chỉ cần một lưu ý, nếu bạn muốn tiếp tục không thấy ảnh chụp nhanh trong danh sách gần đây cho toàn bộ ứng dụng, TẤT CẢ các hoạt động đã triển khai phải chỉ định trong onCreate()phương thức cờ getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); trướcsetContentView();

Nếu không, một ảnh chụp nhanh trong danh sách gần đây sẽ hiển thị hoạt động đầu tiên mà không có cờ nếu người dùng điều hướng qua nó.


1
Trong ứng dụng của mình, tôi có chức năng cài đặt / xóa FLAG_SECURE dựa trên sở thích của người dùng. Nó hoạt động tốt cho đến khi KITKAT và màn hình đen có thể được nhìn thấy trong trình chuyển đổi tác vụ. Trong Lollipop, Tổng quan hiển thị ảnh chụp nhanh cuối cùng của ứng dụng của tôi, thời điểm FLAG_SECURE chưa được đặt (đã xóa).
r.bhardwaj

@ r.bhardwaj Tôi nghĩ rằng chúng ta không thể làm gì nhiều trong trường hợp đó, nhưng bạn có thể khuyên người dùng rằng, thay đổi cần ứng dụng được khởi động lại để có hiệu lực đầy đủ ;-) và bạn đã hoàn thành.
Davideas

1
Bất cứ ai cũng tìm thấy một cách để tăng một chế độ xem tùy chỉnh trước khi chụp ảnh nhanh để nó không chỉ là một màn hình đen? Tôi đã thử tăng cường một cái nhìn về trình quản lý cửa sổ trong onPause, nhưng có vẻ như sau đó thì đã quá muộn.
dùng1064249

Hi @ user1064249 Bạn đã tìm thấy giải pháp nào chưa? Tôi muốn làm tăng Chế độ xem Trình khởi chạy trước khi HĐH chụp ảnh màn hình
Alexiscanny

1

Dưới đây là một giải pháp để ẩn nội dung của ứng dụng bằng cách che nó bằng màn hình giật gân khi ứng dụng được đặt vào nền. Đây không phải là sử dụng kỹ thuật FLAG_SECURE, tôi chỉ đơn giản ghi đè các phương thức onPause và onResume của màn hình và sửa đổi chế độ xem để hiển thị chế độ xem bao gồm mọi thứ ở phía sau.

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


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

điều này làm việc cho tôi, nó ngăn không cho chụp ảnh màn hình và bất kỳ ứng dụng ghi âm nào của bên thứ ba hoặc bên thứ ba từ màn hình ghi.


0

Đây là công việc đối với tôi sau khi thêm các dòng này vào onCreate trước setContentView của mọi hoạt động.

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,     
WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_notification);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.