iOS Ekran Görüntüsü Algılama?


135

Uygulama Snapchat , App Store üzerinden, onlara bir kendini imha fotoğraf paylaşabilir olanak veren bir uygulamadır. Fotoğrafları yalnızca X saniye boyunca görüntüleyebilirsiniz. Ev güç tuşu kombinasyonunu kullanarak resim gösterilirken ekran görüntüsü almaya çalışırsanız, gönderene ekran görüntüsü almaya çalıştığınızı bildirir.

SDK'nın hangi kısmı kullanıcının ekran görüntüsü aldığını tespit etmenizi sağlar? Bunun mümkün olduğunu bilmiyordum.


1
stackoverflow.com/questions/2121970/… , Ekran görüntüsünü daha önce çekmeden önce -applicationDidEnterBackground: öğesini çağırmak için kullanılmış gibi görünüyor. Bundan emin değilim.
iDev

Adamlar. Diğer iş parçacığının cevabı var: stackoverflow.com/questions/2121970/…
me2

1
Bunu da kontrol edin, stackoverflow.com/a/8711894/1730272 , artık mümkün olmadığını söylüyor. Muhtemelen bunu deneyebilir ve bize bildirebilirsiniz.
iDev

İnternette henüz herhangi bir yerde bahsedilen bu görmedim, ancak bir ekran görüntüsü (Organizatör penceresindeki cihazdan) almak için Xcode kullanırsanız, uygulamanın kesinlikle bilemeyeceği bir yol olduğunu varsayalım. Alınan bir Snapchat fotoğrafını görüntülerken eklenen tüm fotoğraflar için Kamera Rulosunu izlemeli ve ekran görüntüsünü Xcode ile çekmek bunu tamamen atlar (jailbreak yapmaya gerek kalmadan).
smileyborg

Takip: Bu teori test edildi ve uygulamanın Xcode ekran görüntülerini algılamadığını doğruladı. Bununla birlikte, ilginç olanın, iOS 6'da, uygulamalara fotoğraflara erişmek için açıkça izin verilmesi gerektiğinin farkına vardım ... ancak bu uygulama, fotoğraflara erişmesine izin vermeden ekran görüntülerini hala tespit ediyor! Algılama için başka bir yöntem kullanıyor olmalıdır - Home + Sleep düğmesi yöntemini kullanırken, etkin fotoğrafın ekrandan da kaldırıldığını fark ediyorum. Bu yüzden, uygulamanın bir GestureRecognizer ile güvenilir bir şekilde izleyebileceği bu ekran görüntüsü işlemiyle ilgili bir model olmalı?
smileyborg

Yanıtlar:


22

Cevabı buldum !! Ekran görüntüsü almak, ekrandaki dokunuşları kesintiye uğratır. Bu yüzden snapchat resmi görmek için beklemeye ihtiyaç duyar. Referans: http://tumblr.jeremyjohnstone.com/post/38503925370/how-to-detect-screenshots-on-ios-like-snapchat


15
İOS 7 ile artık doğru değil . İOS7 + çözümü için aşağıya bakın .
Joe Masilotti

6
Joe'nun söyledikleri doğrudur. Asker bunun doğru cevap olarak işaretini kaldırmalıdır.
Bisküvi Tanrısı

UIApplication Kullanıcı Yaptı Ekran Görüntüsü Bildirimi kullanılabilir .. iOS 7+
Amit Tandel

353

İOS 7'den itibaren diğer cevaplar artık doğru değil. Apple bunu yaptı touchesCancelled:withEvent:, artık kullanıcı bir ekran görüntüsü aldığında çağrılmıyor.

Bu, Snapchat'ı tamamen etkili bir şekilde kıracaktır, bu nedenle yeni bir çözümde birkaç beta eklendi. Şimdi, çözüm UIApplicationUserDidTakeScreenshotNotification bir gözlemci eklemek için NSNotificationCenter kullanmak kadar basit .

İşte bir örnek:

Hedef C

NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationUserDidTakeScreenshotNotification
                                                  object:nil
                                                   queue:mainQueue
                                              usingBlock:^(NSNotification *note) {
                                                 // executes after screenshot
                                              }];

hızlı

NotificationCenter.default.addObserver(
    forName: UIApplication.userDidTakeScreenshotNotification,
    object: nil,
    queue: .main) { notification in
        //executes after screenshot
}

3
Bunu kullanmak ve touchesCancelled:withEvent:iOS'un tüm (son) sürümlerinde bir ekran görüntüsü algılamanıza izin vermelidir.
Joshua Gross

