APK Genişletme Dosyaları

Google Play, kullanıcıların indirdiği sıkıştırılmış APK'nın 100 MB'tan fazla olmamasını zorunlu kılar. Bu alan, çoğu uygulama için tüm uygulama kodu ve öğeleri için geniş bir alandır. Ancak bazı uygulamalar yüksek kaliteli grafikler, medya dosyaları veya diğer büyük öğeler için daha fazla alana ihtiyaç duyar. Önceden, uygulamanızın sıkıştırılmış indirme boyutu 100 MB'ı aşıyorsa, ek kaynaklar hazırlayabilirsiniz. Ek dosyaları barındırmak ve sunmak, çoğu zaman idealin altındadır ve kullanıcı deneyimi genellikle pahalıya mal olur. Bu işlemi sizin için kolaylaştırmak üzere ve kullanıcılar için daha keyifli olan Google Play, iki büyük genişletme dosyası eklemenize olanak tanır. APK'nızı destekler.

Google Play, uygulamanızın genişletme dosyalarını barındırır ve bunları şuradaki cihazda sunar: hiçbir maliyeti olmaz. Genişletme dosyaları cihazın paylaşılan depolama konumuna ( SD kart veya USB'ye takılabilir bölüm; “harici” olarak da bilinir. uygulamanızın erişebileceği depolama alanı) gerekir. Google Play, çoğu cihazda genişletme dosyalarını aynı anda indirir APK'yı indirir; böylece kullanıcı, APK'yı ilk kez. Ancak bazı durumlarda, uygulamanızın bu dosyaları Google Play'den indirmesi gerekir Google Ad Manager'a iletebilirsiniz.

Genişletme dosyası kullanmaktan kaçınmak istiyorsanız ve uygulamanızın sıkıştırılmış indirme boyutu daha büyükse boyutu 100 MB'tan büyükse uygulamanızı Android Uygulaması Paketler: 200 MB'a kadar sıkıştırılmış indirme boyutuna olanak tanır. Ayrıca, Uygulama paketleri, APK oluşturma ve Google Play'de oturum açma işlemlerini erteler. Kullanıcılar, yalnızca uygulamanızı çalıştırmak için gereken kod ve kaynakları sağlayın. Bina oluşturmak, imzalamak kullanıcılar birden fazla APK veya genişletme dosyasını yönetebilir. Kullanıcılar daha küçük ve daha optimize edilmiş indirmeler elde eder.

Genel Bakış

Google Play Console'u kullanarak her APK yüklediğinizde APK'ya bir veya iki genişletme dosyası ekleyin. Her dosya en fazla 2 GB olabilir ve istediğiniz biçimde olabilir. seçebilirsiniz, ancak indirme sırasında bant genişliğini korumak için sıkıştırılmış bir dosya kullanmanızı öneririz. Kavram olarak her genişletme dosyası farklı bir rol oynar:

  • Ana genişletme dosyası birincil genişletme dosyanızı eklemeniz gerekir.
  • yama genişletme dosyası isteğe bağlıdır ve ana genişletme dosyası oluşturun.

Bu iki genişletme dosyasını istediğiniz gibi kullanabilirsiniz, ancak ana genişletme dosyası birincil öğeleri teslim eder ve güncellenmezse nadiren görülür. yama genişletme dosyası daha küçük olmalı ve "yama operatörü" işlevi görmeli veya gerektiğinde geri bildirim vermelisiniz.

Ancak, uygulama güncellemeniz yalnızca yeni bir yama genişletme dosyası gerektirse bile manifest dosyasında güncellenmiş versionCode ile yeni bir APK yükleyin. ( Play Console, mevcut bir APK'ya genişletme dosyası yüklemenize izin vermez.)

Not: Yama genişletme dosyası, anlam açısından ana genişletme dosyası olarak, her dosyayı istediğiniz gibi kullanabilirsiniz.

Dosya adı biçimi

Yüklediğiniz her bir genişletme dosyası, seçtiğiniz herhangi bir biçimde (ZIP, PDF, MP4 vb.) olabilir. Ayrıca transkriptinizi bir kümeyi kapsüllemek ve şifrelemek için JOBB aracını kullanın yamalarını ifade eder. Google Play, dosya türünden bağımsız olarak bunları opak ikili blob'lar olarak değerlendirir ve aşağıdaki şemayı kullanarak dosyaları yeniden adlandırır:

[main|patch].<expansion-version>.<package-name>.obb

Bu şemanın üç bileşeni vardır:

main veya patch
Dosyanın ana dosya mı yoksa yama genişletme dosyası mı olduğunu belirtir. Projede her APK için yalnızca bir ana dosya ve bir yama dosyası bulunmalıdır.
<expansion-version>
Bu, genişletmenin kullanıldığı APK'nın sürüm koduyla eşleşen bir tam sayıdır. ilk ilişkilendirilen (uygulamanın android:versionCode ile eşleşir) değeri) ekleyebilirsiniz.

"Ad" her ne kadar Play Console size sadece yüklenen bir genişletme dosyasını yeni bir APK ile yeniden kullanırsanız genişletme dosyasının adı değişmez; dosyayı ilk yüklediğinizde ona uygulanan sürümü korur.

<package-name>
Uygulamanızın Java stili paket adı.

Örneğin, APK sürümünüzün 314159, paket adınızın ise com.example.app olduğunu varsayalım. Şu durumda: bir ana genişletme dosyası yüklediğinizde dosyanın adı şu şekilde olur:

main.314159.com.example.app.obb

Depolama konumu

Google Play genişletme dosyalarınızı bir cihaza indirdiğinde, bunları sistemin paylaşılan depolama konumu. Doğru davranışı sağlamak için, anahtar kelimeleri silmemeli, taşımamalı veya genişletme dosyalarını kullanabilirsiniz. Uygulamanızın Google Play'den indirme işlemini gerçekleştirmesi gerektiğinde dosyaları tam olarak aynı konuma kaydetmeniz gerekir.

getObbDir() yöntemi, belirli bir konumu döndürür aşağıdaki biçimde olması gerekir:

<shared-storage>/Android/obb/<package-name>/

Her uygulama için bu dizinde hiçbir zaman ikiden fazla genişletme dosyası olmaz. Biri ana genişletme dosyası, diğeri ise yama genişletme dosyasıdır (gerekirse). Geri sürümlerin üzerine yazılır. Android'den beri 4.4 (API düzeyi 19) nedeniyle uygulamalar, OBB genişletme dosyalarını harici depolama olmadan okuyabilir izni gerekir. Ancak, Android 6.0 (API düzeyi 23) ve sonraki sürümlerin bazı uygulamaları için yine de bu izni beyan etmeniz gerekir. READ_EXTERNAL_STORAGE iznini almak için şu adresten izin isteyin: aşağıdaki gibi çalışır:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Android 6 ve sonraki sürümler için çalışma zamanında harici depolama izninin istenmesi gerekir. Ancak Android'in bazı uygulamaları, OBB dosyalarını okumak için izin gerektirmez. İlgili içeriği oluşturmak için kullanılan Aşağıdaki kod snippet'i, harici depolama alanı istenmeden önce okuma erişimini nasıl kontrol edeceğinizi gösterir izin:

Kotlin

val obb = File(obb_filename)
var open_failed = false

try {
    BufferedReader(FileReader(obb)).also { br ->
        ReadObbFile(br)
    }
} catch (e: IOException) {
    open_failed = true
}

if (open_failed) {
    // request READ_EXTERNAL_STORAGE permission before reading OBB file
    ReadObbFileWithPermission()
}

Java

File obb = new File(obb_filename);
 boolean open_failed = false;

 try {
     BufferedReader br = new BufferedReader(new FileReader(obb));
     open_failed = false;
     ReadObbFile(br);
 } catch (IOException e) {
     open_failed = true;
 }

 if (open_failed) {
     // request READ_EXTERNAL_STORAGE permission before reading OBB file
     ReadObbFileWithPermission();
 }

Genişletme dosyalarınızın içeriğini paketten çıkarmanız gerekirse OBB genişletme dosyalarını yükleyin ve paketlenmemiş verileri kaydetmeyin aynı dizinde oluşturur. Paketlenmemiş dosyalarınızı dizine kaydetmeniz gerekir getExternalFilesDir() tarafından belirtilmiş. Ancak, mümkünse, doğrudan kaynak metinden doğrudan okumanıza olanak tanıyan bir genişletme dosyası dosyayı paketten açmanızı gerektirmez. Örneğin, giriş seviyesindeki verilerinizi doğrudan okuyan APK Genişletme Zip Kitaplığı projesi .

Dikkat: APK dosyalarının aksine, kullanıcı ve diğer uygulamalar tarafından okunabilir.

İpucu: Medya dosyalarını ZIP dosyası olarak paketliyorsanız medya dosyalarını kullanabilirsiniz. ofset ve uzunluk kontrollerine sahip dosyalardaki oynatma çağrıları (MediaPlayer.setDataSource() ve SoundPool.load()), açmanız gerekir. Bunun işe yaraması için, Güvenli Tarama'da bulunan medya dosyalarını oluşturmak için de kullanılabilir. Örneğin, zip aracını kullanırken olmaması gereken dosya soneklerini belirtmek için -n seçeneğini kullanmanız gerekir. sıkıştırılmış:
zip -n .mp4;.ogg main_expansion media_files

İndirme işlemi

Google Play çoğu zaman genişletme dosyalarınızı indirir ve kaydeder. APK'yı cihaza indirir. Ancak bazı durumlarda Google Play, genişletme dosyaları indirilemiyor veya kullanıcı, daha önce indirilmiş genişletmeyi silmiş olabilir dosyası olarak da kaydedebilir. Bu durumları ele almak için uygulamanızın dosyaları indirebilmesi gerekir ana etkinlik başladığında kendisine Google Play tarafından sağlanan bir URL kullanılarak gönderilir.

Genel düzeyden indirme işlemi şu şekilde görünür:

  1. Kullanıcı, uygulamanızı Google Play'den yüklemeyi seçer.
  2. Google Play genişletme dosyalarını indirebiliyorsa (bu, çoğu cihazlar) indirildiğinde, bunları APK ile birlikte indirir.

    Google Play genişletme dosyalarını indiremezse Yalnızca APK.

  3. Kullanıcı uygulamanızı başlattığında uygulamanız, genişletme dosyalarının Cihaza kaydedilmiş olanlar.
    1. Yanıt evetse uygulamanız kullanıma hazırdır.
    2. Aksi takdirde, uygulamanızın genişletme dosyalarını Google Play'den HTTP aracılığıyla indirmesi gerekir. Uygulamanız Google Play'in uygulama Lisanslama hizmetini kullanarak Google Play istemcisine bir istek göndermelidir. her bir genişletme dosyasının adı, dosya boyutu ve URL'siyle yanıt verir. Bu bilgileri kullanarak dosyaları indirip uygun depolama konumuna kaydedebilirsiniz.

Dikkat: Reklam oluşturma ve düzenleme için gerekli kodu ve dosyalar halihazırda Google Play'de yer almamışsa, cihazınız üzerinden otomatik olarak yayınlamanız gerekir. Aşağıdaki Genişletme Dosyalarını İndirme bölümünde açıklandığı gibi, kullanabileceğiniz bir kitaplık hazırladık. Bu işlem büyük ölçüde daha basit hale getirir ve minimum miktarda Google'a gönderir.

Geliştirme kontrol listesi

Burada, uygulama:

  1. Öncelikle, uygulamanızın sıkıştırılmış indirme boyutunun 100 MB'tan fazla olması gerekip gerekmediğini belirleyin. Alan değerlidir ve toplam indirme boyutunuzu mümkün olduğunca küçük tutmalısınız. Uygulamanız grafik öğelerinizin birden fazla ekranda birden çok sürümünü sağlamak için 100 MB'tan fazla yer kullanır yoğunlukları yerine, her APK'nın ayrı ayrı oynatıldığı birden fazla APK yayınlamayı düşünebilirsiniz Yalnızca hedeflediği ekranlar için gerekli öğeleri içerir. En iyi sonuçlar için uygulamanızı Google Play'de yayınlamak için, bir Android App Bundle uygulamanızın tüm derlenmiş kod ve kaynaklarını içerir ancak APK oluşturma ve imzalama işlemlerini Google'a erteler Oyna.
  2. Hangi uygulama kaynaklarının APK'nızdan ayrılacağını ve bir içinde paketleneceğini belirleyin ana genişletme dosyası olarak kullanılacak dosya.

    Normalde ana genişletme dosyası oluşturun. Ancak kaynaklarınız ana genişletme dosyanızı yüklemek yerine, öğelerinizin geri kalanı için yama dosyasını kullanabilirsiniz.

  3. Uygulamanızı, paylaşılan depolama konumuna eklenmez.

    Genişletme dosyalarını silmemeniz, taşımamanız veya yeniden adlandırmamanız gerektiğini unutmayın.

    Uygulamanız belirli bir biçim talep etmiyorsa aşağıdakiler için ZIP dosyaları oluşturmanızı öneririz: daha sonra, APK Genişletme Zip dosyasını kullanarak bunları okuyun. Kitaplık.

  4. Uygulamanızın ana etkinliğine, genişletme dosyalarının mevcut olup olmadığını kontrol eden bir mantık ekleyin cihaz başlatıldıktan sonra cihazda olduğunu gösterir. Dosyalar cihazda değilse URL'leri istemek için Google Play'in uygulama Lisanslama hizmetini kullanın genişletme dosyalarını seçin, ardından bunları indirip kaydedin.

    Yazmanız gereken kod miktarını büyük ölçüde azaltmak ve iyi bir kullanıcı deneyimi sağlamak için işlemi sırasında indirmenizi öneririz. İndirme işlemi sırasında İndirici Kitaplık'ı seçin.

    Kitaplığı kullanmak yerine kendi indirme hizmetinizi oluşturmak isterseniz genişletme dosyalarının adını değiştirmemeli ve bunları uygun depolama konumu bilgisidir.

Uygulama geliştirmenizi tamamladığınızda Test Genişletme Dosyalarınız.

Kurallar ve Sınırlamalar

APK genişletme dosyaları ekleme özelliği, uygulamanızı Play Console Uygulamanızı ilk kez yüklerken veya bir uygulamalarında aşağıdaki kurallara ve sınırlamalara dikkat etmeniz gerekir:

  1. Genişletme dosyaları 2 GB'tan büyük olamaz.
  2. Genişletme dosyalarınızı Google Play'den indirmek için kullanıcının (uygulamanızı Google Play'den satın alma) Google Play, Uygulama başka yollarla yüklendiyse genişletme dosyalarınızın URL'lerini sağlayın.
  3. Uygulamanızın içinden indirme işlemi gerçekleştirirken, Google Play'in Her dosya için her bir indirme işlemi benzersizdir ve her birinin süresi, veri gönderildikten kısa bir süre sonra dolar ekleyin.
  4. Uygulamanızı yeni bir APK ile güncellerseniz veya aynı için birden fazla APK yüklerseniz önceki bir APK için yüklediğiniz genişletme dosyalarını seçebilirsiniz. genişletme dosyasının adı değişmez; APK'nın Dosyanın orijinal olarak ilişkilendirildiği dosya,
  5. Genişletmek için genişletme dosyalarını birden fazla APK ile birlikte kullanıyorsanız farklı cihazlar için farklı genişletme dosyaları sağlasanız da ayrı APK'lar yüklemeniz gerekir benzersiz bir versionCode sağlamak için her cihaz için farklı filtreler bildirebilirsiniz. her APK'yı kullanın.
  6. Genişletme dosyalarını değiştirerek uygulamanızda güncelleme yayınlayamazsınız (uygulamanızı güncellemek için yeni bir APK yüklemeniz gerekir) Yalnızca değişiklikleriniz genişletme dosyalarınızdaki öğelerle ilgiliyse versionCode (ve (versionName) de olabilir.

  7. obb/ cihazınıza başka veriler kaydetmeyin dizininde bulunduğundan emin olun. Bazı verilerin paketini açmanız gerekiyorsa verileri getExternalFilesDir() ile belirtilen konuma kaydedin.
  8. .obb genişletme dosyasını silmeyin veya yeniden adlandırmayın ( güncelleme) gerekir. Bunu yapmak, Google Play'in (veya uygulamanızın kendisinin) sürekli olarak genişletme dosyasını indirin.
  9. Bir genişletme dosyasını manuel olarak güncellerken önceki genişletme dosyasını silmeniz gerekir.

Genişletme Dosyalarını İndirme

Çoğu durumda Google Play, genişletme dosyalarınızı cihaza aynı zamanda indirir ve kaydeder. aldığı veya güncellediği zamandır. Bu şekilde, genişletme dosyaları kullanıma sunuyoruz. Ancak, bazı durumlarda, uygulamanızın yanıtta size sağlanan bir URL'den isteyerek genişletme dosyalarını kullanabilirsiniz. Google Play'in Uygulama Lisanslama hizmetinden alabilirsiniz.

Genişletme dosyalarınızı indirmek için ihtiyacınız olan temel mantık şudur:

  1. Uygulamanız başlatıldığında, genişletme dosyalarını paylaşılan depolama konumunda ( Android/obb/<package-name>/ dizini).
    1. Genişletme dosyaları mevcutsa hazırsınız demektir ve uygulamanız devam edebilir.
    2. Genişletme dosyaları orada yoksa:
      1. Aşağıdakileri almak için Google Play'in uygulama lisanslamasını kullanarak bir istekte bulunun: uygulamanın genişletme dosyası adları, boyutları ve URL'leri.
      2. Genişletme dosyalarını indirmek ve kaydetmek için Google Play tarafından sağlanan URL'leri kullanın ekleyebilirsiniz. Dosyaları paylaşılan depolama konumuna kaydetmeniz gerekir. (Android/obb/<package-name>/) ve sağlanan dosya adını aynen kullanın Google Play'in yanıtıyla.

        Not: Google Play'in genişletme dosyaları her indirme için benzersizdir ve genişletme dosyalarından her birinin süresi, verildikten kısa bir süre sonra dolar en iyi şekilde yararlanabilirsiniz.

Uygulamanız ücretsizse (ücretli bir uygulama değilse) muhtemelen uygulama Lisanslama hizmetini kullanmamışsınızdır. Esas olarak, bu uygulamaları uygulamanızın lisanslama politikaları hakkında daha fazla bilgi edinin ve kullanıcının uygulamanızı kullanma (Google Play'de uygulama için haklı olarak ödeme yapmış olması) Çevik yaklaşımın genişletme dosyası işlevselliği, lisanslama hizmeti yanıt verecek şekilde geliştirilmiştir uygulamanızın barındırdığı genişletme dosyalarının URL'sini içeren bir URL ekleyerek . Bu nedenle, uygulamanız kullanıcılar için ücretsiz olsa bile, APK genişletme dosyalarını kullanmak için Lisans Doğrulama Kitaplığı (LVL). Tabii ki uygulamanız ücretsiz olduğundan, lisans doğrulamasını zorunlu kılmanız gerekmez; kitaplığını kullanarak, genişletme dosyalarınızın URL'sini döndüren isteği gerçekleştirebilirsiniz.

Not: Uygulamanızın ücretsiz olup olmamasından bağımsız olarak, Google Play ise, yalnızca kullanıcı uygulamanızı Google Play'den edindiyse genişletme dosyası URL'lerini döndürür.

LVL'ye ek olarak, genişletme dosyalarını indiren bir kod kümesine ihtiyacınız vardır. ve cihazın paylaşılan depolama alanındaki uygun konuma kaydeder. Bu prosedürü uygulamanıza yerleştirdiğinizde, dikkat etmeniz gereken birkaç sorun vardır. üzerinde düşünme:

  • Cihazda genişletme dosyaları için yeterli alan olmayabilir. Bu nedenle, ve yeterli alan yoksa kullanıcıyı uyarın.
  • Kullanıcının engellenmemesi için dosya indirme işlemleri bir arka plan hizmetinde gerçekleşmelidir kullanıcı etkileşimi sağlayın ve indirme işlemi tamamlanırken kullanıcının uygulamanızdan ayrılmasına izin verin.
  • İstek ve indirme işlemi sırasında farklı hatalarla karşılaşabilirsiniz. Bu hatalar zarif bir şekilde ele alın.
  • İndirme işlemi sırasında ağ bağlantısı değişebilir. Dolayısıyla bu tür değişiklikleri ve kesintiye uğrarsa indirme işlemine devam edin.
  • İndirme işlemi arka planda gerçekleşirken, İndirme işleminin ilerlemesini gösterir, işlem tamamlandığında kullanıcıya bilgi verir ve kullanıcıyı geri uygulamanızı sağlayabilirsiniz.

Bu işi sizin için basitleştirmek amacıyla İndirici Kitaplığı'nı tasarladık. lisans hizmeti aracılığıyla genişletme dosyası URL'lerini isteyen, genişletme dosyalarını indirir ve yukarıda listelenen tüm görevleri gerçekleştirir ve hatta etkinliğinizin duraklatılmasına ve devam ettirilmesine indirin. Uygulamanıza İndirme Aracı Kitaplığı'nı ve birkaç kod kancasını ekleyerek ve genişletme dosyalarını indirme işlemi zaten sizin için kodlanmıştır. Bu nedenle, kullanıcılara en iyi minimum çabayla bir kullanıcı deneyimi yaşamanızı sağlamak için İndirici Kitaplığı'nı kullanarak genişletme dosyalarınızı indirin. Aşağıdaki bölümlerde yer alan bilgiler, Google Ads'in uygulamanıza aktarmaktır.

Genişletme dosyalarını indirmek için Google Play URL'leri için uygulamayı Lisanslama belgelerinde bir lisans isteği gerçekleştirip genişletme dosya adlarını alın. ve yanıt ekstralarındaki URL'leri gösterir. Lisanslamanız olarak APKExpansionPolicy sınıfını (Lisans Doğrulama Kitaplığı'na dahildir) kullanmanız gerekir. politikası kullanılmalıdır.

İndirme Aracı Kitaplığı hakkında

Uygulamanızla APK genişletme dosyalarını kullanmak ve asgari düzeyde çaba sarf etmeniz gerekiyorsa, Google Play APK Genişletme Kitaplığı paketi. Bu kitaplık, genişletme dosyalarınızı arka plan hizmeti, indirme durumuyla ilgili bir kullanıcı bildirimi gösterir, ağı işler bağlantı kesilir, mümkün olduğunda indirme işlemi devam eder ve daha pek çok işlem yapılır.

İndirme Aracı Kitaplığı'nı kullanarak genişletme dosyası indirmelerini uygulamak için tüm yapmanız gereken:

  • Her biri yalnızca birkaç tane gereken özel bir Service alt sınıfını ve BroadcastReceiver alt sınıfını genişletin veya sizden gelen kod satırını kullanın.
  • Ana etkinliğinize, genişletme dosyalarının mevcut olup olmadığını kontrol eden bir mantık ekleyin. indirilmiş olabilir; indirilmediyse, indirme işlemini çağırır ve kullanıcı arayüzü.
  • Ana etkinliğinizde, size kullanılabilecek birkaç yöntem içeren bir geri çağırma İndirme işleminin ilerleme durumuyla ilgili güncellemeleri alır.

Aşağıdaki bölümlerde, İndirme Aracı Kitaplığı'nı kullanarak uygulamanızı nasıl ayarlayacağınız açıklanmaktadır.

İndirme Aracı Kitaplığı'nı kullanmaya hazırlanma

İndirici Kitaplığı'nı kullanmak için şunları yapmanız gerekir: SDK Manager'dan iki paket indirin ve uygun kitaplıkları uygulamasını indirin.

İlk olarak Android SDK Yöneticisi'ni açın (Araçlar > SDK Yöneticisi) ve Görünüm ve Davranış > Sistem Ayarları > Android SDK'sı varsa Aşağıdakileri seçip indirmek için SDK Araçları sekmesini kullanın:

  • Google Play Lisanslama Kitaplığı paketi
  • Google Play APK Genişletme Kitaplığı paketi

Lisans Doğrulama Kitaplığı ve İndirici için yeni bir kitaplık modülü oluşturma Kitaplık'a dokunun. Her kitaplık için:

  1. Dosya > Yeni > Yeni Modül.
  2. Yeni Modül Oluştur penceresinde Android Kitaplığı'nı seçin. ve ardından İleri'yi seçin.
  3. "Google Play Lisans Kitaplığı" gibi bir uygulama/Kitaplık adı belirtin Minimum SDK düzeyi'ni, ardından Sonlandır.
  4. Dosya > Proje Yapısı.
  5. Özellikler sekmesini ve Kitaplık'ı seçin Kod deposu'nda, <sdk>/extras/google/ dizinindeki kitaplığa girin (Lisans Doğrulama Kitaplığı için play_licensing/ veya İndirme Aracı Kitaplığı için play_apk_expansion/downloader_library/).
  6. Yeni modülü oluşturmak için Tamam'ı seçin.

Not: İndirici Kitaplığı, Lisansa bağlıdır Doğrulama Kitaplığı. Lisansın ve belgenin Doğrulama Kitaplığı'nı indirin.

Alternatif olarak, komut satırından projenizi kitaplıkları içerecek şekilde de güncelleyebilirsiniz:

  1. Dizinleri <sdk>/tools/ dizinine değiştirin.
  2. Şunu eklemek için: --library seçeneği ile android update project işlemini yürütün: LVL ve İndirici Kitaplığı'nı projenize ekleyin. Örnek:
    android update project --path ~/Android/MyApp \
    --library ~/android_sdk/extras/google/market_licensing \
    --library ~/android_sdk/extras/google/market_apk_expansion/downloader_library
    
    .

Hem Lisans Doğrulama Kitaplığı hem de İndirme Aracı Kitaplığı kullanıyorsanız, genişletme dosyalarını indirme olanağını hızlıca entegre edebilirsiniz. Google Play Genişletme dosyaları için seçtiğiniz biçim ve bu dosyaları okuma şekliniz diğer uygulamalarınızdan biri. en iyi uygulamaları paylaşacağım.

İpucu: APK Genişletme paketinde bir örnek uygulama konulu videomuzu izleyin. Örnekte üçüncü bir kitaplık kullanılıyor {0}APK Genişletmesi Zip Kitaplığı adı verilen Apk Genişletme paketinde bulunur.) Eğer ne yapmayı planladığını genişletme dosyalarınız için ZIP dosyalarını kullanırken, APK Genişletme Zip Kitaplığı'nı en iyi şekilde yararlanabilirsiniz. Daha fazla bilgi için aşağıdaki bölüme bakın APK Genişletme Zip Kitaplığı'nı Kullanma hakkında daha fazla bilgi edinin.

Kullanıcı izinlerini bildirme

Genişletme dosyalarını indirmek için İndirici Kitaplığı uygulamanızın manifest dosyasında beyan etmeniz gereken çeşitli izinler gerektiriyor. Onlar şunlardır:

<manifest ...>
    <!-- Required to access Google Play Licensing -->
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />

    <!-- Required to download files from Google Play -->
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- Required to keep CPU alive while downloading files
        (NOT to keep screen awake) -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <!-- Required to poll the state of the network connection
        and respond to changes -->
    <uses-permission
        android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!-- Required to check whether Wi-Fi is enabled -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

    <!-- Required to read and write the expansion files on shared storage -->
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest>

Not: İndirme Aracı Kitaplığı için varsayılan olarak API gerekir. ancak APK Genişletmesi Zip Kitaplığı, API düzeyi 5'i gerektiriyor.

İndirme aracını uygulama

İndirme işlemlerini arka planda gerçekleştirmek için, İndirici Kitaplığı, indirme işlemini DownloaderService adlı, genişletmeniz gereken Service alt sınıfa sahip. İçinde genişletme dosyalarını sizin için indirmenin yanı sıra, DownloaderService şunları da yapabilir:

  • Şu öğedeki değişiklikleri dinleyen bir BroadcastReceiver kaydeder: cihazın ağ bağlantısını (CONNECTIVITY_ACTION yayın) kullanarak gerektiğinde (örneğin, bağlantı kaybı nedeniyle) indirme işlemini duraklatabilir ve mümkün olduğunda indirme işlemini devam ettirin (bağlantı kazanılır).
  • İndirme işleminin yeniden denenmesi için RTC_WAKEUP alarmı programlar olduğu durumlar da olabilir.
  • İndirme işleminin ilerleme durumunu gösteren özel bir Notification oluşturur ve kontrol edebilirsiniz.
  • Uygulamanıza, indirme işlemini manuel olarak duraklatma ve devam ettirme izni verir.
  • Paylaşılan depolama biriminin eklenmiş ve kullanılabilir olduğunu, dosyaların halihazırda mevcut olmadığını doğrular, genişletme dosyalarını indirmeden önce yeterli alan bulunduğundan emin olun. Ardından kullanıcıya bilgi verir doğru olmadığını anlayabilirsiniz.

Tek yapmanız gereken, uygulamanızda DownloaderService sınıfını genişleten ve belirli uygulama ayrıntılarını sağlamak için üç yöntemi geçersiz kılan bir sınıf oluşturmaktır:

getPublicKey()
Bu, yayıncınız için Base64 olarak kodlanmış RSA ortak anahtarı olan bir dize döndürmelidir hesabına sahip olduğunuzu varsayalım. (Lisanslama özelliğini ayarlama başlıklı makaleye bakın).
getSALT()
Bu, Policy lisansının kullandığı rastgele bayt dizisini döndürmelidir Obfuscator oluşturun. Tuz, kodu karartılmış SharedPreferences verilerinizin lisans verilerinizin kaydedildiği dosya benzersiz olur ve bulunamaz.
getAlarmReceiverClassName()
Bu,BroadcastReceiver uygulamanız gerektiğini belirten alarmı alacak yeniden başlatılır (indirici hizmeti beklenmedik bir şekilde durursa bu olabilir).

Örneğin, DownloaderService öğesinin eksiksiz bir kullanımını burada görebilirsiniz:

Kotlin

// You must use the public key belonging to your publisher account
const val BASE64_PUBLIC_KEY = "YourLVLKey"
// You should also modify this salt
val SALT = byteArrayOf(
        1, 42, -12, -1, 54, 98, -100, -12, 43, 2,
        -8, -4, 9, 5, -106, -107, -33, 45, -1, 84
)

class SampleDownloaderService : DownloaderService() {

    override fun getPublicKey(): String = BASE64_PUBLIC_KEY

    override fun getSALT(): ByteArray = SALT

    override fun getAlarmReceiverClassName(): String = SampleAlarmReceiver::class.java.name
}

Java

public class SampleDownloaderService extends DownloaderService {
    // You must use the public key belonging to your publisher account
    public static final String BASE64_PUBLIC_KEY = "YourLVLKey";
    // You should also modify this salt
    public static final byte[] SALT = new byte[] { 1, 42, -12, -1, 54, 98,
            -100, -12, 43, 2, -8, -4, 9, 5, -106, -107, -33, 45, -1, 84
    };

    @Override
    public String getPublicKey() {
        return BASE64_PUBLIC_KEY;
    }

    @Override
    public byte[] getSALT() {
        return SALT;
    }

    @Override
    public String getAlarmReceiverClassName() {
        return SampleAlarmReceiver.class.getName();
    }
}

Uyarı: BASE64_PUBLIC_KEY değerini güncellemeniz gerekir aynı olmasını sağlamanız gerekir. Anahtarı, Geliştirici Konsolda profil bilgilerinizin altında bulunur. Bu, proje başlatma belgesinde indirme sayısını artırır.

Manifest dosyanızda hizmeti beyan etmeyi unutmayın:

<app ...>
    <service android:name=".SampleDownloaderService" />
    ...
</app>

Alarm alıcısını devreye alma

Dosya indirmelerinin ilerlemesini izlemek ve gerekirse indirme işlemini yeniden başlatmak için DownloaderService, şu işlem için RTC_WAKEUP alarmı planlar: şurada bir BroadcastReceiver için Intent sağlar: uygulamasını indirin. API çağırmak için BroadcastReceiver öğesini tanımlamanız gerekir indirme işleminin durumunu kontrol eden ve yeniden başlatılan İndirici Kitaplığı'ndan gerekebilir.

DownloaderClientMarshaller.startDownloadServiceIfRequired() işlevini çağırmak için onReceive() yöntemini geçersiz kılmanız yeterlidir.

Örnek:

Kotlin

class SampleAlarmReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        try {
            DownloaderClientMarshaller.startDownloadServiceIfRequired(
                    context,
                    intent,
                    SampleDownloaderService::class.java
            )
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
    }
}

Java

public class SampleAlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            DownloaderClientMarshaller.startDownloadServiceIfRequired(context,
                intent, SampleDownloaderService.class);
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Bunun, adını döndürmeniz gereken sınıf olduğuna dikkat edin hizmetinizin getAlarmReceiverClassName() yöntemine (önceki bölüme bakın).

Manifest dosyanızda alıcıyı bildirmeyi unutmayın:

<app ...>
    <receiver android:name=".SampleAlarmReceiver" />
    ...
</app>

İndirme işlemi başlatılıyor

Uygulamanızdaki ana etkinlik (başlatıcı simgenizin başlattığı) genişletme dosyalarının cihazda zaten olup olmadığını doğrulamaktan ve genişletme dosyalarının indirmenin başka bir noktası da yoktur.

İndirme işlemini İndirme Aracı Kitaplığı'nı kullanarak başlatmak için aşağıdakiler gerekir: prosedürler:

  1. Dosyaların indirilip indirilmediğini kontrol edin.

    Downloader Library, aşağıdaki işlemleri yapmak için Helper sınıfındaki bazı API'leri içerir: bu işlemle ilgili yardım almak istiyorum:

    • getExpansionAPKFileName(Context, c, boolean mainFile, int versionCode)
    • doesFileExist(Context c, String fileName, long fileSize)

    Örneğin, APK Genişletme paketinde sağlanan örnek uygulama etkinliğin onCreate() yönteminde aşağıdaki yöntemi izleyerek genişletme dosyalarının cihazda zaten olup olmadığı:

    Kotlin

    fun expansionFilesDelivered(): Boolean {
        xAPKS.forEach { xf ->
            Helpers.getExpansionAPKFileName(this, xf.isBase, xf.fileVersion).also { fileName ->
                if (!Helpers.doesFileExist(this, fileName, xf.fileSize, false))
                    return false
            }
        }
        return true
    }
    

    Java

    boolean expansionFilesDelivered() {
        for (XAPKFile xf : xAPKS) {
            String fileName = Helpers.getExpansionAPKFileName(this, xf.isBase,
                xf.fileVersion);
            if (!Helpers.doesFileExist(this, fileName, xf.fileSize, false))
                return false;
        }
        return true;
    }
    

    Bu durumda, her XAPKFile nesnesi bilinen bir sürümün numarasını ve dosya boyutunu içerir ana genişletme dosyası olup olmadığına dair bir boole dosyası ekleyin. (Örneğe bakın uygulamanın SampleDownloaderActivity sınıfını ziyaret edin.)

    Bu yöntem false (yanlış) değerini döndürürse uygulamanın indirme işlemine başlaması gerekir.

  2. DownloaderClientMarshaller.startDownloadServiceIfRequired(Context c, PendingIntent notificationClient, Class<?> serviceClass) statik yöntemini çağırarak indirme işlemini başlatın.

    Yöntem aşağıdaki parametreleri alır:

    • context: Uygulamanızın Context.
    • notificationClient: Ana sohbetinizi başlatmak için PendingIntent etkinliği'ne dokunun. Bu dil, DownloaderService öğesinin Notification içinde kullanılır. sağlar. Kullanıcı bildirimi seçtiğinde sistem, burada sağladığınız PendingIntent öğesini çağırır ve etkinliği açar Genelde indirme işlemini başlatan etkinlik, indirme işleminin ilerleme durumunu gösterir.
    • serviceClass: Uygulamanız için Class nesnesi DownloaderService, hizmeti başlatmak ve gerekirse indirme işlemini başlatmak için gereklidir.

    Yöntem, şunu belirten bir tam sayı döndürür: gerekli olup olmadığına bağlıdır. Olası değerler:

    • NO_DOWNLOAD_REQUIRED: Dosyalar zaten varsa döndürülür veya zaten bir indirme işlemi devam ediyor.
    • LVL_CHECK_REQUIRED: Lisans doğrulaması şu durumlarda döndürülür için gereklidir.
    • DOWNLOAD_REQUIRED: Genişletme dosyası URL'leri zaten biliniyorsa döndürülür, ancak indirilmedi.

    LVL_CHECK_REQUIRED ve DOWNLOAD_REQUIRED için davranış temelde önemlidir ve normalde bunlarla ilgili endişe duymanıza gerek kalmaz. startDownloadServiceIfRequired() adlı ana etkinliğinizde, yanıtın NO_DOWNLOAD_REQUIRED olup olmadığını kontrol edebilirsiniz. Yanıt NO_DOWNLOAD_REQUIRED dışında bir şeyse İndirme İşlemi kitaplığı indirme işlemini başlatır ve etkinlik kullanıcı arayüzünüzü İndirme işleminin ilerleme durumunu görüntüleyin (sonraki adıma bakın). Yanıt NO_DOWNLOAD_REQUIRED ise, dosyalar kullanılabilir durumda demektir ve uygulamanız başlayabilir.

    Örnek:

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        // Check if expansion files are available before going any further
        if (!expansionFilesDelivered()) {
            val pendingIntent =
                    // Build an Intent to start this activity from the Notification
                    Intent(this, MainActivity::class.java).apply {
                        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
                    }.let { notifierIntent ->
                        PendingIntent.getActivity(
                                this,
                                0,
                                notifierIntent,
                                PendingIntent.FLAG_UPDATE_CURRENT
                        )
                    }
    
    
            // Start the download service (if required)
            val startResult: Int = DownloaderClientMarshaller.startDownloadServiceIfRequired(
                    this,
                    pendingIntent,
                    SampleDownloaderService::class.java
            )
            // If download has started, initialize this activity to show
            // download progress
            if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
                // This is where you do set up to display the download
                // progress (next step)
                ...
                return
            } // If the download wasn't necessary, fall through to start the app
        }
        startApp() // Expansion files are available, start the app
    }
    

    Java

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // Check if expansion files are available before going any further
        if (!expansionFilesDelivered()) {
            // Build an Intent to start this activity from the Notification
            Intent notifierIntent = new Intent(this, MainActivity.getClass());
            notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                                    Intent.FLAG_ACTIVITY_CLEAR_TOP);
            ...
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                    notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
            // Start the download service (if required)
            int startResult =
                DownloaderClientMarshaller.startDownloadServiceIfRequired(this,
                            pendingIntent, SampleDownloaderService.class);
            // If download has started, initialize this activity to show
            // download progress
            if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
                // This is where you do set up to display the download
                // progress (next step)
                ...
                return;
            } // If the download wasn't necessary, fall through to start the app
        }
        startApp(); // Expansion files are available, start the app
    }
    
  3. startDownloadServiceIfRequired() yöntemi başka herhangi bir şey döndürdüğünde ( NO_DOWNLOAD_REQUIRED yerine) tarafından IStub için bir örnek oluşturun DownloaderClientMarshaller.CreateStub(IDownloaderClient client, Class<?> downloaderService) aranıyor. IStub, etkinliğiniz ile indirme aracı arasında bir bağlantı sağlar Böylece etkinliğiniz, indirme işleminin ilerleme durumuyla ilgili geri çağırmalar alır.

    CreateStub() çağrısı yaparak IStub örneğinizi oluşturmak için iletmeniz gerekir IDownloaderClient arayüzü ve DownloaderService uygulama hakkında bilgi edindiniz. İndirme ilerleme durumunu alma ile ilgili bir sonraki bölümde IDownloaderClient arayüzünü içerir. İndirme durumu değiştiğinde etkinlik arayüzünü güncelleyebilmeniz için bunu genellikle Activity sınıfınızda uygulamanız gerekir.

    Etkinliğinizin onCreate() yöntemi sırasında, startDownloadServiceIfRequired() sonrasında IStub örneğinizi oluşturmak için CreateStub() öğesini çağırmanızı öneririz indirme işlemini başlatır.

    Örneğin, onCreate() için önceki kod örneğinde, startDownloadServiceIfRequired() sonucuna şu şekilde yanıt verebilirsiniz:

    Kotlin

            // Start the download service (if required)
            val startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(
                    this@MainActivity,
                    pendingIntent,
                    SampleDownloaderService::class.java
            )
            // If download has started, initialize activity to show progress
            if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
                // Instantiate a member instance of IStub
                downloaderClientStub =
                        DownloaderClientMarshaller.CreateStub(this, SampleDownloaderService::class.java)
                // Inflate layout that shows download progress
                setContentView(R.layout.downloader_ui)
                return
            }
    

    Java

            // Start the download service (if required)
            int startResult =
                DownloaderClientMarshaller.startDownloadServiceIfRequired(this,
                            pendingIntent, SampleDownloaderService.class);
            // If download has started, initialize activity to show progress
            if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
                // Instantiate a member instance of IStub
                downloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
                        SampleDownloaderService.class);
                // Inflate layout that shows download progress
                setContentView(R.layout.downloader_ui);
                return;
            }
    

    onCreate() yöntemi geri geldikten sonra etkinliğiniz onResume() numaralı telefona bir arama aldığında IStub numaralı telefondan connect() adlı kişiyi uygulamanızın Context cihazına iletin. Öte yandan, Etkinliğinizin onStop() geri aramasında disconnect().

    Kotlin

    override fun onResume() {
        downloaderClientStub?.connect(this)
        super.onResume()
    }
    
    override fun onStop() {
        downloaderClientStub?.disconnect(this)
        super.onStop()
    }
    

    Java

    @Override
    protected void onResume() {
        if (null != downloaderClientStub) {
            downloaderClientStub.connect(this);
        }
        super.onResume();
    }
    
    @Override
    protected void onStop() {
        if (null != downloaderClientStub) {
            downloaderClientStub.disconnect(this);
        }
        super.onStop();
    }
    

    IStub üzerinde connect() çağrılarının yapılması, etkinliğinizi DownloaderService öğesine bağlar ve böylece etkinliğiniz indirmede yapılan değişikliklerle ilgili geri çağırmalar alır IDownloaderClient arayüzü üzerinden görebilirsiniz.

