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:
- Uygulamanızın manifest dosyasına lisanslama iznini ekleme.
- Politika Uygulama: LVL'de sağlanan eksiksiz uygulamalardan birini seçebilir veya kendi politikanızı oluşturabilirsiniz.
Policy
ürününüz lisans yanıt verilerini önbelleğe alacaksa Gizleyici Uygulama.- Uygulamanızın ana Etkinliğinde lisansı kontrol etmek için kod ekleme.
- 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
:
- 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).
- 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. - 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. - 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:
- Salt; her bir kod karartma (kaldırma) için kullanılacak rastgele bayt dizisidir.
- Bir uygulama tanımlayıcısı dizesidir. Bu dize genellikle uygulamanın paket adıdır.
- 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:
- İçe aktarma işlemi ekleme
- LisansCheckerCallback'i özel bir iç sınıf olarak uygulayın
- LicenseCheckerCallback'ten kullanıcı arayüzü ileti dizisine yayınlamak için bir İşleyici oluşturun
- LisansChecker ve LicenseCheckerCallback Örneği
- Lisans kontrolünü başlatmak için checkAccess() işlevini çağırın.
- Lisanslama için ortak anahtarınızı yerleştirme
- 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
nesnesinincheckAccess()
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ılanallow()
vedontAllow()
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()
vedontAllow()
yöntemleri, yanıtları için bir "neden" sağlar. Bu,Policy
değerlerinden biri,LICENSED
,NOT_LICENSED
ya daRETRY
olabilir. Özellikle, yöntemindontAllow()
içinRETRY
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.
Yukarıdaki şemada, tipik bir lisans kontrolünün nasıl yapıldığı gösterilmektedir:
- Uygulamanın ana Etkinliğindeki kod,
LicenseCheckerCallback
veLicenseChecker
nesnelerini örneklendirir.LicenseChecker
oluşturulurken kodContext
, kullanılacak birPolicy
uygulaması ve lisanslama için parametre olarak yayıncı hesabının ortak anahtarı geçer. - Daha sonra kod,
LicenseChecker
nesnesindecheckAccess()
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çinPolicy
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. - Bu durumda
- 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çinPolicy
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
nesnesindeallow()
yöntemini çağırır. - Lisans geçerli değilse
Policy
, doğrulayıcıya bildirim gönderir. Doğrulayıcı,LicenseCheckerCallback
üzerindedontAllow()
yöntemini çağırır.
- Lisans geçerliyse
- Ağın isteği göndermek için uygun olmaması gibi durumlarda, kurtarılabilir bir yerel hata veya sunucu hatası olması durumunda
LicenseChecker
,Policy
nesnenizinprocessServerResponse()
yöntemineRETRY
yanıtı iletir.Ayrıca hem
allow()
hem dedontAllow()
geri çağırma yöntemleri birreason
bağımsız değişkeni alır.allow()
yönteminin nedeni genelliklePolicy.LICENSED
veyaPolicy.RETRY
,dontAllow()
nedeni ise genelliklePolicy.NOT_LICENSED
veyaPolicy.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. - Uygulamanın, geçersiz bir paket adının lisansını kontrol etmeye çalışması gibi bir uygulama hatası durumunda,
LicenseChecker
, LicenseCheckerCallback'inapplicationError()
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:
LicenseCheckerCallback
yöntemleriniz, çoğu durumda bir arka plan iş parçacığından çağrılır.- 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ılanPolicy
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:
- 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.
- Uygulama ayrıntıları sayfasında Hizmetler ve API'ler bağlantısını bulup tıklayın.
- 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.
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.