Uygulamanıza İstemci Tarafı Lisans Doğrulamasını Ekleme

Uyarı: Uygulamanız istemci tarafında lisans doğrulama işlemi gerçekleştirdiğinde, potansiyel saldırganların bu doğrulama işlemiyle ilişkilendirilen mantığı değiştirmesi veya kaldırması daha kolay olur.

Bu nedenle, bunun yerine sunucu tarafı lisans doğrulaması gerçekleştirmenizi önemle tavsiye ederiz.

Yayıncı hesabı ve geliştirme ortamı (Lisanslama Ayarlama bölümüne bakın) kurduktan sonra Lisans Doğrulama Kitaplığı (LVL) ile uygulamanıza lisans doğrulaması eklemeye hazırsınızdır.

LVL ile lisans doğrulaması eklemek şu görevleri içerir:

  1. Uygulamanızın manifest dosyasına lisanslama iznini ekleme.
  2. Politika Uygulama: LVL'de sağlanan eksiksiz uygulamalardan birini seçebilir veya kendi politikanızı oluşturabilirsiniz.
  3. Policy ürününüz lisans yanıt verilerini önbelleğe alacaksa Gizleyici Uygulama.
  4. Uygulamanızın ana Etkinliğinde lisansı kontrol etmek için kod ekleme.
  5. DeviceLimiter uygulama (isteğe bağlıdır ve çoğu uygulama için önerilmez).

Aşağıdaki bölümlerde bu görevler açıklanmaktadır. Entegrasyon tamamlandıktan sonra uygulamanızı başarılı bir şekilde derleyebilir ve Test Ortamını Ayarlama bölümünde açıklandığı gibi teste başlayabilirsiniz.

LVL'ye dahil edilen kaynak dosya grubunun tamamına genel bir bakış için LVL Sınıflarının ve Arayüzlerinin Özeti bölümüne bakın.

Lisanslama İzni Ekleme

Google Play uygulamasını sunucuya lisans kontrolü göndermek üzere kullanmak için uygulamanızın uygun izni (com.android.vending.CHECK_LICENSE) istemesi gerekir. Uygulamanız lisanslama iznini beyan etmez ancak bir lisans kontrolü başlatmaya çalışırsa LVL bir güvenlik istisnası atar.

Uygulamanızda lisanslama izni istemek için <uses-permission> öğesini aşağıdaki gibi <manifest> alt öğesi olarak tanımlayın:

<uses-permission android:name="com.android.vending.CHECK_LICENSE" />

Örneğin, LVL örnek uygulamasının izni nasıl beyan ettiği aşağıda açıklanmıştır:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...">
    <!-- Devices >= 3 have version of Google Play that supports licensing. -->
    <uses-sdk android:minSdkVersion="3" />
    <!-- Required permission to check licensing. -->
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
    ...
</manifest>

Not: SDK Araçları bu izni bağımlı uygulamaların manifest'leriyle birleştirmeyeceğinden şu anda LVL kitaplığı projesinin manifest dosyasında CHECK_LICENSE iznini beyan edemezsiniz. Bunun yerine, her bağımlı uygulamanın manifest dosyasında izni beyan etmeniz gerekir.

Politika Uygulama

Google Play lisanslama hizmeti, belirli bir lisansa sahip belirli bir kullanıcıya uygulamanıza erişim izni verilip verilmeyeceğini belirlemez. Bu sorumluluk, başvurunuzda sağladığınız bir Policy uygulamasına bırakılır.

Politika, LVL tarafından beyan edilen ve lisans kontrolünün sonucuna göre uygulamanızın kullanıcı erişimine izin verme veya vermeme mantığını tutmak için tasarlanmış bir arayüzdür. LVL'yi kullanmak için uygulamanızın Policy uygulaması sağlaması gerekir.

Policy arayüzünde iki yöntem tanımlar: allowAccess() ve processServerResponse(). Bu yöntemler, lisans sunucusundan alınan bir yanıtı işlerken LicenseChecker örneği tarafından çağrılır. Ayrıca LicenseResponse adında, processServerResponse() çağrılarında geçirilen lisans yanıtı değerini belirten bir enum tanımlar.

  • processServerResponse(), erişim izni verip vermeyeceğinizi belirlemeden önce lisanslama sunucusundan alınan ham yanıt verilerini önceden işlemenize olanak tanır.

    Tipik bir uygulamada, verilerin uygulama çağrıları ve cihaz açma döngülerinde erişilebilir olmasını sağlamak için verilerin bir kısmı veya tamamı lisans yanıtından alınır ve veriler SharedPreferences depolama alanı gibi kalıcı bir depolama alanında yerel olarak depolanır. Örneğin, Policy, uygulama her başlatıldığında değerleri sıfırlamak yerine kalıcı bir depodaki son başarılı lisans kontrolünün zaman damgasını, yeniden deneme sayısını, lisans geçerlilik süresini ve benzer bilgileri korur.

    Yanıt verilerini yerel olarak depolarken Policy, verilerde karartma yapıldığından emin olmalıdır (aşağıdaki Gizleyici Uygulama bölümüne bakın).

  • allowAccess(), mevcut lisans yanıtı verilerine (lisanslama sunucusundan veya önbellekten) ya da uygulamaya özgü diğer bilgilere göre kullanıcıya uygulamanıza erişim izni verilip verilmeyeceğini belirler. Örneğin, allowAccess() uygulamanızda kullanım veya bir arka uç sunucusundan alınan diğer veriler gibi ek ölçütler dikkate alınabilir. Her durumda, allowAccess() uygulanması yalnızca kullanıcının uygulamayı kullanma lisansı varsa (lisanslama sunucusu tarafından belirlendiği şekilde veya lisans kontrolünün tamamlanmasını engelleyen geçici bir ağ ya da sistem sorunu varsa) true döndürmelidir. Bu tür durumlarda, uygulamanız, yeniden deneme yanıtlarının sayısını saklayabilir ve bir sonraki lisans kontrolü tamamlanana kadar geçici olarak erişim izni verebilir.

Uygulamanıza lisans ekleme sürecini basitleştirmek ve bir Policy öğesinin nasıl tasarlanması gerektiğine dair bir örnek sunmasını sağlamak için LVL, değişiklik yapmadan veya ihtiyaçlarınıza uyarlamadan kullanabileceğiniz iki tam Policy uygulaması içerir:

  • Farklı ağ koşullarında erişimi yönetmek için sunucu tarafından sağlanan ayarları ve önbelleğe alınmış yanıtları kullanan esnek bir Policy olan ServerManagedPolicy ve
  • Yanıt verilerini önbelleğe almayan ve yalnızca sunucu lisanslı bir yanıt döndürdüğünde erişim izni veren StrictPolicy.