İndirme ilerleme durumu alınıyor

İndirme işleminin ilerleme durumuyla ilgili güncellemeleri almak ve DownloaderService ile etkileşimde bulunmak için İndirme Aracı Kitaplığı'nın IDownloaderClient arayüzünü uygulamanız gerekir. İndirme işlemini başlatmak için kullandığınız etkinlik genellikle indirme durumunu görüntüleme ve hizmete istek gönderme.

IDownloaderClient için gerekli arayüz yöntemleri şunlardır:

onServiceConnected(Messenger m)
Etkinliğinizde IStub örneğini oluşturduktan sonra yöntemidir; bu yöntem, örneğinize bağlı bir Messenger nesnesi aktarır / DownloaderService. Hizmete istek göndermek (ör. duraklatma ve devam ettirme) hizmete bağlı IDownloaderService arayüzünü almak için DownloaderServiceMarshaller.CreateProxy() işlevini çağırmalısınız.

Önerilen uygulama aşağıdaki gibi görünür:

Kotlin

private var remoteService: IDownloaderService? = null
...

override fun onServiceConnected(m: Messenger) {
    remoteService = DownloaderServiceMarshaller.CreateProxy(m).apply {
        downloaderClientStub?.messenger?.also { messenger ->
            onClientUpdated(messenger)
        }
    }
}