46
Bu, ekran görüntüsünün alınmasını önlemek için çalışmaz. Sadece bir kişinin alındığını bildirebilir .. UIApplication Sınıfı Referans: UIApplicationUserDidTakeScreenshotNotification Kullanıcı ekran görüntüsü almak için Ana Sayfa ve Kilit düğmelerine bastığında gönderildi. Bu bildirim bir userInfo sözlüğü içermez. Bu bildirim, ekran görüntüsü alındıktan SONRA gönderilir.
badweasel

6
@badweasel Doğru. Bu bildirimin geleneksel Kakao adlandırma kurallarına uygun olduğu düşünüldüğünde, "Yapıldı" sözcüğü, bildirimden sonra yayınlandığını ima eder. Bu durumda "Will" eşdeğeri yoktur ve AFAIK, kullanıcının genel API kullanarak ekran görüntüsü almasını engellemenin bir yolu yoktur.
Mick MacCallum

1
Size bir +1 verdiğimi unutmayın. Başlangıçta OP sorusunu yanlış okudum ve sorunun bir şeyi önlemek için nasıl tespit edileceğini düşündüm - çünkü aradığım şey bu. Bu yüzden açıklamaya sadece açıklama ekledim çünkü bu soruya gelen birçok insanın bu cevabı aramasını bekliyorum. Ben de "yaptım" sözcüğünden de varsaydım ama belgeler daha da netleştiriyor. Uygulamamda insanların fotoğraf düzenlemesine izin veriyorum, ancak bazı araçlar IAP gerektiriyor. Ama satın almadan önce denemelerine izin verdim. Bu yüzden bir filigran eklemek için yakalanmadan önce tespit etmek istedim. Yapamam.
badweasel

1
@MickMacCallum Ana kuyrukta yapmanın belirli bir nedeni var mı?
kidsid49

13

Heres Swift'te kapanışlarla nasıl yapılır:

func detectScreenShot(action: () -> ()) {
    let mainQueue = NSOperationQueue.mainQueue()
    NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationUserDidTakeScreenshotNotification, object: nil, queue: mainQueue) { notification in
        // executes after screenshot
        action()
    }
}

detectScreenShot { () -> () in
    print("User took a screen shot")
}

Hızlı 4.2

func detectScreenShot(action: @escaping () -> ()) {
    let mainQueue = OperationQueue.main
    NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: mainQueue) { notification in
        // executes after screenshot
        action()
    }
}

Bu standart bir işlev olarak dahil edilmiştir:

https://github.com/goktugyil/EZSwiftExtensions

Feragatname: Benim repo


Hey, bunu denedim ve harika çalıştı, ama kodda neler olduğunu biraz açıklayabilir misin? Swift'te yeniyim ve okumak biraz zor.
16:50

Bu onlardan biri, "eğer çalışırsa onunla uğraşmayın" tür kodlar. Bunun ne işe yaradığını öğrenmenize gerek yok çünkü burada kullanılan çerçeveler çok nadir.
Esqarrouth

Ancak, bu kısmı bilmiyorsanız, kapakların nasıl çalıştığını kontrol etmelisiniz, temel olarak ekran görüntüsü algılama işlevini çağırdığınızda, parantezlere koyduğunuz şey bir eylem işlevi olarak gönderilir
Esqarrouth

@Esqarrouth Bunu ana kuyrukta yapmanın belirli bir nedeni var mı?
kidsid49

Kopyalama hamurunun nedeni
Esqarrouth

4

En son SWIFT 3 :

func detectScreenShot(action: @escaping () -> ()) {
        let mainQueue = OperationQueue.main
        NotificationCenter.default.addObserver(forName: .UIApplicationUserDidTakeScreenshot, object: nil, queue: mainQueue) { notification in
            // executes after screenshot
            action()
        }
    }

In viewDidLoad , bu işlevi çağırmak

detectScreenShot { () -> () in
 print("User took a screen shot")
}

Ancak,