Çoğu uygulamada ServerManagedPolicy kullanılması önemle tavsiye edilir. ServerManagedPolicy, LVL varsayılanıdır ve LVL örnek uygulamasıyla entegre edilmiştir.

Özel politikalarla ilgili kurallar

Lisanslama uygulamanızda, LVL'de sağlanan tüm politikaların tamamını (ServerManagedPolicy veya StrictPolicy) kullanabilir veya özel politika oluşturabilirsiniz. Herhangi bir özel politika türü için, uygulamanızda anlaşılması ve hesaba katılması gereken birkaç önemli tasarım noktası vardır.

Lisans sunucusu, hizmet reddine yol açabilecek kaynakların aşırı kullanımına karşı koruma sağlamak için genel istek sınırları uygular. Bir uygulama istek sınırını aştığında, lisanslama sunucusu 503 yanıtı döndürür ve bu yanıt genel sunucu hatası olarak uygulamanıza aktarılır. Bu durumda, sınır sıfırlanana kadar kullanıcı lisans yanıtı alamaz. Bu durum kullanıcıyı süresiz olarak etkileyebilir.

Özel bir politika tasarlıyorsanız Policy:

  1. Yerel kalıcı depolama alanındaki en son başarılı lisans yanıtını önbelleğe alır (ve düzgün bir şekilde gizler).
  2. Lisanslama sunucusuna istek göndermek yerine, önbelleğe alınan yanıt geçerli olduğu sürece tüm lisans kontrolleri için önbelleğe alınan yanıtı döndürür. Yanıt geçerliliğini sunucu tarafından sağlanan ekstra VT değerine göre ayarlamanız önemle tavsiye edilir. Daha fazla bilgi için Sunucu Yanıtı Ekstraları konusuna bakın.
  3. Bir isteğin yeniden denenmesi hatayla sonuçlanırsa üstel bir geri yükleme aralığı kullanır. Google Play istemcisinin başarısız istekleri otomatik olarak yeniden denediğini unutmayın. Bu nedenle, çoğu durumda Policy tarafından yeniden deneme yapılmasına gerek yoktur.
  4. Lisans kontrolünün yeniden denendiği sırada kullanıcının, sınırlı bir süre veya sınırlı sayıda kullanım için uygulamanıza erişmesine izin veren bir "ek süre" sağlar. Ek süre, bir sonraki lisans kontrolü başarıyla tamamlanana kadar erişim izni vererek kullanıcıya fayda sağlar ve geçerli bir lisans yanıtı olmadığında uygulamanıza erişim konusunda kesin bir sınır uygular.

Policy cihazınızı yukarıda listelenen yönergelere göre tasarlamak son derece önemlidir. Çünkü bu, hata koşullarında bile uygulamanız üzerinde etkili bir kontrol sağlarken kullanıcılar için mümkün olan en iyi deneyimi sağlar.

Lisanslama sunucusu tarafından sağlanan ayarları kullanarak geçerliliği ve önbelleğe almayı, yeniden deneme süresini ve diğer işlemleri Policy kullanabilirsiniz. Sunucu tarafından sağlanan ayarları çıkarmak kolaydır ve bu ayarların kullanılması kesinlikle önerilir. Ekstraların nasıl ayıklanacağı ve kullanılacağına ilişkin bir örnek için ServerManagedPolicy uygulamasını inceleyin. Sunucu ayarlarının bir listesi ve bunların nasıl kullanılacağıyla ilgili bilgiler için Sunucu Yanıtı Ekstraları bölümüne bakın.

Sunucu Yönetilen Politikası

LVL, ServerManagedPolicy adı verilen tam ve önerilen Policy arayüzü uygulamasını içerir. Uygulama, LVL sınıflarıyla entegre edilmiştir ve kitaplıkta varsayılan Policy görevi görür.

ServerManagedPolicy, lisans ve yeniden deneme yanıtları için tüm işlemleri sağlar. Bir SharedPreferences dosyasında tüm yanıt verilerini yerel olarak önbelleğe alır ve uygulamanın Obfuscator uygulamasıyla verileri karartır. Bu, lisans yanıtı verilerinin güvende olmasını ve cihazın açma/kapatma döngüleri boyunca değişmesini sağlar. ServerManagedPolicy, processServerResponse() ve allowAccess() arayüz yöntemlerinin somut uygulamalarının yanı sıra lisans yanıtlarını yönetmek için bir dizi destekleyici yöntem ve tür içerir.

ServerManagedPolicy'nin önemli bir özelliği, bir uygulamanın geri ödeme süresi boyunca ve değişen ağ ve hata koşulları üzerinden lisanslamayı yönetmek için temel olarak sunucu tarafından sağlanan ayarları kullanmasıdır. Bir uygulama lisans kontrolü için Google Play sunucusuyla iletişim kurduğunda sunucu, belirli lisans yanıt türlerinin ekstralar alanına anahtar/değer çiftleri olarak çeşitli ayarlar ekler. Örneğin sunucu; uygulamanın lisans geçerlilik süresi, yeniden deneme ek süresi ve izin verilen maksimum yeniden deneme sayısı için önerilen değerleri sağlar. ServerManagedPolicy, processServerResponse() yönteminde lisans yanıtından değerleri ayıklar ve allowAccess() yönteminde kontrol eder. ServerManagedPolicy tarafından kullanılan, sunucu tarafından sağlanan ayarların listesi için Sunucu Yanıtı Ekstraları bölümüne bakın.

Kolaylık, en iyi performans ve Google Play sunucusundaki lisans ayarlarını kullanmanın avantajı açısından lisanslama Policy olarak ServerManagedPolicy'yi kullanmanız önemle tavsiye edilir.

SharedPreferences bölgesinde yerel olarak depolanan lisans yanıtı verilerinin güvenliğiyle ilgili endişeleriniz varsa daha güçlü bir kod karartma algoritması kullanabilir veya lisans verilerini depolamayan daha katı bir Policy tasarlayabilirsiniz. LVL, böyle bir Policy örneğini içerir. Daha fazla bilgi için StrictPolicy'yi inceleyin.

ServerManagedPolicy'yi kullanmak için bunu Etkinliğinize içe aktarmanız, bir örnek oluşturmanız ve LicenseChecker oluşturduğunuz sırada örneğe referans iletmeniz yeterlidir. Daha fazla bilgi için LisansChecker ve LicenseCheckerCallback Oluşturma konusuna bakın.

Katı Politikası