Java

private IDownloaderService remoteService;
...

@Override
public void onServiceConnected(Messenger m) {
    remoteService = DownloaderServiceMarshaller.CreateProxy(m);
    remoteService.onClientUpdated(downloaderClientStub.getMessenger());
}

IDownloaderService nesnesi başlatıldığında, komutlarını şuraya gönderebilirsiniz: indirme hizmetini kullanabilirsiniz. Örneğin, indirme işlemini duraklatabilir veya devam ettirebilirsiniz (requestPauseDownload() ve requestContinueDownload()).

onDownloadStateChanged(int newState)
İndirme durumunda bir değişiklik gerçekleştiğinde indirme hizmeti bu çağrıyı çağırır. Örneğin: indirme işlemi başladığında veya tamamlandığında.

newState değeri, IDownloaderClient sınıfının STATE_* sabitlerinden birine göre.

Kullanıcılarınıza faydalı bir mesaj sunmak için ilgili bir dize isteyebilirsiniz her eyalet için Helpers.getDownloaderStringResourceIDFromState() çağırarak yapabilirsiniz. Bu İndirme Aracı ile paket halinde sunulan dizelerden birinin kaynak kimliğini döndürür Kitaplık'a dokunun. Örneğin, "Dolaşımda olduğunuz için indirme duraklatıldı" dizesi STATE_PAUSED_ROAMING değerine karşılık gelir.

