Android'in uygulamam arka plana geçtiğinde ekran görüntüsü almasını nasıl engelleyebilirim?


147

Şu anda geliştirdiğim uygulama, güvenlik nedenleriyle arka plana itildiğinde işletim sisteminin işletim sisteminin bir ekran görüntüsünü almasını engellemesini gerektiriyor. Bu şekilde, uygulamalar arasında geçiş yaparken son etkin ekranı göremez.

Bu işlevselliği uygulama sınıfının onPause yöntemine eklemeyi planlıyorum, ancak önce bu işlevi nasıl elde edebileceğimi bulmam gerekiyor.

Öyleyse, bunu nasıl düzelteceğine dair ipucu olan kimse var mı?

Yanıtlar:


268

Deneyin 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);
  }
}

Bu, ICS son görevler geçmişinden manuel ekran görüntülerine ve otomatik ekran görüntülerine karşı kesinlikle koruma sağlar. Ayrıca ekran kaydına karşı da koruma sağlar (örneğin, medya projeksiyon API'larını kullanan uygulamalar).

GÜNCELLEME : Android 6.0'da Now On Tap veya diğer asistanlara karşı da koruma sağlar; kullanıcı asistanı getirirse, kullanıcı arayüzünüzdeki widget'ların ve kapsayıcıların ayrıntılarına erişemezler.

GÜNCELLEME # 2 : Ancak, etkinlikteki her şey korunmayacaktır. Herhangi bir pop-up pencereler - Dialog, Spinner, AutoCompleteTextView, işlem çubuğu taşma vs - güvensiz olacaktır. Sen düzeltebilirsiniz Dialogarayarak sorunu getWindow()üzerinde ve ayar FLAG_SECURE. Gerisi ... zorlaşır. Daha fazlası için bu blog gönderisine bakın .


6
@ Dany's: Aslında soruyla ilgili her şeyi var. Bunu bir Nexus S (4.0.3) üzerinde test ettim ve beklendiği gibi çalışıyor - son görevlerin ekran görüntüsü bastırıldı. Hala uygulama adını ve simgesini görüyorsunuz, ancak ekran görüntüsü siyah. ICS donanımında deneyebilirsiniz.
CommonsWare

2
@ StingRay5: FLAG_SECUREbaşından beri var - yakın zamana kadar sınırlı bir anlamı vardı.
CommonsWare

1
Etkinlik yaşam döngüsünde onCreateThumbnail adında bir yöntem olması ilginçtir, ancak hiç kullanılmamıştır.
Snicolas

2
@PankajKumar: Yazdığınız "ekran görüntüsü alma kodu" klasik "çerçeve tamponunu kök olarak yakala" hilesi ise, FLAG_SECUREçok düşük seviyeli olduğu için buna karşı savunma yapmaz. Benzer şekilde, kendi widget hiyerarşinizi alıp Bitmap-backed'e çekmişseniz Canvas, FLAG_SECUREmuhtemelen kendi ekran görüntülerinizi kendi widget'larınızın ekran görüntülerini aldığınız ve bu nedenle muhtemelen oradaki "güvenli" olanları istediğiniz için buna karşı savunma yapmayacaksınız . FLAG_SECUREiçindir sistem böyle son-görevler küçük resimler olarak ekran görüntüleri,.
CommonsWare

2
Harika ve basit cevap! Snapchat gibi uygulamaların neden birisinin gönderilen resimlerin ekran görüntüsünü almasını önlemek için bunu kullanmadığını merak ediyorum .
Shobhit Puri

78

WindowManager.LayoutParams.FLAG_SECURE kullanımında dikkatli olun, bazı cihazlarda (Samsung Galaxy ACE'de doğrulanmıştır, örn. GT-S5830) bu, görünümü karıştıracaktır. Samsung'a özgü bir hataya benziyor. Aşağıdakileri tavsiye ederim:

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

Karıştırılmış bir ekran şöyle görünür:

Şifreli Ekran Görüntüsü

Bu, ICS Samsung telefonlarında düzgün çalışıyor, bu yüzden sorunun Gingerbread cihazlarına (veya daha eski) izole edildiğini varsayıyorum.


8
Tamamen haklısınız, bu sorunla karşılaştık ve kesinlikle API seviyesini kontrol etmemiz gerekiyordu. Aslında bunu göndermeyi unuttum, bu yüzden tekrar açtığın için teşekkürler. :)
StingRay5

Ayrıca Samsung Gio (Gingerbread) ama Froyo üzerindeki OK oluşur - sadece 2.3 oluşursa bu yüzden
piksel

Bu sorunu da fark ettik. Gingerbread cihazlarındaki Emülatörde doğrulayabilirsiniz.
twaddington

Bu sorunun Samsung Gingerbread cihazlarında göründüğünü de doğrulayabilirim.
Ernir Erlingsson

7
Daha yeni Android sürümlerinde bile FLAG_SECURE sorunlu olabilir: Android 4.3'te FLAG_SECURE, ekran döndürme animasyonunda animasyon sorunlarına neden olur, bkz. Code.google.com/p/android/issues/detail?id=58632 - bu, Android 4.4'te düzeltildi
Oliver

13

CommonsWare tarafından sağlanan çözüm, Lollipop'ta da geçerli olmaya devam ediyor.

Eğer devam etmek istiyorsanız Sadece bir nota değil için son listede anlık bakınız tüm app, TÜM uygulanan faaliyetler içinde belirtmelidir onCreate()yöntemle bayrağı getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); öncesetContentView();