LVL, Policy arayüzünün StrictPolicy adı verilen alternatif bir tam uygulamasını içerir. StrictPolicy uygulaması, ServerManagedPolicy'den daha kısıtlayıcı bir Politika sağlar. Zira erişim sırasında sunucudan kullanıcının lisanslı olduğunu belirten bir lisans yanıtı alınmadığı sürece kullanıcının uygulamaya erişmesine izin verilmez.

StrictPolicy'nin temel özelliği, hiçbir lisans yanıt verisini kalıcı bir depoda yerel olarak depolamamasıdır. Hiçbir veri depolanmadığından yeniden deneme istekleri izlenmez ve önbelleğe alınan yanıtlar, lisans kontrollerini gerçekleştirmek için kullanılamaz. Policy, yalnızca aşağıdaki durumlarda erişime izin verir:

  • Lisans yanıtı, lisanslama sunucusundan alınır ve
  • Lisans yanıtı, kullanıcının uygulamaya erişim lisansı olduğunu gösterir.

Asıl endişeniz, kullanım sırasında kullanıcının lisans sahibi olduğu onaylanmadığı sürece, hiçbir kullanıcının uygulamaya erişmesine izin verilmemesini sağlamaksa StrictPolicy uygun olabilir. Ayrıca Politika, ServerManagedPolicy'den biraz daha güvenlik sunar. Yerel olarak önbelleğe alınan veri olmadığından, kötü amaçlı bir kullanıcının önbelleğe alınan veriler üzerinde oynaması ve uygulamaya erişmesi mümkün değildir.

Aynı zamanda, bu Policy normal kullanıcılar için bir zorluk oluşturur. Bunun nedeni, kullanıcıların ağ (hücre veya kablosuz) bağlantısı olmadığında uygulamaya erişemeyecekleri anlamına gelir. Diğer bir yan etki de, önbelleğe alınmış yanıt kullanmak mümkün olmadığından uygulamanızın sunucuya daha fazla lisans kontrolü isteği göndermesidir.

Genel olarak bu politika, mutlak güvenlik ve erişim üzerinde kontrol sağlamak için bir dereceye kadar kullanıcı rahatlığından ödün vermeyi temsil eder. Bu Policy aracını kullanmadan önce dengeyi dikkatlice düşünün.

StrictPolicy'yi kullanmak için bunu Etkinliğinize içe aktarmanız, bir örnek oluşturmanız ve LicenseChecker uygulamanızı oluştururken buna bir referans aktarmanız yeterlidir. Daha fazla bilgi için LisansChecker ve LicenseCheckerCallback örneğini inceleyin.

Tipik bir Policy uygulaması, bir uygulamanın lisans yanıtı verilerini kalıcı bir mağazaya kaydederek uygulama çağrıları ve cihaz açma döngülerinde erişilebilir. Örneğin, Policy, uygulama her başlatıldığında değerleri sıfırlamak yerine kalıcı bir depodaki son başarılı lisans kontrolünün zaman damgasını, yeniden deneme sayısını, lisansın geçerlilik süresini ve benzer bilgileri korur. ServerManagedPolicy'de LVL'ye dahil edilen varsayılan Policy, verilerin kalıcı olmasını sağlamak için lisans yanıt verilerini SharedPreferences örneğinde depolar.

Policy, uygulamaya erişime izin verilip verilmeyeceğini belirlemek için depolanan lisans yanıtı verilerini kullanacağından, depolanan verilerin güvenli olduğundan ve bir cihazda kök kullanıcı tarafından yeniden kullanılamayacağından ya da değiştirilemeyeceğinden emin olmak gerekir. Özellikle, Policy uygulama ve cihaz için benzersiz bir anahtar kullanarak verileri saklamadan önce her zaman karartmalıdır. Hem uygulamaya hem de cihaza özgü bir anahtar kullanarak karartmak, kodu karartılan verilerin uygulamalar ve cihazlar arasında paylaşılmasını önlediği için son derece önemlidir.

LVL, uygulamanın lisans yanıt verilerini güvenli ve kalıcı bir şekilde depolamasına yardımcı olur. Öncelikle uygulamanızın depolanan veriler için seçtiği kod karartma algoritmasını sağlamasına olanak tanıyan bir Obfuscator arayüzü sağlar. Bunun üzerine LVL, uygulamanın Obfuscator sınıfını çağırma ve karartılmış verileri SharedPreferences örneğinde okuma ve yazma işlerinin çoğunu yerine getiren yardımcı sınıf PreferenceObfuscator'ı sağlar.

LVL, verilerin kodunu karartmak için AES şifrelemesini kullanan ve AESObfuscator adı verilen tam bir Obfuscator uygulaması sunar. AESObfuscator'ı uygulamanızda değişiklik yapmadan kullanabilir veya ihtiyaçlarınıza göre uyarlayabilirsiniz. Lisans yanıt verilerini önbelleğe alan bir Policy (ServerManagedPolicy gibi) kullanıyorsanız Obfuscator uygulamanız için temel olarak AESObfuscator'ı kullanmanız önemle tavsiye edilir. Daha fazla bilgi edinmek için sonraki bölüme bakın.

AESObfuscator

LVL, AESObfuscator adı verilen tam ve önerilen bir Obfuscator arayüzü uygulamasını içerir. Uygulama, LVL örnek uygulamasıyla entegre edilir ve kitaplıkta varsayılan Obfuscator işlevi görür.

AESObfuscator, veri depolama alanına yazılırken veya okunurken verileri şifrelemek ve şifrelerini çözmek için AES'yi kullanarak verilerde güvenli bir şekilde kod karartma işlemi sağlar. Obfuscator, uygulama tarafından sağlanan üç veri alanını kullanarak şifrelemeyi başlatır:

  1. Salt; her bir kod karartma (kaldırma) için kullanılacak rastgele bayt dizisidir.
  2. Bir uygulama tanımlayıcısı dizesidir. Bu dize genellikle uygulamanın paket adıdır.
  3. Benzersiz olmasını sağlamak için cihaza özel mümkün olduğunca çok kaynaktan türetilen bir cihaz tanımlayıcı dizesi.

AESObfuscator'ı kullanmak için öncelikle Etkinliğinize aktarın. Salt baytları barındıracak özel bir statik son dizi tanımlayın ve bunu rastgele oluşturulmuş 20 bayt olarak başlatın.

Kotlin

// Generate 20 random bytes, and put them here.
private val SALT = byteArrayOf(
        -46, 65, 30, -128, -103, -57, 74, -64, 51, 88,
        -95, -45, 77, -117, -36, -113, -11, 32, -64, 89
)

Java