onDownloadProgress(DownloadProgressInfo progress)
İndirme hizmeti, DownloadProgressInfo nesnesini teslim etmek için bu komutu Bu sayfada, kalan tahmini süre de dahil olmak üzere indirme işleminin ilerlemesiyle ilgili mevcut hız, genel ilerleme durumu ve toplam bilgilerini kullanarak indirme ilerleme durumunu güncelleyebilirsiniz.

İpucu: İndirme işlemini güncelleyen geri çağırma örnekleri için ilerleme kullanıcı arayüzü içinSampleDownloaderActivity APK Genişletme paketi.

IDownloaderService arayüzü için yararlı bulabileceğiniz bazı herkese açık yöntemler şunlardır:

requestPauseDownload()
İndirme işlemini duraklatır.
requestContinueDownload()
Duraklatılmış indirme işlemini devam ettirir.
setDownloadFlags(int flags)
Dosyaların indirilebileceği ağ türleri için kullanıcı tercihlerini ayarlar. İlgili içeriği oluşturmak için kullanılan mevcut uygulama bir işareti (FLAGS_DOWNLOAD_OVER_CELLULAR) desteklemektedir, ancak diğerleri. Varsayılan olarak bu bayrak etkin değildir, bu nedenle indirme işlemi için kullanıcının kablosuz ağa bağlı olması gerekir genişletme dosyalarını kullanabilirsiniz. İndirmeleri etkinleştirmek için bir kullanıcı tercihi belirtmek isteyebilirsiniz hücresel şebeke. Bu durumda şu numarayı arayabilirsiniz:

Kotlin

remoteService = DownloaderServiceMarshaller.CreateProxy(m).apply {
    ...
    setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR)
}

Java

remoteService
    .setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR);

APKExpansionPolicy'yi Kullanma

Google Play Store'u kullanmak yerine kendi indirme hizmetinizi oluşturmaya karar verirseniz İndirici Kitaplığı'nı kullanıyorsanız yine de Lisans Doğrulama Kitaplığı'nda sağlanan APKExpansionPolicy kodunu kullanmanız gerekir. APKExpansionPolicy sınıfı ServerManagedPolicy ile neredeyse aynıdır (şurada mevcuttur: Google Play Lisans Doğrulama Kitaplığı) ancak APK genişletmesi için ek işlem içerir dosya yanıtı ekstraları.

Not: Önceki bölümde açıklandığı gibi İndirici Kitaplığı'nı kullanırsanız kitaplığının APKExpansionPolicy ile tüm etkileşimini sağladığından bu sınıfa doğrudan göz atın.

Bu sınıfta, mevcut ve açık kaynaklarla ilgili gerekli bilgileri edinmenize genişletme dosyaları:

  • getExpansionURLCount()
  • getExpansionURL(int index)
  • getExpansionFileName(int index)
  • getExpansionFileSize(int index)

olmadığınızda APKExpansionPolicy hizmetini nasıl kullanacağınız hakkında daha fazla bilgi İndirici Kitaplığı'nı kullanarak Uygulamanıza Lisans Ekleme dokümanlarına bakın, Burada, bunun gibi bir lisans politikasının nasıl uygulanacağını bulabilirsiniz.

