Java kodunuzdan uygulamanızın öğe paketlerine erişmek için bu kılavuzdaki adımları kullanın.
Kotlin ve Java için uygulama geliştirme
Play Asset Delivery'yi projenizin Android App Bundle'ına eklemek için aşağıdaki adımları uygulayın. Bu adımları uygulamak için Android Studio'yu kullanmanız gerekmez.
Projenizin
build.gradle
dosyasındaki Android Gradle eklentisinin sürümünü4.0.0
veya sonraki bir sürüme güncelleyin.Projenizin en üst düzey dizininde, öğe paketi için bir dizin oluşturun. Bu dizin adı, öğe paketi adı olarak kullanılıyor. Öğe paketi adları harfle başlamalıdır ve yalnızca harf, sayı ve alt çizgi içerebilir.
Öğe paketi dizininde, bir
build.gradle
dosyası oluşturun ve aşağıdaki kodu ekleyin. Öğe paketinin adını ve yalnızca bir gönderim türünü belirttiğinizden emin olun:Eski
// In the asset pack's build.gradle file: plugins { id 'com.android.asset-pack' } assetPack { packName = "asset-pack-name" // Directory name for the asset pack dynamicDelivery { deliveryType = "[ install-time | fast-follow | on-demand ]" } }
Kotlin
// In the asset pack's build.gradle.kts file: plugins { id("com.android.asset-pack") } assetPack { packName.set("asset-pack-name") // Directory name for the asset pack dynamicDelivery { deliveryType.set("[ install-time | fast-follow | on-demand ]") } }
Projenin uygulamasındaki
build.gradle
dosyasına, projenizdeki her öğe paketinin adını aşağıda gösterildiği gibi ekleyin:Eski
// In the app build.gradle file: android { ... assetPacks = [":asset-pack-name", ":asset-pack2-name"] }
Kotlin
// In the app build.gradle.kts file: android { ... assetPacks += listOf(":asset-pack-name", ":asset-pack2-name") }
Projenin
settings.gradle
dosyasına, aşağıda gösterildiği gibi projenizdeki tüm öğe paketlerini ekleyin:Eski
// In the settings.gradle file: include ':app' include ':asset-pack-name' include ':asset-pack2-name'
Kotlin
// In the settings.gradle.kts file: include(":app") include(":asset-pack-name") include(":asset-pack2-name")
Öğe paketi dizininde aşağıdaki alt dizini oluşturun:
src/main/assets
.Öğeleri
src/main/assets
dizinine yerleştirin. Burada da alt dizinler oluşturabilirsiniz. Uygulamanızın dizin yapısı aşağıdaki gibi görünecektir:build.gradle
settings.gradle
app/
asset-pack-name/build.gradle
asset-pack-name/src/main/assets/your-asset-directories
Gradle ile Android App Bundle'ı oluşturun. Oluşturulan uygulama paketinde, kök düzeyindeki dizin artık aşağıdakileri içerir:
asset-pack-name/manifest/AndroidManifest.xml
: Öğe paketinin tanımlayıcısını ve iletim modunu yapılandırırasset-pack-name/assets/your-asset-directories
: Öğe paketinin bir parçası olarak yayınlanan tüm öğeleri içeren dizin
Gradle, her öğe paketi için manifest oluşturur ve
assets/
dizinini sizin için oluşturur.(İsteğe bağlı) Hızlı takip ve isteğe bağlı yayınlama kullanmayı planlıyorsanız Play Asset Delivery Kitaplığı'nı ekleyin.
Eski
implementation "com.google.android.play:asset-delivery:2.2.2" // For Kotlin use asset-delivery-ktx implementation "com.google.android.play:asset-delivery-ktx:2.2.2"
Kotlin
implementation("com.google.android.play:asset-delivery:2.2.2") // For Kotlin use core-ktx implementation("com.google.android.play:asset-delivery-ktx:2.2.2")
(İsteğe bağlı) Uygulama paketinizi farklı doku sıkıştırma biçimlerini destekleyecek şekilde yapılandırın.
Play Asset Delivery API ile entegrasyon
Play Asset Delivery Java API, öğe paketleri isteme, indirmeleri yönetme ve öğelere erişim için AssetPackManager
sınıfını sağlar. Önce projenize Play Asset Delivery Kitaplığı'nı eklediğinizden emin olun.
Bu API'yi, erişmek istediğiniz öğe paketinin yayınlanma türüne göre uygularsınız. Bu adımlar aşağıdaki akış şemasında gösterilmektedir.
Yükleme zamanında teslimat
install-time
olarak yapılandırılan öğe paketleri, uygulama kullanıma sunulduğu anda kullanılabilir. Bu modda sunulan öğelere erişmek için Java AssetManager API'yi kullanın:
Kotlin
import android.content.res.AssetManager ... val context: Context = createPackageContext("com.example.app", 0) val assetManager: AssetManager = context.assets val stream: InputStream = assetManager.open("asset-name")
Java
import android.content.res.AssetManager; ... Context context = createPackageContext("com.example.app", 0); AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open("asset-name");
Hızlı takip ve isteğe bağlı teslimat
Aşağıdaki bölümlerde, öğe paketleriyle ilgili indirmeden önce nasıl bilgi alınacağı, indirme işlemini başlatmak için API'nin nasıl çağrılacağı ve indirilen paketlere nasıl erişileceği gösterilmektedir. Bu bölümler fast-follow
ve on-demand
öğe paketleri için geçerlidir.
Durumu denetle
Her öğe paketi, uygulamanın dahili depolama alanında ayrı bir klasörde depolanır.
Bir öğe paketinin kök klasörünü belirlemek için getPackLocation()
yöntemini kullanın. Bu yöntem aşağıdaki değerleri döndürür:
Döndürülen değer | Durum |
---|---|
Geçerli bir AssetPackLocation nesnesi |
Öğe paketi kök klasörüne assetsPath() adresinden hemen erişebilirsiniz |
null |
Bilinmeyen öğe paketi veya öğeler kullanılamıyor |
Öğe paketleriyle ilgili indirme bilgilerini alma
Uygulamaların, öğe paketini getirmeden önce indirme boyutunu bildirmesi gerekir. İndirme boyutunu ve paketin halihazırda indirilip indirilmediğini belirlemek için requestPackStates()
veya getPackStates()
yöntemini kullanın.
Kotlin
suspend fun requestPackStates(packNames: List<String>): AssetPackStates
Java
Task<AssetPackStates> getPackStates(List<String> packNames)
requestPackStates()
, AssetPackStates
nesnesi döndüren bir askıya alma işlevidir. getPackStates()
ise Task<AssetPackStates>
değeri döndüren eşzamansız bir yöntemdir. Bir AssetPackStates
nesnesinin packStates()
yöntemi Map<String,
AssetPackState>
döndürür. Bu eşleme, istenen her bir öğe paketinin durumunu,
adıyla kodlanmış şekilde içerir:
Kotlin
AssetPackStates#packStates(): Map<String, AssetPackState>
Java
Map<String, AssetPackState> AssetPackStates#packStates()
Nihai istek aşağıdaki bilgilerde gösterilir:
Kotlin
const val assetPackName = "assetPackName" coroutineScope.launch { try { val assetPackStates: AssetPackStates = manager.requestPackStates(listOf(assetPackName)) val assetPackState: AssetPackState = assetPackStates.packStates()[assetPackName] } catch (e: RuntimeExecutionException) { Log.d("MainActivity", e.message) } }
Java
final String assetPackName = "myasset"; assetPackManager .getPackStates(Collections.singletonList(assetPackName)) .addOnCompleteListener(new OnCompleteListener<AssetPackStates>() { @Override public void onComplete(Task<AssetPackStates> task) { AssetPackStates assetPackStates; try { assetPackStates = task.getResult(); AssetPackState assetPackState = assetPackStates.packStates().get(assetPackName); } catch (RuntimeExecutionException e) { Log.d("MainActivity", e.getMessage()); return; })
Aşağıdaki AssetPackState
yöntemlerinde, öğe paketinin boyutu, şu ana kadar indirilen tutar (istenirse) ve uygulamaya zaten aktarılmış olan tutar sağlanır:
Bir öğe paketinin durumunu öğrenmek için durumu AssetPackStatus
sınıfındaki sabit bir alana karşılık gelen bir tam sayı olarak döndüren status()
yöntemini kullanın. Henüz yüklenmeyen bir öğe paketi AssetPackStatus.NOT_INSTALLED
durumunda.
Bir istek başarısız olursa döndürülen değeri AssetPackErrorCode
sınıfında sabit bir alana karşılık gelen errorCode()
yöntemini kullanın.
Yükle
Bir öğe paketini ilk kez indirmek için requestFetch()
veya fetch()
yöntemini kullanın ya da bir öğe paketinin güncellenmesini isteyin:
Kotlin
suspend fun AssetPackManager.requestFetch(packs: List<String>): AssetPackStates
Java
Task<AssetPackStates> fetch(List<String> packNames)
Bu yöntem, paketlerin listesi ile başlangıçtaki indirme durumlarını ve boyutlarını içeren bir AssetPackStates
nesnesi döndürür.
requestFetch()
veya fetch()
aracılığıyla istenen bir öğe paketi zaten indiriliyorsa indirme durumu döndürülür ve başka bir indirme işlemi başlatılmaz.
İndirme durumlarını izle
Öğe paketlerinin yükleme ilerlemesini takip etmek için AssetPackStateUpdatedListener
uygulamanız gerekir. Durum güncellemeleri, tek tek öğe paketlerinin durumunun izlenmesini desteklemek için paket bazında ayrılmıştır. İsteğiniz için diğer tüm indirmeler tamamlanmadan önce mevcut öğe paketlerini kullanmaya başlayabilirsiniz.
Kotlin
fun registerListener(listener: AssetPackStateUpdatedListener) fun unregisterListener(listener: AssetPackStateUpdatedListener)
Java
void registerListener(AssetPackStateUpdatedListener listener) void unregisterListener(AssetPackStateUpdatedListener listener)
Büyük boyutlu indirme işlemleri
İndirme işlemi 200 MB'tan büyükse ve kullanıcı kablosuz ağa bağlı değilse indirme işlemi, kullanıcı bir mobil veri bağlantısı kullanarak indirme işlemine devam etmek için açıkça izin verene kadar başlamaz. Benzer şekilde, indirme boyutu büyükse ve kullanıcı kablosuz ağı kaybederse indirme işlemi duraklatılır ve mobil veri bağlantısı kullanarak devam etmek için açık izin gerekir. Duraklatılmış bir paket
WAITING_FOR_WIFI
durumunda. Kullanıcı rızası isteme amacıyla kullanıcı arayüzü akışını tetiklemek için showConfirmationDialog()
yöntemini kullanın.
Uygulama bu yöntemi çağırmıyorsa indirme işlemi duraklatılır ve yalnızca kullanıcı tekrar bir kablosuz ağa bağlandığında otomatik olarak devam eder.
Zorunlu kullanıcı onayı
Bir paketin durumu REQUIRES_USER_CONFIRMATION
ise kullanıcı, showConfirmationDialog()
ile birlikte gösterilen iletişim kutusunu kabul edene kadar indirme işlemi devam etmez.
Bu durum, uygulama Play tarafından tanınmadığında (örneğin, uygulama başka cihazdan yüklenmişse) ortaya çıkabilir.
Bu durumda showConfirmationDialog()
çağrısının, uygulamanın güncellenmesine neden olacağını unutmayın. Güncellemeden sonra öğeleri
tekrar istemeniz gerekir.
Aşağıda, bir işleyici uygulamasına örnek verilmiştir:
Kotlin
private val activityResultLauncher = registerForActivityResult( ActivityResultContracts.StartIntentSenderForResult() ) { result -> if (result.resultCode == RESULT_OK) { Log.d(TAG, "Confirmation dialog has been accepted.") } else if (result.resultCode == RESULT_CANCELED) { Log.d(TAG, "Confirmation dialog has been denied by the user.") } } assetPackManager.registerListener { assetPackState -> when(assetPackState.status()) { AssetPackStatus.PENDING -> { Log.i(TAG, "Pending") } AssetPackStatus.DOWNLOADING -> { val downloaded = assetPackState.bytesDownloaded() val totalSize = assetPackState.totalBytesToDownload() val percent = 100.0 * downloaded / totalSize Log.i(TAG, "PercentDone=" + String.format("%.2f", percent)) } AssetPackStatus.TRANSFERRING -> { // 100% downloaded and assets are being transferred. // Notify user to wait until transfer is complete. } AssetPackStatus.COMPLETED -> { // Asset pack is ready to use. Start the game. } AssetPackStatus.FAILED -> { // Request failed. Notify user. Log.e(TAG, assetPackState.errorCode()) } AssetPackStatus.CANCELED -> { // Request canceled. Notify user. } AssetPackStatus.WAITING_FOR_WIFI, AssetPackStatus.REQUIRES_USER_CONFIRMATION -> { if (!confirmationDialogShown) { assetPackManager.showConfirmationDialog(activityResultLauncher); confirmationDialogShown = true } } AssetPackStatus.NOT_INSTALLED -> { // Asset pack is not downloaded yet. } AssetPackStatus.UNKNOWN -> { Log.wtf(TAG, "Asset pack status unknown") } } }
Java
assetPackStateUpdateListener = new AssetPackStateUpdateListener() { private final ActivityResultLauncher<IntentSenderRequest> activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { if (result.getResultCode() == RESULT_OK) { Log.d(TAG, "Confirmation dialog has been accepted."); } else if (result.getResultCode() == RESULT_CANCELED) { Log.d(TAG, "Confirmation dialog has been denied by the user."); } } }); @Override public void onStateUpdate(AssetPackState assetPackState) { switch (assetPackState.status()) { case AssetPackStatus.PENDING: Log.i(TAG, "Pending"); break; case AssetPackStatus.DOWNLOADING: long downloaded = assetPackState.bytesDownloaded(); long totalSize = assetPackState.totalBytesToDownload(); double percent = 100.0 * downloaded / totalSize; Log.i(TAG, "PercentDone=" + String.format("%.2f", percent)); break; case AssetPackStatus.TRANSFERRING: // 100% downloaded and assets are being transferred. // Notify user to wait until transfer is complete. break; case AssetPackStatus.COMPLETED: // Asset pack is ready to use. Start the game. break; case AssetPackStatus.FAILED: // Request failed. Notify user. Log.e(TAG, assetPackState.errorCode()); break; case AssetPackStatus.CANCELED: // Request canceled. Notify user. break; case AssetPackStatus.WAITING_FOR_WIFI: case AssetPackStatus.REQUIRES_USER_CONFIRMATION: if (!confirmationDialogShown) { assetPackManager.showConfirmationDialog(activityResultLauncher); confirmationDialogShown = true; } break; case AssetPackStatus.NOT_INSTALLED: // Asset pack is not downloaded yet. break; case AssetPackStatus.UNKNOWN: Log.wtf(TAG, "Asset pack status unknown") break; } } }
Alternatif olarak, mevcut indirmelerin durumunu öğrenmek için getPackStates()
yöntemini de kullanabilirsiniz.
AssetPackStates
indirme işleminin ilerleme durumunu, indirme durumunu ve tüm hata hata kodlarını içerir.
Öğe paketlerine erişme
İndirme isteği COMPLETED
durumuna ulaştıktan sonra dosya sistemi çağrılarını kullanarak bir öğe paketine erişebilirsiniz. Öğe paketinin kök klasörünü almak için getPackLocation()
yöntemini kullanın.
Öğeler, öğe paketi kök dizinindeki assets
dizininde depolanır. assets
dizininin yolunu assetsPath()
yardımcı yöntemini kullanarak alabilirsiniz.
Belirli bir öğenin yolunu almak için aşağıdaki yöntemi kullanın:
Kotlin
private fun getAbsoluteAssetPath(assetPack: String, relativeAssetPath: String): String? { val assetPackPath: AssetPackLocation = assetPackManager.getPackLocation(assetPack) // asset pack is not ready ?: return null val assetsFolderPath = assetPackPath.assetsPath() // equivalent to: FilenameUtils.concat(assetPackPath.path(), "assets") return FilenameUtils.concat(assetsFolderPath, relativeAssetPath) }
Java
private String getAbsoluteAssetPath(String assetPack, String relativeAssetPath) { AssetPackLocation assetPackPath = assetPackManager.getPackLocation(assetPack); if (assetPackPath == null) { // asset pack is not ready return null; } String assetsFolderPath = assetPackPath.assetsPath(); // equivalent to: FilenameUtils.concat(assetPackPath.path(), "assets"); String assetPath = FilenameUtils.concat(assetsFolderPath, relativeAssetPath); return assetPath; }
Diğer Play Asset Delivery API yöntemleri
Aşağıda, uygulamanızda kullanmak isteyebileceğiniz bazı ek API yöntemleri verilmiştir.
İsteği iptal et
Etkin durumdaki bir öğe paketi isteğini iptal etmek için cancel()
kodunu kullanın. Bu isteğin en iyi çaba işlemi olduğunu unutmayın.
Öğe paketini kaldırma
Bir öğe paketinin kaldırılmasını planlamak için requestRemovePack()
veya removePack()
kullanın.
Birden fazla öğe paketinin konumunu alma
Birden fazla öğe paketinin durumunu toplu olarak sorgulamak için getPackLocations()
kullanın. Öğe paketlerinin ve konumlarının haritasını döndürür. getPackLocations()
tarafından döndürülen haritada şu anda indirilmiş ve güncel olan her paket için bir giriş bulunur.
Sonraki adım
Yerel olarak ve Google Play'den Play Asset Delivery'yi test edin.