...
    // Generate 20 random bytes, and put them here.
    private static final byte[] SALT = new byte[] {
     -46, 65, 30, -128, -103, -57, 74, -64, 51, 88, -95,
     -45, 77, -117, -36, -113, -11, 32, -64, 89
     };
    ...

Ardından, cihaz tanımlayıcısını barındıracak bir değişken tanımlayın ve bunun için gereken herhangi bir şekilde bir değer oluşturun. Örneğin, LVL'ye dahil edilen örnek uygulama, her cihaza özgü olan android.Settings.Secure.ANDROID_ID sistem ayarlarını sorgular.

Kullandığınız API'lere bağlı olarak, uygulamanızın cihaza özel bilgileri edinmek için ek izinler istemesi gerekebileceğini unutmayın. Örneğin, cihazın IMEI'sini veya ilgili verileri almak amacıyla TelephonyManager öğesini sorgulamak için uygulamanın, manifest dosyasında android.permission.READ_PHONE_STATE iznini de istemesi gerekir.

Obfuscator cihazınızda kullanmak üzere cihaza özel bilgiler edinme amacıyla yeni izinler istemeden önce, bu işlemin uygulamanızı veya Google Play'deki filtrelemesini nasıl etkileyebileceğini göz önünde bulundurun (çünkü bazı izinler, SDK derleme araçlarının, ilişkili <uses-feature> öğesini eklemesine neden olabilir).

Son olarak takviye değer, uygulama tanımlayıcısı ve cihaz tanımlayıcısını ileterek bir AESObfuscator örneği oluşturun. Policy ve LicenseChecker oluştururken örneği doğrudan oluşturabilirsiniz. Örneğin:

Kotlin

    ...
    // Construct the LicenseChecker with a Policy.
    private val checker = LicenseChecker(
            this,
            ServerManagedPolicy(this, AESObfuscator(SALT, packageName, deviceId)),
            BASE64_PUBLIC_KEY
    )
    ...

Java

    ...
    // Construct the LicenseChecker with a Policy.
    checker = new LicenseChecker(
        this, new ServerManagedPolicy(this,
            new AESObfuscator(SALT, getPackageName(), deviceId)),
        BASE64_PUBLIC_KEY // Your public licensing key.
        );
    ...

Tam bir örnek için LVL örnek uygulamasındaki MainActivity bölümüne bakın.

Bir Etkinlikten Lisansı Kontrol Etme

Uygulamanıza erişimi yönetmek için bir Policy uyguladıktan sonraki adım uygulamanıza bir lisans denetimi eklemektir. Bu kontrol, gerektiğinde lisanslama sunucusuna bir sorgu başlatır ve uygulamaya erişimi lisans yanıtına göre yönetir. Lisans kontrolünü ekleme ve yanıtı işleme süreci, ana Activity kaynak dosyanızda gerçekleşir.

Lisans kontrolünü eklemek ve yanıtı işlemek için şunları yapmanız gerekir:

  1. İçe aktarma işlemi ekleme
  2. LisansCheckerCallback'i özel bir iç sınıf olarak uygulayın
  3. LicenseCheckerCallback'ten kullanıcı arayüzü ileti dizisine yayınlamak için bir İşleyici oluşturun
  4. LisansChecker ve LicenseCheckerCallback Örneği
  5. Lisans kontrolünü başlatmak için checkAccess() işlevini çağırın.
  6. Lisanslama için ortak anahtarınızı yerleştirme
  7. IPC bağlantılarını kapatmak için LicenseChecker'ın onDestroy() yöntemini çağırın.

Aşağıdaki bölümlerde bu görevler açıklanmaktadır.

Lisans kontrolüne ve yanıtına genel bakış

Çoğu durumda, lisans kontrolünü onCreate() yöntemi ile uygulamanızın ana Activity bölümüne eklemeniz gerekir. Böylece, kullanıcı uygulamanızı doğrudan başlattığında lisans kontrolünün hemen çağrılmasını sağlar. Bazı durumlarda, lisans kontrollerini başka konumlara da ekleyebilirsiniz. Örneğin, uygulamanız, diğer uygulamaların Intent tarihine kadar başlatabileceği birden fazla Etkinlik bileşeni içeriyorsa bu Etkinliklere lisans kontrolleri ekleyebilirsiniz.

Lisans denetimi iki ana işlemden oluşur:

  • Lisans kontrolünü başlatmak için bir yöntem çağrısıdır. LVL'de bu, oluşturduğunuz LicenseChecker nesnesinin checkAccess() yöntemine yapılan bir çağrıdır.
  • Lisans kontrolünün sonucunu döndüren bir geri arama. LVL'de bu, uyguladığınız bir LicenseCheckerCallback arayüzüdür. Arayüzde, lisans kontrolünün sonucuna göre kitaplık tarafından çağrılan allow() ve dontAllow() olmak üzere iki yöntem tanımlanır. Bu iki yöntemi, kullanıcıların uygulamanıza erişmesine izin vermek veya vermemek için ihtiyacınız olan mantığı kullanarak uygularsınız. Bu yöntemlerin erişime izin verilip verilmeyeceğini belirlemediğini unutmayın. Bu belirleme, Policy uygulamanızın sorumluluğundadır. Aksine bu yöntemler, erişime izin verme ve vermeme (ve uygulama hatalarını işleme) ile ilgili uygulama davranışlarını sağlar.

    allow() ve dontAllow() yöntemleri, yanıtları için bir "neden" sağlar. Bu, Policy değerlerinden biri, LICENSED, NOT_LICENSED ya da RETRY olabilir. Özellikle, yöntemin dontAllow() için RETRY yanıtını aldığı bir durumu ele almanız ve kullanıcıya bir "Yeniden dene" düğmesi sağlamanız gerekir. Bu durum, hizmet istek sırasında kullanılamaması nedeniyle oluşmuş olabilir.

Şekil 1. Tipik bir lisans kontrolü etkileşimine genel bakış.