Genişletme Dosyasını Okuma

APK genişletme dosyalarınız cihaza kaydedildikten sonra, dosyalarınızı nasıl okuduğunuz kullandığınız dosyanın türüne bağlıdır. Genel bakış bölümünde belirtildiği gibi, genişletme dosyaları, sahip olduğunuz herhangi bir dosya olabilir. ister ancak belirli bir dosya adı biçimi kullanılarak yeniden adlandırılır ve <shared-storage>/Android/obb/<package-name>/.

Dosyalarınızı nasıl okuduğunuzdan bağımsız olarak, her zaman öncelikle harici okuma için kullanılabilir. Kullanıcının depolama alanını ya da SD kartı çıkarmıştır.

Not: Uygulamanız başlatıldığında her zaman harici depolama alanının kullanılabilir ve okunabilir olması için getExternalStorageState() çağrılır. Bu, birkaç olası dizeden birini döndürür belirten bir e-posta alırsınız. Sitenizin Google tarafından okunabilmesi için uygulaması için döndürülen değer MEDIA_MOUNTED olmalıdır.

Dosya adları alınıyor

Genel bakış bölümünde açıklandığı gibi, APK genişletme dosyalarınız kaydedilir belirli bir dosya adı biçimi kullanarak:

[main|patch].<expansion-version>.<package-name>.obb