Aksi takdirde, son listedeki bir anlık görüntü, kullanıcı gezinmişse ilk etkinliği bayraksız olarak gösterecektir.


1
Uygulamamda, bir kullanıcı tercihine göre FLAG_SECURE'ü ayarlama / temizleme işlevine sahibim. Görev değiştiricide KITKAT ve siyah ekran görülebilene kadar iyi çalıştı. Lollipop'ta Genel Bakış, uygulamamın son anlık görüntüsünü, FLAG_SECURE'ün ayarlanmadığı zamanı (temizlendiği) gösterir.
r.bhardwaj

@ r.bhardwaj Bu durumda çok fazla şey yapamayacağımızı düşünüyorum, ancak kullanıcıya değişikliğin tam olarak etkili olması için Uygulamanın yeniden başlatılması gerektiğini ;-) ve işin bittiğini söyleyebilirsiniz.
Davideas

1
Anlık görüntü alınmadan önce özel bir görünümü şişirmenin bir yolunu buldunuz, bu yüzden sadece siyah bir ekran değil mi? OnPause'da pencere yöneticisinde bir görünümü şişirmeyi denedim, ancak o zamana kadar çok geç görünüyor.
user1064249

Merhaba @ user1064249 Herhangi bir çözüm buldunuz mu? İşletim sistemi ekran görüntüsünü almadan önce Başlatıcı Görünümünü şişirmek istiyorum
Alexiscanny

1

İşte bir uygulamanın içeriğini, uygulama arka plana yerleştirildiğinde bir açılış ekranıyla kaplayarak gizlemek için bir çözüm. Bu FLAG_SECURE tekniğini kullanmıyor, sadece ekranların onPause ve onResume yöntemlerini geçersiz kılıyorum ve arkadaki her şeyi kapsayan bir görünüm gösterecek şekilde görünümü değiştiriyorum.

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


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

bu benim için çalıştı, ekran görüntüsünün alınmasını ve ayrıca herhangi bir dahili veya üçüncü taraf kayıt uygulamasının ekran kaydetmesini engelliyor.


0

Bu, her etkinliğin setContentView öncesinde bu satırı onCreate'e ekledikten sonra benim için çalışıyor.

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,     
WindowManager.LayoutParams.FLAG_SECURE);
setContentView(R.layout.activity_notification);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.