Yukarıdaki şemada, tipik bir lisans kontrolünün nasıl yapıldığı gösterilmektedir:

  1. Uygulamanın ana Etkinliğindeki kod, LicenseCheckerCallback ve LicenseChecker nesnelerini örneklendirir. LicenseChecker oluşturulurken kod Context, kullanılacak bir Policy uygulaması ve lisanslama için parametre olarak yayıncı hesabının ortak anahtarı geçer.
  2. Daha sonra kod, LicenseChecker nesnesinde checkAccess() yöntemini çağırır. Yöntem uygulaması, SharedPreferences içinde yerel olarak önbelleğe alınmış geçerli bir lisans yanıtı olup olmadığını belirlemek için Policy yöntemini çağırır.
    • Bu durumda checkAccess() uygulaması allow() yöntemini çağırır.
    • Aksi takdirde LicenseChecker, lisanslama sunucusuna gönderilen bir lisans kontrolü isteği başlatır.

    Not: Bir taslak uygulamanın lisans kontrolü gerçekleştirdiğinizde lisanslama sunucusu her zaman LICENSED hatasını döndürür.

  3. Yanıt alındığında LicenseChecker, imzalanmış lisans verilerini doğrulayan bir LicenseValidator oluşturur, ardından yanıt alanlarını çıkarır, ardından bunları ayrıntılı değerlendirme için Policy uygulamanıza iletir.
    • Lisans geçerliyse Policy, yanıtı SharedPreferences içinde önbelleğe alır ve doğrulayıcıya bildirir. Daha sonra, doğrulayıcı LicenseCheckerCallback nesnesinde allow() yöntemini çağırır.
    • Lisans geçerli değilse Policy, doğrulayıcıya bildirim gönderir. Doğrulayıcı, LicenseCheckerCallback üzerinde dontAllow() yöntemini çağırır.
  4. Ağın isteği göndermek için uygun olmaması gibi durumlarda, kurtarılabilir bir yerel hata veya sunucu hatası olması durumunda LicenseChecker, Policy nesnenizin processServerResponse() yöntemine RETRY yanıtı iletir.

    Ayrıca hem allow() hem de dontAllow() geri çağırma yöntemleri bir reason bağımsız değişkeni alır. allow() yönteminin nedeni genellikle Policy.LICENSED veya Policy.RETRY, dontAllow() nedeni ise genellikle Policy.NOT_LICENSED veya Policy.RETRY olur. Bu yanıt değerleri kullanıcıya uygun bir yanıt göstermeniz açısından yararlıdır. Örneğin, dontAllow() Policy.RETRY ile yanıt verdiğinde bir "Yeniden dene" düğmesi sağlayabilirsiniz. Bu durum, hizmetin kullanılamadığından kaynaklanmış olabilir.

  5. Uygulamanın, geçersiz bir paket adının lisansını kontrol etmeye çalışması gibi bir uygulama hatası durumunda, LicenseChecker, LicenseCheckerCallback'in applicationError() yöntemine bir hata yanıtı gönderir.

Aşağıdaki bölümlerde açıklanan lisans kontrolünü başlatmaya ve sonucu işlemeye ek olarak, uygulamanızın bir Politika uygulaması ve Policy, yanıt verilerini (ör. ServerManagedPolicy) saklıyorsa bir Obfuscator uygulaması da sağlaması gerektiğini unutmayın.

İçe aktarma işlemi ekle

İlk olarak, uygulamanın ana etkinliğinin sınıf dosyasını açın ve LVL paketinden LicenseChecker ve LicenseCheckerCallback öğelerini içe aktarın.

Kotlin

import com.google.android.vending.licensing.LicenseChecker
import com.google.android.vending.licensing.LicenseCheckerCallback

Java

import com.google.android.vending.licensing.LicenseChecker;
import com.google.android.vending.licensing.LicenseCheckerCallback;

LVL (ServerManagedPolicy) ile sağlanan varsayılan Policy uygulamasını kullanıyorsanız bunu da AESObfuscator ile birlikte içe aktarın. Özel bir Policy veya Obfuscator kullanıyorsanız onun yerine bunları içe aktarın.

Kotlin

import com.google.android.vending.licensing.ServerManagedPolicy
import com.google.android.vending.licensing.AESObfuscator

Java

import com.google.android.vending.licensing.ServerManagedPolicy;
import com.google.android.vending.licensing.AESObfuscator;

LicenseCheckerCallback'i gizli bir iç sınıf olarak uygulama

LicenseCheckerCallback, lisans kontrolünün sonucunu yürütmek için LVL tarafından sağlanan bir arayüzdür. LVL kullanarak lisanslamayı desteklemek için LicenseCheckerCallback uygulamasını ve uygulamaya erişime izin verme veya vermeme yöntemlerini uygulamanız gerekir.

Lisans kontrolünün sonucunda her zaman yanıt yükünün, sunucu yanıt kodunun ve Policy tarafından sağlanan ek işlemlerin doğrulanmasına dayalı olarak yapılan LicenseCheckerCallback yöntemlerinden birine çağrı yapılır. Uygulamanız, bu yöntemleri gereken herhangi bir şekilde uygulayabilir. Genel olarak en iyi yöntem, yöntemleri basit tutmak ve yalnızca kullanıcı arayüzü durumunu ve uygulama erişimini yönetmekle sınırlı tutmaktır. Bir arka uç sunucusuyla iletişim kurarak veya özel kısıtlamalar uygulayarak lisans yanıtlarının daha fazla işlenmesini istiyorsanız bu kodu LicenseCheckerCallback yöntemlerine yerleştirmek yerine Policy ile birleştirmeyi düşünmelisiniz.

Çoğu durumda, LicenseCheckerCallback uygulamanızı uygulamanızın ana Etkinlik sınıfı içinde özel bir sınıf olarak beyan etmeniz gerekir.

allow() ve dontAllow() yöntemlerini gerektiği gibi uygulayın. Öncelikle, yöntemlerde lisans sonucunu bir iletişim kutusunda görüntüleme gibi basit sonuç işleme davranışlarını kullanabilirsiniz. Bu sayede uygulamanızı daha kısa sürede çalıştırabilir ve hata ayıklamaya yardımcı olabilirsiniz. Daha sonra, tam olarak istediğiniz davranışları belirledikten sonra daha karmaşık bir işleme ekleyebilirsiniz.

dontAllow() ürününde lisanssız yanıtların ele alınmasıyla ilgili bazı öneriler:

  • Kullanıcıya, sağlanan reason Policy.RETRY ise yeni lisans kontrolü başlatacak bir düğmenin yer aldığı "Tekrar dene" iletişim kutusunu görüntüleyin.
  • Kullanıcının, uygulamayı satın alabileceği Google Play'deki ayrıntılar sayfasına derin bağlantı içeren bir düğmenin bulunduğu"Bu uygulamayı satın al" iletişim kutusunu görüntüleyin. Bu tür bağlantıları nasıl oluşturacağınız hakkında daha fazla bilgi için Ürünlerinize Bağlantı Oluşturma bölümünü inceleyin.
  • Uygulama lisanslı olmadığı için uygulama özelliklerinin sınırlandığını belirten bir Durum Bilgisi bildirimi görüntüleyin.

Aşağıdaki örnekte LVL örnek uygulamasının, lisans denetimi sonucunu bir iletişim kutusunda gösteren yöntemlerle LicenseCheckerCallback özelliğini nasıl uyguladığı gösterilmektedir.