Genişletme dosyalarınızın konumunu ve adlarını almak için Dosyalarınızın yolunu oluşturmak için getExternalStorageDirectory() ve getPackageName() yöntemlerini kullanın.

Tam yolu içeren bir diziyi almak için uygulamanızda kullanabileceğiniz bir yöntem aşağıda verilmiştir eklemek için:

Kotlin

fun getAPKExpansionFiles(ctx: Context, mainVersion: Int, patchVersion: Int): Array<String> {
    val packageName = ctx.packageName
    val ret = mutableListOf<String>()
    if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
        // Build the full path to the app's expansion files
        val root = Environment.getExternalStorageDirectory()
        val expPath = File(root.toString() + EXP_PATH + packageName)

        // Check that expansion file path exists
        if (expPath.exists()) {
            if (mainVersion > 0) {
                val strMainPath = "$expPath${File.separator}main.$mainVersion.$packageName.obb"
                val main = File(strMainPath)
                if (main.isFile) {
                    ret += strMainPath
                }
            }
            if (patchVersion > 0) {
                val strPatchPath = "$expPath${File.separator}patch.$mainVersion.$packageName.obb"
                val main = File(strPatchPath)
                if (main.isFile) {
                    ret += strPatchPath
                }
            }
        }
    }
    return ret.toTypedArray()
}

Java

// The shared path to all app expansion files
private final static String EXP_PATH = "/Android/obb/";

static String[] getAPKExpansionFiles(Context ctx, int mainVersion,
      int patchVersion) {
    String packageName = ctx.getPackageName();
    Vector<String> ret = new Vector<String>();
    if (Environment.getExternalStorageState()
          .equals(Environment.MEDIA_MOUNTED)) {
        // Build the full path to the app's expansion files
        File root = Environment.getExternalStorageDirectory();
        File expPath = new File(root.toString() + EXP_PATH + packageName);

        // Check that expansion file path exists
        if (expPath.exists()) {
            if ( mainVersion > 0 ) {
                String strMainPath = expPath + File.separator + "main." +
                        mainVersion + "." + packageName + ".obb";
                File main = new File(strMainPath);
                if ( main.isFile() ) {
                        ret.add(strMainPath);
                }
            }
            if ( patchVersion > 0 ) {
                String strPatchPath = expPath + File.separator + "patch." +
                        mainVersion + "." + packageName + ".obb";
                File main = new File(strPatchPath);
                if ( main.isFile() ) {
                        ret.add(strPatchPath);
                }
            }
        }
    }
    String[] retArray = new String[ret.size()];
    ret.toArray(retArray);
    return retArray;
}

Bu yöntemi, uygulamanıza Context ileterek çağırabilirsiniz ve istenen genişletme dosyasının sürümü.

Genişletme dosyası sürüm numarasını belirlemenin birçok yolu vardır. Basit bir yol, indirme işlemi başladığında sürümü bir SharedPreferences dosyasına kaydetmek için APKExpansionPolicy sınıfının getExpansionFileName(int index) yöntemiyle genişletme dosyası adını sorgulamak. Daha sonra, genişletmeye erişmek istediğinizde SharedPreferences dosyasını okuyarak sürüm kodunu alabilirsiniz dosyası olarak kaydedebilirsiniz.

Paylaşılan depolama alanından okuma hakkında daha fazla bilgi için Veri Depolama sayfasına bakın. belgelerinden faydalanabilirsiniz.

APK Genişletmesi Zip Kitaplığı'nı kullanma

Google Market Apk Genişletme paketi, APK adlı bir kitaplık içerir. Genişletme Zip Kitaplığı (<sdk>/extras/google/google_market_apk_expansion/zip_file/ konumundadır). Bu kitaplık, isteğe bağlı genişletmenizi okumanıza yardımcı olur kaydedildiklerinden emin olun. Bu kitaplığı kullanarak şuradaki kaynakları kolayca okuyabilirsiniz: sanal bir dosya sistemi haline getirin.

APK Genişletme Zip Kitaplığı aşağıdaki sınıfları ve API'leri içerir:

APKExpansionSupport
Genişletme dosya adlarına ve ZIP dosyalarına erişmek için bazı yöntemler sunar:
getAPKExpansionFiles()
Yukarıda gösterilen ve her iki genişletmeye ait tam dosya yolunu döndüren yöntem dosyası olarak da kaydedebilir.
getAPKExpansionZipFile(Context ctx, int mainVersion, int patchVersion)
Hem ana dosyanın hem de dosyanın toplamını temsil eden bir ZipResourceFile döndürür yama dosyası olarak kaydeder. Yani hem mainVersion hem de patchVersion ise bu, şunlar için okuma erişimi sağlayan bir ZipResourceFile döndürür: tüm veriler, yama dosyasının verileri ana dosyanın üzerinde birleştirilir.
ZipResourceFile
Paylaşılan depolama alanındaki bir ZIP dosyasını temsil eder ve tüm işi sanal bir dosya sistemi oluşturmayı öğreneceksiniz. APKExpansionSupport.getAPKExpansionZipFile() kullanarak veya ZipResourceFile ile yolu. Bu ders, birçok faydalı yöntem içerir ancak çoğuna erişmeleri gerekmez. Önemli yöntemlerden bazıları şunlardır:
getInputStream(String assetPath)
ZIP dosyasındaki bir dosyayı okumak için bir InputStream sağlar. İlgili içeriği oluşturmak için kullanılan assetPath, kök dizin.
getAssetFileDescriptor(String assetPath)
AssetFileDescriptor ZIP dosyası olarak kaydedin. assetPath, kök dizin. Bu özellik, bazı MediaPlayer API'leri gibi AssetFileDescriptor gerektiren belirli Android API'leri için kullanışlıdır.
APEZProvider
Çoğu uygulamanın bu sınıfı kullanması gerekmez. Bu sınıf, ZIP dosyalarındaki verileri bir içerik aracılığıyla sıralayan bir ContentProvider tanımlar sağlayan belirli Android API'lerine dosya erişimi sağlamak için Uri medya dosyalarına Uri erişimi bekleniyor. Örneğin, bu ifadenin VideoView.setVideoURI() ile bir video oynatın.

Medya dosyalarının ZIP sıkıştırması atlanıyor

Medya dosyalarını depolamak için genişletme dosyalarınızı kullanıyorsanız, bir ZIP dosyası yine de şunları yapmanıza olanak tanır: ofset ve uzunluk kontrolleri sağlayan Android medya oynatma çağrılarını (ör. MediaPlayer.setDataSource() ve SoundPool.load()) tıklayın. Bu amaçla çalışmak için ZIP dosyasını oluştururken medya dosyalarında ek sıkıştırma işlemi uygulamamanız gerekir pakettir. Örneğin, zip aracını kullanırken -n seçeneğini kullanın:

zip -n .mp4;.ogg main_expansion media_files

ZIP dosyasından okuma

APK Genişletme Zip Kitaplığı'nı kullanırken ZIP dosyanızdan bir dosyayı okumak genellikle takip etmek için:

Kotlin

// Get a ZipResourceFile representing a merger of both the main and patch files
val expansionFile =
        APKExpansionSupport.getAPKExpansionZipFile(appContext, mainVersion, patchVersion)

// Get an input stream for a known file inside the expansion file ZIPs
expansionFile.getInputStream(pathToFileInsideZip).use {
    ...
}

Java