NotificationCenter.default.addObserver(self, selector: #selector(test), name: .UIApplicationUserDidTakeScreenshot, object: nil)

    func test() {
    //do stuff here
    }

tamamen iyi çalışıyor. MainQueue'nun hiçbir noktasını göremiyorum ...


Soru, ekran görüntüsü alınmadan önce nasıl bildirim alacağınızı sormaktır. Bu alındıktan sonra söyler .
rmaddy

1
@rmaddy Bu sorunun daha önce nasıl haberdar edileceğini sorduğunu nereden gördünüz? Sadece yukarıdaki cevabımı iyileştirdim, yorum niyetinizden emin değilim ..
Maksim Kniazev

Soru soruyor: "kullanıcının ekran görüntüsü aldığını tespit et" . OP bu olaydan sonra bilmek isterse, şu soru okunmalıdır: "kullanıcının ekran görüntüsü aldığını tespit et" .
rmaddy

1

Kullanıcıya dokunup dokunmadığını tespit etmek için bunu yapmanın doğrudan bir yolu yok gibi görünüyor home + power button. Gereğince bu , o darwin bildirimini kullanarak daha önce mümkündü, ama artık çalışmıyor. Snapchat zaten yaptığı için, tahminim, iPhone fotoğraf albümünü bu 10 saniye arasında yeni bir resim eklenmiş olup olmadığını tespit etmek için kontrol ediyorlar ve bir şekilde görüntülenen geçerli görüntü ile karşılaştırıyorlar. Bu karşılaştırma için bazı görüntü işlemleri yapılabilir. Sadece bir düşünce, muhtemelen işe yaraması için bunu genişletmeye çalışabilirsiniz. Daha fazla ayrıntı için bunu kontrol edin .

Düzenle:

Görünüşe göre UITouch iptal olayını tespit ediyor olabilirler (Ekran yakalama dokunuşları iptal eder) ve bu hata mesajını bu blog'a göre kullanıcıya gösterir: iOS'ta ekran görüntüleri nasıl algılanır (SnapChat gibi)

Bu durumda, bunu – touchesCancelled:withEvent:tespit etmek için UITouch iptalini algılamak için yöntemi kullanabilirsiniz . Bu temsilci yönteminde görüntüyü kaldırabilir ve kullanıcıya uygun bir uyarı gösterebilirsiniz.

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesCancelled:touches withEvent:event];

    NSLog(@"Touches cancelled");

    [self.imageView removeFromSuperView]; //and show an alert to the user
}

Bu konuda kesin bir cevap almak için doğru yerlere iyi bağlanmış görünüyorsunuz;)
smileyborg

Kesin bir cevaptan ziyade eğitimli bir tahmindir. Ne yazık ki bunun için kesin bir cevap almak için herhangi bir bağlantım yok. Herhangi bir özel API kullanmıyorlarsa, bunu yapmanın tek yolu budur. Albüme eklediğiniz görüntüyü algılamak ve bazı algoritmaya dayalı olarak bu görüntüyü ekrandaki geçerli görüntüyle karşılaştırmak için.
iDev

Ancak bunu, cihazın fotoğraflarına ve Film Rulosuna erişim istemeden yapabildikleri göz önüne alındığında ... başka bir şey olmalı mı? Teorim, alınan fotoğraf mesajını görüntülemek için sizi uzun süre bastırmaları ve Home + Lockdüğmelere bastığınızda işletim sisteminin hemen hiçbir parmak ekrana dokunmuyormuş gibi davranmasıyla ilgilidir. Belki touchesEnded:withEventde normalde olduğu gibi (veya benzer bir geri arama) olmadan olur, belki de bu benzersiz olay modelini izleyebilirler? Tamamen yanlış yolda olabilirim, ama bu noktada benim tek teorim bu.
smileyborg

Bir parmağınızı ekrana koyun ve kaldırmadan diğer iki düğmeye basıp basamayacağınızı deneyin. Sanırım hala bu mesajı gösteriyordu. Bu yüzden bazı özel API kullanıyor olabilirler ve bir şekilde uygulama mağazasına koymayı başarabilirler.
iDev

2
İOS 7'den itibaren artık mümkün değil.
God of Biscuits

1

Swift 4+

NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: OperationQueue.main) { notification in
           //you can do anything you want here. 
        }

Bu gözlemciyi kullanarak, kullanıcının ekran görüntüsü ne zaman aldığını öğrenebilirsiniz, ancak onu engelleyemezsiniz.


0

Swift 4 Örnekleri

Kapatma kullanarak örnek 1

NotificationCenter.default.addObserver(forName: .UIApplicationUserDidTakeScreenshot, 
                                       object: nil, 
                                       queue: OperationQueue.main) { notification in
    print("\(notification) that a screenshot was taken!")
}

Seçici ile örnek 2

NotificationCenter.default.addObserver(self, 
                                       selector: #selector(screenshotTaken), 
                                       name: .UIApplicationUserDidTakeScreenshot, 
                                       object: nil)

@objc func screenshotTaken() {
    print("Screenshot taken!")
}
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.