Kotlin

private inner class MyLicenseCheckerCallback : LicenseCheckerCallback {

    override fun allow(reason: Int) {
        if (isFinishing) {
            // Don't update UI if Activity is finishing.
            return
        }
        // Should allow user access.
        displayResult(getString(R.string.allow))
    }

    override fun dontAllow(reason: Int) {
        if (isFinishing) {
            // Don't update UI if Activity is finishing.
            return
        }
        displayResult(getString(R.string.dont_allow))

        if (reason == Policy.RETRY) {
            // If the reason received from the policy is RETRY, it was probably
            // due to a loss of connection with the service, so we should give the
            // user a chance to retry. So show a dialog to retry.
            showDialog(DIALOG_RETRY)
        } else {
            // Otherwise, the user isn't licensed to use this app.
            // Your response should always inform the user that the application
            // isn't licensed, but your behavior at that point can vary. You might
            // provide the user a limited access version of your app or you can
            // take them to Google Play to purchase the app.
            showDialog(DIALOG_GOTOMARKET)
        }
    }
}

Java

private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
    public void allow(int reason) {
        if (isFinishing()) {
            // Don't update UI if Activity is finishing.
            return;
        }
        // Should allow user access.
        displayResult(getString(R.string.allow));
    }

    public void dontAllow(int reason) {
        if (isFinishing()) {
            // Don't update UI if Activity is finishing.
            return;
        }
        displayResult(getString(R.string.dont_allow));

        if (reason == Policy.RETRY) {
            // If the reason received from the policy is RETRY, it was probably
            // due to a loss of connection with the service, so we should give the
            // user a chance to retry. So show a dialog to retry.
            showDialog(DIALOG_RETRY);
        } else {
            // Otherwise, the user isn't licensed to use this app.
            // Your response should always inform the user that the application
            // isn't licensed, but your behavior at that point can vary. You might
            // provide the user a limited access version of your app or you can
            // take them to Google Play to purchase the app.
            showDialog(DIALOG_GOTOMARKET);
        }
    }
}

Ek olarak, uygulamanızın yeniden denenilemeyen hataları işlemesi için LVL'nin çağırdığı applicationError() yöntemini uygulamanız gerekir. Bu tür hataların listesi için Lisanslama Referansı'ndaki Sunucu Yanıt Kodları'na bakın. Bu yöntemi gereken herhangi bir şekilde uygulayabilirsiniz. Çoğu durumda yöntem hata kodunu günlüğe kaydedip dontAllow() yöntemini çağırır.

LicenseCheckerCallback'ten UI iş parçacığına yayınlamak için bir İşleyici oluşturun

Lisans kontrolü sırasında LVL, isteği lisanslama sunucusuyla iletişimi gerçekleştiren Google Play uygulamasına iletir. LVL, isteği eşzamansız IPC üzerinden iletir (Binder kullanarak). Böylece, gerçek işleme ve ağ iletişimi, uygulamanız tarafından yönetilen bir iş parçacığında gerçekleşmez. Benzer şekilde, Google Play uygulaması sonucu aldığında IPC üzerinden bir geri çağırma yöntemini çağırır ve bu yöntem, uygulamanızın işlemindeki bir IPC iş parçacığı havuzunda yürütülür.

LicenseChecker sınıfı, isteği gönderen çağrı ve yanıtı alan geri çağırma da dahil olmak üzere uygulamanızın Google Play uygulamasıyla IPC iletişimini yönetir. LicenseChecker ayrıca açık lisans isteklerini takip eder ve bunların zaman aşımlarını yönetir.

LicenseChecker, zaman aşımlarını düzgün bir şekilde yönetebilmesi ve gelen yanıtları uygulamanızın kullanıcı arayüzü iş parçacığını etkilemeden işleyebilmesi için, örneklendirme sırasında bir arka plan iş parçacığı oluşturur. İş parçacığında, sonucun sunucudan alınan bir yanıt veya zaman aşımı hatası olmasına bakılmaksızın tüm lisans kontrolü sonuçlarını işleme alır. İşleme tamamlandığında LVL, arka plan iş parçacığından LicenseCheckerCallback yöntemlerinizi çağırır.

Uygulamanız için bu şu anlama gelir:

  1. LicenseCheckerCallback yöntemleriniz, çoğu durumda bir arka plan iş parçacığından çağrılır.
  2. Bu yöntemler, kullanıcı arayüzü iş parçacığında bir İşleyici oluşturmadığınız ve geri çağırma yöntemlerinizin İşleyici'ye gönderilmesini sağlamadığınız sürece, durumu güncelleyemez veya kullanıcı arayüzü iş parçacığındaki herhangi bir işlemi çağıramaz.

LicenseCheckerCallback yöntemlerinizin kullanıcı arayüzü iş parçacığını güncellemesini istiyorsanız ana Etkinlik'in onCreate() yönteminde aşağıda gösterildiği gibi bir Handler örneği oluşturun. Bu örnekte, LVL örnek uygulamasının LicenseCheckerCallback yöntemleri (yukarıya bakın) İşleyici'nin post() yöntemiyle kullanıcı arayüzü iş parçacığını güncellemek için displayResult() yöntemini çağırır.

Kotlin

    private lateinit var handler: Handler

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        handler = Handler()
    }

Java

    private Handler handler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        handler = new Handler();
    }

Ardından, LicenseCheckerCallback yöntemlerinizde İşleyici yöntemlerini kullanarak İşleyici'ye Çalıştırılabilir veya Mesaj nesnelerini gönderebilirsiniz. LVL'de yer alan örnek uygulamanın, lisans durumunu görüntülemek için UI iş parçacığında bir İşleyiciye Çalıştırılabilir'i şu şekilde yayınlar.

Kotlin

private fun displayResult(result: String) {
    handler.post {
        statusText.text = result
        setProgressBarIndeterminateVisibility(false)
        checkLicenseButton.isEnabled = true
    }
}

Java

private void displayResult(final String result) {
        handler.post(new Runnable() {
            public void run() {
                statusText.setText(result);
                setProgressBarIndeterminateVisibility(false);
                checkLicenseButton.setEnabled(true);
            }
        });
    }

LicenseChecker ve LicenseCheckerCallback'i örnekleme

Ana Etkinlik'in onCreate() yönteminde LicenseCheckerCallback ve LicenseChecker'nin gizli örneklerini oluşturun. LicenseChecker için oluşturucuyu çağırırken söz konusu örneğe bir referans iletmeniz gerektiğinden önce LicenseCheckerCallback öğesini çalıştırmanız gerekir.