// Get a ZipResourceFile representing a merger of both the main and patch files
ZipResourceFile expansionFile =
    APKExpansionSupport.getAPKExpansionZipFile(appContext,
        mainVersion, patchVersion);

// Get an input stream for a known file inside the expansion file ZIPs
InputStream fileStream = expansionFile.getInputStream(pathToFileInsideZip);

Yukarıdaki kod, ana genişletme dosyanızda veya dosyasını kullanarak her iki dosyadaki tüm dosyaların birleştirilmiş bir haritasından okuma yapabilirsiniz. Tek yapmanız gereken getAPKExpansionFile() yöntemini sağlamanız gerekir: uygulamanız android.content.Context ve hem ana genişletme dosyası hem de yamanın sürüm numarası genişletme dosyası olarak gönderin.

Belirli bir genişletme dosyasından okumayı tercih ederseniz istenen genişletme dosyasının yoluyla ZipResourceFile oluşturucuyu kullanabilirsiniz:

Kotlin

// Get a ZipResourceFile representing a specific expansion file
val expansionFile = ZipResourceFile(filePathToMyZip)

// Get an input stream for a known file inside the expansion file ZIPs
expansionFile.getInputStream(pathToFileInsideZip).use {
    ...
}

Java

// Get a ZipResourceFile representing a specific expansion file
ZipResourceFile expansionFile = new ZipResourceFile(filePathToMyZip);

// Get an input stream for a known file inside the expansion file ZIPs
InputStream fileStream = expansionFile.getInputStream(pathToFileInsideZip);

Genişletme dosyalarınızda bu kitaplığı kullanma hakkında daha fazla bilgi için örnek uygulamanın SampleDownloaderActivity sınıfını kullanabilirsiniz. Bu sınıf, indirilen dosyaları CRC'yi kullanarak doğrulamalıdır. Bu örneği proje başlatma belgesine dayalı olarak kendiniz uygulamanız için, genişletmenizin bayt boyutunu dosyaları xAPKS dizisinde gösterilir.

Genişletme Dosyalarınızı Test Etme

Uygulamanızı yayınlamadan önce test etmeniz gereken iki şey vardır: genişletme dosyalarını ve dosyaları indirmenizi sağlar.

Dosya okumalarını test etme

Uygulamanızı Google Play'e yüklemeden önce uygulamanızın, paylaşılan depolama alanındaki dosyaları okuma yeteneğini test etmesi gerekir. Tek yapmanız gereken dosyaları cihazın paylaşılan depolama alanındaki uygun konuma eklemek ve uygulama:

  1. Cihazınızda, paylaşılan depolama alanında Google'ın Play, dosyalarınızı kaydedecek.

    Örneğin, paketinizin adı com.example.android ise paylaşılan depolama alanında Android/obb/com.example.android/ dizini. (Fiş paylaşılan depolama birimini eklemek ve bunu manuel olarak oluşturmak için test cihazınızı bilgisayarınıza dizinine ekleyin.)

  2. Genişletme dosyalarını bu dizine manuel olarak ekleyin. Dosyalarınızı şu şekilde yeniden adlandırdığınızdan emin olun: Google Play'in kullanacağı dosya adı biçimiyle eşleşmelidir.

    Örneğin, dosya türünden bağımsız olarak com.example.android uygulamasının ana genişletme dosyası main.0300110.com.example.android.obb olmalıdır. Sürüm kodu, istediğiniz herhangi bir değer olabilir. Unutmayın:

    • Ana genişletme dosyası her zaman main ile, yama dosyası ise patch.
    • Paket adı, her zaman dosyanın ekli olduğu APK'nın adıyla eşleşir Google Play
  3. Genişletme dosyaları cihazda bulunduğuna göre, aşağıdaki işlemleri yapmak için uygulamanızı yükleyip çalıştırabilirsiniz: genişletme dosyalarınızı test edin.

Genişletme dosyalarının işlenmesiyle ilgili bazı hatırlatıcıları burada bulabilirsiniz:

  • .obb genişletme dosyalarını silmeyin veya yeniden adlandırmayın (paketi açsanız bile verileri farklı bir konuma taşıma). Bunu yaptığınızda Google Play (veya uygulamanızın kendisi) genişletme dosyasını tekrar tekrar indirmek.
  • obb/ cihazınıza başka veriler kaydetmeyin dizininde bulunduğundan emin olun. Bazı verilerin paketini açmanız gerekiyorsa verileri getExternalFilesDir() ile belirtilen konuma kaydedin.

Dosya indirmelerini test etme

Çünkü bu işlemi ilk kez yaparken uygulamanızın bazen genişletme dosyalarını manuel olarak indirmesi gerekir bu işlemi test etmeniz ve uygulamanızın bu sorguda başarılı bir şekilde sorgu gönderebildiğinden dosyaları indirin ve cihaza kaydedin.

Uygulamanızda manuel indirme prosedürünü test etmek için dahili test kanalına yayınlayabilir ve böylece yalnızca yetkili test kullanıcıları. Her şey beklendiği gibi çalışıyorsa uygulamanız ana etkinlik başlar başlamaz genişletme dosyalarını indirmeye başlar.

Not: Önceden uygulamaları aşağıdaki ölçütlere göre test edebiliyordunuz: yayınlanmamış bir "taslak" yükleme sürümünü değil. Bu işlev artık devre dışı desteklenir. Bunun yerine, testinizi dahili, kapalı veya açık test kanalına yayınlamanız gerekir. plan yapar ve değişiklikleri uygular. Daha fazla bilgi için bkz. Taslak Uygulamalar Hayır Daha Uzun Süreli Desteklenir.

Uygulamanız güncelleniyor

Google Play'de genişletme dosyalarını kullanmanın en büyük avantajlarından biri de uygulamanızı güncellemeye devam edin. Google Play her APK ile iki genişletme dosyası sağlamanıza olanak tanır; ikinci dosyayı "yama" olarak kullanabilirsiniz güncellemeleri ve yeni öğeleri sağlar. Bu işlem, kullanıcılar için büyük ve pahalı olabilecek ana genişletme dosyasını yeniden indirmeniz gerekebilir.

Yama genişletme dosyası teknik olarak ana genişletme dosyasıyla aynıdır ve Android sistemi veya Google Play, ana ve yama genişletmeniz arasında gerçek yama işlemi gerçekleştirir. dosyası olarak da kaydedebilir. Uygulama kodunuz gerekli tüm yamaları uygulamalıdır.

Genişletme dosyalarınız olarak ZIP dosyalarını kullanıyorsanız APK Genişletme Sıklığı APK Genişletme paketine dahil olan Kitaplık'ta birleştirme ve sizin yama dosyası oluşturun.

Not: Yalnızca yamada değişiklik yapmanız gerekse bile genişletme dosyasını kullanıyorsanız Google Play'in güncelleme gerçekleştirmesi için APK'yı yine de güncellemeniz gerekir. Uygulamada kod değişikliği gerekmiyorsa versionCode öğesini (uygulamada) manifest'ini kullanabilirsiniz.

APK ile ilişkilendirilmiş ana genişletme dosyasını değiştirmediğiniz sürece Play Console'da, uygulamanızı daha önce yüklemiş olan kullanıcılar ana genişletme dosyasını indirin. Mevcut kullanıcılar yalnızca güncellenen APK'yı ve yeni yamayı alır. genişletme dosyasını (önceki ana genişletme dosyasını korur).

Genişletme dosyalarında yapılan güncellemelerle ilgili unutulmaması gereken birkaç sorun aşağıda belirtilmiştir:

  • Uygulamanız için aynı anda yalnızca iki genişletme dosyası olabilir. Bir ana genişletme dosyası ve bir yama genişletme dosyası var. Bir dosya güncellendiğinde Google Play, (ve manuel güncellemeler yaparken uygulamanız da öyle olmalıdır).
  • Bir yama genişletme dosyası eklediğinizde Android sistemi, ana genişletme dosyası oluşturun. Uygulamanızı yama verilerini destekleyecek şekilde tasarlamanız gerekir. Ancak APK Genişletme paketinde ZIP dosyalarını kullanmak için bir kitaplık bulunur Bu dosya, yama dosyasındaki verileri ana genişletme dosyasında birleştirir. Böylece, tüm genişletme dosyası verilerini kolayca okuyabilirsiniz.
ziyaret edin.