LicenseChecker örneğini örneklediğinizde şu parametreleri aktarmanız gerekir:

  • Context uygulaması
  • Lisans kontrolü için kullanılacak Policy uygulamasına referans. Çoğu durumda, LVL tarafından sağlanan varsayılan Policy uygulamasını (ServerManagedPolicy) kullanırsınız.
  • Lisanslama için yayıncı hesabınızın ortak anahtarını barındıran Dize değişkeni.

ServerManagedPolicy kullanıyorsanız sınıfa doğrudan erişmeniz gerekmez. Bu nedenle, aşağıdaki örnekte gösterildiği gibi LicenseChecker oluşturucuda örnek oluşturabilirsiniz. ServerManagedPolicy oluştururken yeni bir Obfuscator örneğine referans aktarmanız gerektiğini unutmayın.

Aşağıdaki örnekte, bir Etkinlik sınıfının onCreate() yönteminden LicenseChecker ve LicenseCheckerCallback örneklendirmesi gösterilmektedir.

Kotlin

class MainActivity : AppCompatActivity() {
    ...
    private lateinit var licenseCheckerCallback: LicenseCheckerCallback
    private lateinit var checker: LicenseChecker

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // Construct the LicenseCheckerCallback. The library calls this when done.
        licenseCheckerCallback = MyLicenseCheckerCallback()

        // Construct the LicenseChecker with a Policy.
        checker = LicenseChecker(
                this,
                ServerManagedPolicy(this, AESObfuscator(SALT, packageName, deviceId)),
                BASE64_PUBLIC_KEY // Your public licensing key.
        )
        ...
    }
}

Java

public class MainActivity extends Activity {
    ...
    private LicenseCheckerCallback licenseCheckerCallback;
    private LicenseChecker checker;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // Construct the LicenseCheckerCallback. The library calls this when done.
        licenseCheckerCallback = new MyLicenseCheckerCallback();

        // Construct the LicenseChecker with a Policy.
        checker = new LicenseChecker(
            this, new ServerManagedPolicy(this,
                new AESObfuscator(SALT, getPackageName(), deviceId)),
            BASE64_PUBLIC_KEY // Your public licensing key.
            );
        ...
    }
}

LicenseChecker işlevinin, yalnızca yerel olarak önbelleğe alınmış geçerli lisans yanıtı varsa kullanıcı arayüzü iş parçacığındaki LicenseCheckerCallback yöntemlerini çağırdığını unutmayın. Lisans denetimi sunucuya gönderilirse geri çağırmaların kaynağı, ağ hataları olsa bile her zaman arka plan iş parçacığıdır.

Lisans kontrolünü başlatmak için checkAccess() işlevini çağırın

Ana Etkinliğinizde, LicenseChecker örneğine ait checkAccess() yöntemine bir çağrı ekleyin. Çağrıda, LicenseCheckerCallback örneğinize parametre olarak bir referans iletin. Çağrıdan önce özel kullanıcı arayüzü etkilerini veya durum yönetimini gerçekleştirmeniz gerekiyorsa sarmalayıcı yönteminden checkAccess() yöntemini çağırmak faydalı olabilir. Örneğin, LVL örnek uygulaması, doCheck() sarmalayıcı yönteminden checkAccess() çağırır:

Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        // Call a wrapper method that initiates the license check
        doCheck()
        ...
    }
    ...
    private fun doCheck() {
        checkLicenseButton.isEnabled = false
        setProgressBarIndeterminateVisibility(true)
        statusText.setText(R.string.checking_license)
        checker.checkAccess(licenseCheckerCallback)
    }

Java

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // Call a wrapper method that initiates the license check
        doCheck();
        ...
    }
    ...
    private void doCheck() {
        checkLicenseButton.setEnabled(false);
        setProgressBarIndeterminateVisibility(true);
        statusText.setText(R.string.checking_license);
        checker.checkAccess(licenseCheckerCallback);
    }

Lisanslama için ortak anahtarınızı yerleştirme

Google Play hizmeti her uygulama için otomatik olarak lisanslama ve uygulama içi faturalandırma için kullanılan 2048 bitlik bir RSA ortak/özel anahtar çifti oluşturur. Anahtar çifti, uygulamayla benzersiz bir şekilde ilişkilendirilir. Uygulamayla ilişkilendirilmiş olsa da anahtar çifti, uygulamalarınızı imzalamak için kullandığınız (veya bu anahtardan türetilen) anahtarla aynı değildir.

Google Play Console, ortak anahtarı lisanslama için Play Console'da oturum açmış tüm geliştiricilere gösterir, ancak özel anahtarı güvenli bir konumda tüm kullanıcılardan gizler. Bir uygulama, hesabınızda yayınlanan bir uygulama için lisans kontrolü istediğinde, lisanslama sunucusu uygulamanızın anahtar çiftinin özel anahtarını kullanarak lisans yanıtını imzalar. LVL yanıtı aldığında lisans yanıtının imzasını doğrulamak için uygulama tarafından sağlanan ortak anahtarı kullanır.

Bir uygulamaya lisans eklemek için uygulamanızın ortak anahtarını lisanslama ve uygulamanıza kopyalamanız gerekir. Lisanslama için uygulamanızın ortak anahtarını nasıl bulacağınız aşağıda açıklanmıştır:

  1. Google Play Console'a gidin ve oturum açın. Lisansladığınız uygulamanın yayınlandığı (veya yayınlanacağı) hesapta oturum açtığınızdan emin olun.
  2. Uygulama ayrıntıları sayfasında Hizmetler ve API'ler bağlantısını bulup tıklayın.
  3. Hizmetler ve API'ler sayfasında Lisanslama ve Uygulama İçi Faturalandırma bölümünü bulun. Lisanslama için ortak anahtarınız Bu Uygulama İçin Lisans Anahtarınız alanında verilir.

Ortak anahtarı uygulamanıza eklemek için alandan anahtar dizesini kopyalayıp uygulamanıza Dize değişkeninin BASE64_PUBLIC_KEY değeri olarak yapıştırmanız yeterlidir. Kopyalama sırasında, hiçbir karakteri atlamadan anahtar dizesinin tamamını seçtiğinizden emin olun.

LVL örnek uygulamasından bir örneği burada bulabilirsiniz:

Kotlin

private const val BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG ... " //truncated for this example
class LicensingActivity : AppCompatActivity() {
    ...
}

Java

public class MainActivity extends Activity {
    private static final String BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG ... "; //truncated for this example
    ...
}

IPC bağlantılarını kapatmak için LicenseChecker'ın onDestroy() yöntemini çağırın

Son olarak, Context uygulamanız değişmeden önce LVL'nin temizlenmesini sağlamak için Activity'in onDestroy() uygulamasından LicenseChecker onDestroy() yöntemine çağrı ekleyin. Çağrı, LicenseChecker ürününün Google Play uygulamasının ILicensingService'e yönelik açık IPC bağlantılarını düzgün şekilde kapatmasına neden olur ve hizmete ve işleyiciye yapılan tüm yerel referansları kaldırır.

LicenseChecker'in onDestroy() yönteminin çağrılmaması, uygulamanızın yaşam döngüsü boyunca sorunlara yol açabilir. Örneğin, kullanıcı bir lisans kontrolü etkinken ekran yönünü değiştirirse Context uygulaması kaldırılır. Uygulamanız, LicenseChecker cihazının IPC bağlantısını düzgün şekilde kapatmazsa yanıt alındığında uygulamanız çöker. Benzer şekilde, kullanıcı, lisans kontrolü devam ederken uygulamanızdan çıkarsa hizmet bağlantısını kesmek için LicenseChecker'ın onDestroy() yöntemini düzgün bir şekilde çağırmadığı sürece uygulamanız yanıt alındığında çöker.

Aşağıda, LVL'ye dahil edilen örnek uygulamadan bir örnek verilmiştir. Burada mChecker, LicenseChecker örneğidir:

Kotlin

    override fun onDestroy() {
        super.onDestroy()
        checker.onDestroy()
        ...
    }

Java

    @Override
    protected void onDestroy() {
        super.onDestroy();
        checker.onDestroy();
        ...
    }

LicenseChecker hizmetinin kapsamını genişletiyor veya değiştiriyorsanız açık IPC bağlantılarını temizlemek için LicenseChecker finishCheck() yöntemini de çağırmanız gerekebilir.

DeviceLimiter Uygulama

Bazı durumlarda, Policy cihazınızın tek bir lisansı kullanmasına izin verilen gerçek cihaz sayısını sınırlandırmasını isteyebilirsiniz. Bu durum, kullanıcının lisanslı bir uygulamayı çeşitli cihazlara taşımasını ve bu uygulamayı bu cihazlarda aynı hesap kimliği altında kullanmasını engeller. Ayrıca, lisansla ilişkili hesap bilgilerini diğer kişilere sağlayarak kullanıcının uygulamayı "paylaşmasını" da önler. Bu kişiler daha sonra cihazlarında bu hesapta oturum açabilir ve uygulamanın lisansına erişebilir.

LVL, tek bir allowDeviceAccess() yöntemini tanımlayan bir DeviceLimiter arayüzü sunarak cihaz başına lisanslamayı destekler. LicenseValidator, lisanslama sunucusundan alınan bir yanıtı işlerken allowDeviceAccess() yöntemini çağırarak yanıttan çıkarılan bir kullanıcı kimliği dizesini iletir.

Cihaz sınırlamasını desteklemek istemiyorsanız herhangi bir işlem yapmanız gerekmez. LicenseChecker sınıfı otomatik olarak NullDeviceLimiter adlı varsayılan bir uygulamayı kullanır. Adından da anlaşılacağı gibi NullDeviceLimiter bir "işlemsiz" sınıfıdır. Bu sınıftaki allowDeviceAccess() yöntemi, tüm kullanıcılar ve cihazlar için yalnızca LICENSED yanıtı döndürür.

Dikkat: Cihaz başına lisanslama aşağıdaki nedenlerle çoğu uygulama için önerilmez:

  • Kullanıcı ve cihaz eşlemeyi yönetecek bir arka uç sunucusu sağlamanızı gerektirir.
  • Bu durum yanlışlıkla kullanıcının başka bir cihazda meşru olarak satın aldığı bir uygulamaya erişiminin reddedilmesine neden olabilir.

Kodunuzu karartma

Uygulamanızın güvenliğini sağlamak için, özellikle de lisanslama ve/veya özel kısıtlamalar ve korumalar kullanan ücretli bir uygulamada, uygulama kodunuzun kodunu karartmanız önemlidir. Kodunuzu düzgün bir şekilde karartmak, kötü amaçlı kullanıcıların uygulamanın bayt kodunu çözmesini, değiştirmesini (ör. lisans denetimini kaldırarak) ve daha sonra yeniden derlemesini zorlaştırır.

Android uygulamaları için, kod optimizasyonu özellikleri de sunan ProGuard dahil olmak üzere çeşitli kod karartma programları mevcuttur. Kodunuzu karartmak için ProGuard veya benzer bir program kullanmanız Google Play Lisanslama kullanan tüm uygulamalarda şiddetle önerilir.

Lisanslı Bir Uygulamayı Yayınlama

Lisans uygulamanızı test etmeyi bitirdiğinizde, uygulamayı Google Play'de yayınlamaya hazır olursunuz. Hazırlamak, imzalamak ve ardından uygulamayı yayınlamak için normal adımları uygulayın.

Nereden Destek Alınır?

Uygulamalarınızda yayınlama ya da dağıtım yaparken sorularınız olursa veya sorunlarla karşılaşırsanız lütfen aşağıdaki tabloda listelenen destek kaynaklarını kullanın. Sorgularınızı doğru foruma yönlendirerek ihtiyacınız olan desteği daha hızlı alabilirsiniz.

Tablo 2. Google Play Lisanslama Hizmeti için geliştirici destek kaynakları.

Destek Türü Kaynak Konu Aralığı
Geliştirme ve testlerle ilgili sorunlar Google Grupları: android-developers LVL indirme ve entegrasyonu, kitaplık projeleri, Policy sorular, kullanıcı deneyimi fikirleri, yanıtların işlenmesi, Obfuscator, IPC, test ortamı kurulumu
Yığın Taşması: http://stackoverflow.com/questions/managed/android
Hesaplar, yayınlama ve dağıtım sorunları Google Play Yardım Forumu Yayıncı hesapları, lisanslama anahtarı çifti, test hesapları, sunucu yanıtları, test yanıtları, uygulama dağıtımı ve sonuçlar
Pazar Lisanslama Desteği Hakkında SSS
LVL sorun izleyicisi Pazar lisanslama proje sorunları izleyicisi Özellikle LVL kaynak kodu sınıfları ve arayüz uygulamalarıyla ilgili hata ve sorun raporları

Yukarıda listelenen gruplara yayın gönderme hakkında genel bilgi için Geliştirici Destek Kaynakları sayfasının Topluluk Kaynakları bölümüne bakın.

Ek Kaynaklar

LVL'ye dahil edilen örnek uygulama, MainActivity sınıfında lisans kontrolünün nasıl başlatılacağı ve sonucun nasıl işleneceğine dair tam bir örnek sağlar.