Android 14 ile Geliştiricilere Gelen Yenilikler

Ferhat ÖZÇELİK
10 min readOct 18, 2023

--

Mobil uygulama geliştiricileri için heyecan verici bir döneme giriş yapmaya hazır olun. Google’ın Android işletim sistemi, Android 14 güncellemesi ile bir kez daha sınırları zorluyor ve kullanıcı deneyimini bir üst seviyeye taşıyor. Bu yeni güncelleme, geliştiricilere sunduğu çeşitli araçlar ve özelliklerle dikkat çekiyor.

Android 14 ile gelen API düzeyindeki değişiklikler, uygulamalarınızı daha hızlı ve verimli hale getirmenize yardımcı olacak. Daha düşük güç tüketimi ve daha yüksek performans, kullanıcıların uygulamanızı daha çok sevmelerine neden olabilir.

Gizlilik konusundaki endişeleri ele alarak, Android 14 kullanıcı izinlerini ve gizlilik kontrollerini daha da güçlendirdi. Bu, kullanıcıların uygulamalarınızı daha güvenli bir şekilde kullanmalarını sağlarken, aynı zamanda geliştiricilerin veri güvenliği konusundaki sorumluluklarını yerine getirmelerine yardımcı oluyor.

Android 14 ayrıca uygulama tasarımlarınızı daha çekici ve kişiselleştirilebilir hale getirme fırsatı sunuyor. Bu, kullanıcıları daha fazla etkileyebilir ve sadık müşteriler haline getirebilir.

Bu yazıda, Android 14 ile geliştiricilere sunulan yenilikleri detaylı bir şekilde inceleyeceğiz. Uygulama geliştirme dünyasında yeni bir çağın başladığını ve bu güncelleme ile gelecek fırsatları kaçırmamanız gerektiğini anlatacağız. Bu heyecan verici yolculuğa katılmak için bizi takip edin ve Android 14'ün getirdiği yenilikleri keşfedin!

Yerelleştirme

Android 14, geliştiricilere ve kullanıcılara artık sistem dilinden bağımsız olarak bölgesel ayarlarını kişiselleştirebilecekler. Bu güncelleme, sıcaklık birimleri, haftanın ilk günü ve hesaplama sistemlerini kullanıcının tercihlerine göre ayarlamalarına olanak tanıyor.

Share Sheet

Android 14, metin, resim veya diğer içerikleri paylaştığınızda karşınıza çıkan sistemsel bir iletişim kutusu olan Share Sheet’in tasarımını ve özelliklerini güncelledi.

Pixel 7 Pro’da, Android 13'teki 4 öğenin aksine, yeni işletim sisteminde Direct Share bölümünde 5 öğe yer alıyor. Ayrıca, bu bölümde gördüğünüz içeriklerin sıralama sistemi de değiştirildi. Kullanıcıya bir mesaj gönderdiğinizde ShortcutManagerCompat.pushDynamicShortcut() kullanmalı ve ShortcutInfo oluştururken addCapabilityBinding() ile actions.intent.SEND_MESSAGE değerini kullanmalısınız. Benim görüşüme göre, bu çözüm için sabitler eklenmemiş olması oldukça garip.

Şimdi, standart sistem arayüzünde ChooserAction nesnesi olarak ekstra eylemler eklemek mümkün olacak. Bu eylemler, bir eylemi seçtiğinizde gönderilecek olan simge, başlık ve PendingIntent içerecek. Kişisel eylemleriniz için bir sınırlama bulunmuyor.

ShortcutManagerCompat.pushDynamicShortcut(context,
ShortcutInfoCompat.Builder(context, id)
// Configure Shortcut
.addCapabilityBinding("actions.intent.SEND_MESSAGE")
.build()
)

Ayrıca, gönderilen içeriği düzenlemek amacıyla kullanılan özel bir eylem daha bulunuyor. Bu eylemi oluşturmak için de ChooserActions kullanmanız gerekiyor.

Oluşturulan tüm ek eylemler, özel yeni bir EXTRA aracılığıyla Intent’e eklenmelidir. Bu nasıl yapılacağını aşağıda görebilirsiniz.

Android 13'te olduğu gibi, kutudan çıkan bazı standart eylemleri ekledilerse harika olurdu, ancak bu makalenin yayınlandığı tarihte böyle eylemleri bulamadım.

val intent: Intent = // Create Intent put content for sharing

val modifyAction: ChooserAction =
ChooserAction.Builder(modifyIcon, "Share", modifyActionIntent).build()

// Specify action to edit content
intent.putExtra(EXTRA_CHOOSER_MODIFY_SHARE_ACTION, modifyAction)


// Additional actions that can be done with content
val customActions: Array<ChooserAction> = arrayOf(
ChooserAсtion.Builder(copyIcon, "Copy", copyIntent).build(),
ChooserAсtion.Builder(albumIcon, "Album", createAlbumIntent).build(),
ChooserAсtion.Builder(createLinkIcon, "link", createLinkIntent).build()
)
// Add additional actions that can be done with content
inent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions)


// Create Intent for Share Sheet
val chooserIntent = Intent.createChooser(customActions, "Share")
// Launch Share Sheet
context.startActivity(chooserIntent)

Android sisteminde Google Play’den Veri Güvenliği

Her gün gelişen dijital dünyada, kişisel verilerimizi korumak ve uygulamaların bu verilere nasıl eriştiğini anlamak, daha da önemli hale geliyor. 2023'te Google Play Store ve Android 14 ile gelen yeni zorunluluklar, kullanıcıların verilerinin güvende olduğundan emin olmalarına ve bu süreci anlamalarına yardımcı oluyor. İşte bu değişikliklerin neden önemli olduğu ve nasıl çalıştığına dair bir bakış:

Kapsamlı Bilgilendirme: Artık uygulama geliştiricileri, uygulamalarının kullanıcı verilerini nasıl koruduğu hakkında daha fazla bilgi vermek zorunda. Bu bilgiler sadece Google Play Store’daki uygulama sayfasında değil, aynı zamanda Android 14 içinde de görülebilir olacak.

Konum İzinleri: Özellikle konum verileri gibi hassas bilgilere erişim istendiğinde, kullanıcılar neden bu verilere ihtiyaç duyulduğunu ve bu verilerin kimlerle paylaşılacağını görebilecekler. Bu, yalnızca uygulamanın konum verilerini üçüncü taraf hizmetlerle paylaştığı durumlar için geçerli olacak.

Veri Paylaşımının Şeffaflığı: Bu değişiklikler, veri paylaşımının daha şeffaf hale gelmesini sağlamayı amaçlıyor. Artık uygulamalar, kullanıcıların izni olmadan kuralları değiştiremeyecekler. Bu, kullanıcıların daha iyi bilgilendirilmesi ve daha fazla kontrol sahibi olmaları anlamına geliyor.

Genişletilmiş Bildirimler: Bu yaklaşım sadece konum verilerini değil, aynı zamanda diğer veri türleri için de geçerli olmalıdır. Kullanıcılar, uygulamaların diğer hassas bilgilere erişme nedenlerini de daha iyi anlamalıdır.

Bu değişiklikler, kullanıcı verilerinin güvenliği ve gizliliği konusundaki farkındalığı artırırken, aynı zamanda geliştiricileri daha sorumlu davranmaya teşvik ediyor. Bu, teknoloji dünyasında ve kullanıcı gizliliğinde daha fazla şeffaflık sağlama yolunda önemli bir adım olarak kabul edilmelidir.

Predictive Back Gesture

Uygulama içinde kişisel geçiş animasyonları oluşturma yeteneği eklenmiştir. Bunun için OnBackPressedCallback içine handleOnBackProgressed() adında bir yöntem eklenmiştir. Bu yöntem, Bekleme Jest’inin ilerlemesi ile birlikte çağrılır. Ayrıca, Bekleme Jest’inin animasyonunun sonunda ve iptal edilmesinin sonunda çağrılan handleOnBackPressed() ve handleOnBackCancelled() yöntemleri de bulunmaktadır.

Ekran üzerinde, Jetpack AppCompat 1.8.0 kütüphanesini kullanarak özel animasyonlarınızı nasıl uygulayabileceğinizi gösteren bir örnek bulunmaktadır. Ayrıca, artık kullanımı terk edilmiş olan overidePendingTransition() yöntemi yerine yeni overrideActivityTransition() yöntemini kullanmanız gerekmektedir. Mevcut yöntem, Predictive Back Gesture ile geçiş animasyonunu yürütürken daha yüksek önceliğe sahip olduğundan, doğru bir şekilde çalışmamaktadır.

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
val box = findViewById<View>(R.id.box)
val screenWidth =
Resources.getSystem().displayMetrics.widthPixels
val maxXShift = (screenWidth / 20)

val callback = object : OnBackPressedCallback(
enabled = true
) {

override fun handleOnBackProgressed(
backEvent: BackEvent
) {
when (backEvent.swipeEdge) {
BackEvent.EDGE_LEFT ->
box.translationX = backEvent.progress *
maxXShift
BackEvent.EDGE_RIGHT ->
box.translationX = -(backEvent.progress *
maxXShift)
}
box.scaleX = 1F - (0.1F * backEvent.progress)
box.scaleY = 1F - (0.1F * backEvent.progress)
}

override fun handleOnBackPressed() {
// Back Gesture competed
}


override fun handleOnBackCancelled() {
// Back Gesture cancelled
// Reset animation objects to initial state
}
}
this.onBackPressedDispatcher.addCallback(callback)
}
}
// New API
overrideActivityTransition(
enterAnim = R.anim.open_trans,
exitAnim = R.anim.exit_trans,
backgroundColor = R.color.bgr_color
)

// deprecated
overridePendingTransition(R.anim.open_trans, R.anim.exit_trans)

JobScheduler Güncellemeleri

JobScheduler, cihaz ve sunucu arasında veri transferi için uzun görevleri başlatma yeteneği kazandı. Bu tür bir göreve “kullanıcı başlatmalı veri transferi görevi” denir. Bu tür bir görev, uygulama kullanıcıya görünür olduğunda veya uygulama arka plandan bir Etkinlik başlatabiliyorsa yalnızca başlatılabilir.

Kullanıcı başlatmalı veri transferi görevini başlatmak için, AndroidManifest dosyasında RUN_USER_INITIATED_JOBS iznini belirtmelisiniz ve JobService sınıfını genişleten bir Hizmet eklemelisiniz. JobInfo oluştururken setUserInitiated() yöntemini true olarak belirtmeniz gerekmektedir. JobInfo’yu başlatmak için bir sistem bildirimi görüntüleme gereksinimi de bulunmaktadır. Bu işlemi onStartJob() yöntemini çağırdığınızda yapmanız gerekmektedir.

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

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

<application>
<service
android:name="dev.androidbroadcast.CustomTransferService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" />
</application>
</manifest>
val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
// Additional network request requirement
.build()

val jobInfo = JobInfo.Builder(1, ComponentName(context, CustomTransferService::class.java))
.setUserInitiated(true)
.setRequiredNetwork(networkRequest)
.setEstimatedNetworkBytes(ONE_GIGABYTE, ZERO_BYTES)
// ...
.build()

val jobScheduler: JobScheduler = checkNotNull(context.getSystemService())
jobScheduler.schedule(jobInfo)
class CustomTransferService : JobService() {

override fun onStartJob(job: JobParameters): Boolean {
if (job.jobId == JOB_ID) {
// Showing a notification
setNotification(job, NOTIF_ID, newNotification(), JobService.JOB_END_NOTIFICATION_POLICY_REMOVE)
val success = doDataTransfer()
jobFinished(job, wantsReschedule = !success)
return false
}
error("Job isn't handled")
}
}

Başarılı bir başlangıç için tüm başlatma koşullarını yerine getirmek gereklidir. Ayrıca, işlemin gerçekleştirilmesi için sistemde gerekli kaynakların olması gerekir. Kullanıcı başlatmalı veri transferi görevinin önemli bir farkı, bir Görevi başlatmak için App Standby Buckets kotalarına tabi olmamasıdır. Ancak, sistem belirli koşullar altında görevi durdurabilirse de görevi durdurmadan önce onStopJob() yöntemi çağrılacaktır. Bu yöntemde, ağ işleminin mevcut ilerlemesini kaydetmeniz önerilir, böylece yeniden başladığınızda işi baştan değil, sadece gerekli kısmı tamamlamanız gerekir.

class CustomTransferService : JobService() {

override fun onStopJob(job: JobParameters): Boolean {
if (job.jobId == JOB_ID) {
// Saving data transfer progress
return true
}
}
}

API’ye göre, Kullanıcı Başlattı etiketinin her türden Görev için kullanılabileceği görünüyor, ancak yöntemin belgesi Android 14'te yalnızca setRequiredNetwork() veya setRequiredNetworkType() ile birleştirilerek çağrılması gerektiğini belirtiyor. Muhtemelen gelecekteki Android sürümlerinde, kullanıcı tarafından başlatılabilen daha fazla açıkça etiketlenmiş görev türünü göreceğiz.

Android 14'ün piyasaya sürüldüğü dönemde, JobScheduler’ın yerine Google’ın önerdiği Jetpack WorkManager, API’sine bu özelliği açıkça eklememişti. Bu özellik gelecekteki sürümlerde eklenmiş olabilir veya değişiklik mevcut WorkManager API’nin alt yapısında kullanılmış olabilir.

BroadcastReceiver Değişiklikleri

Intent, kod ile kayıtlı (context-registered) BroadcastReceiver'a iletilen davranış, targetSdk'ya bakılmaksızın tüm uygulamalar için değiştirilmiştir. Uygulama önbellekteyken, yani minimize edilmiş ve kullanıcı bir süre boyunca kullanmamışsa, alabilecekleri tüm Intent'ler iletilmeyecektir. Intent iletimi, uygulama tekrar etkin hale geldiğinde gerçekleşecektir. Ayrıca, aynı Intent'leri birden fazla gönderirken yalnızca bir tanesi iletilir. AndroidManifest'te kayıtlı BroadcastReceiver'lar aynı şekilde çalışmaya devam edecektir.

Ayrıca, kod tarafından yapılan BroadcastReceiver kaydı daha katı hale gelmiştir. Şimdi, tıpkı AndroidManifest'te olduğu gibi, ihraç edilip edilmediğini belirtmek gerekmektedir. Kaydederken RECEIVER_EXPORTED veya RECEIVER_NOT_EXPORTED bayrağını belirtmeniz gerekecektir. Bu değişiklik, Android 14'ü destekleyen uygulamalar için geçerlidir.

class DataReceiver: BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
// Process data
}
}

val intentFilter = IntentFilter() // configure IntentFilter
context.registerReceiver(DataReceiver(), intentFilter, Context.RECEIVER_NOT_EXPORTED)

Artık SCHEDULE_EXACT_ALARM Varsayılan Olarak Devre Dışı

Android 12'de, AlarmManager API’sini kullanmak için alarmın kesin zamanı ile ilişkilendirilen yeni bir SCHEDULE_EXACT_ALARM izni tanıtıldı. Android 13'te yeni USE_EXACT_ALARMS izni ortaya çıktı. Android 14'te yeni bir izin eklenmedi, ancak SCHEDULE_EXACT_ALARM’ın çalışma şekli değiştirildi. Artık bu izin, hedefSdk’sı 33 ve daha yüksek olan uygulamalara verilmeyecektir. İzin, cihaz güncellemesi veya yedekleme geri yükleme durumlarında verilecektir, ancak yeni yüklemeler için verilmeyecektir. İstisnalar, sistem sertifikasıyla imzalanmış uygulamalar ve özel ayrıcalıklara sahip uygulamaları içerir, ayrıca pil optimizasyonu devre dışı bırakılan uygulamalar için de geçerlidir.

Fotoğraf ve Videolara Erişim

IOS’a benzer şekilde , Android 14, fotoğraf ve videolara kısmi erişim sağlar. Artık medya erişimi talep ettiğinizde, kullanıcıya tüm medyaya erişim sağlamayı veya yalnızca belirli fotoğraf ve videolara erişim sağlamayı seçme olanağı sunan bir iletişim kutusu görünecektir. Bu yeni özellik, hedefSdk’larına bakılmaksızın tüm uygulamalar için çalışacaktır.

Android 13, fotoğraf erişimi ve video erişimi için ayrı izinleri zaten tanıttı. Şimdi, READ_MEDIA_VISUAL_USER_SELECTED adlı ek bir izin ekleniyor, bu izin size belirli fotoğraf ve videolar için tekrar tekrar seçim isteme yetkisi verir. Yeni izni, yeni davranışı desteklemek için mevcut READ_MEDIA_IMAGES ve READ_MEDIA_VIDEO izinlerine ek olarak kullanmalısınız. Bu izni bildirmek, uygulamanızın bu yeniden seçmeyi desteklediği anlamına gelir.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" />

<!-- Devices running Android 13 (API level 33) or higher -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />

<!-- To handle the reselection within the app on Android 14 -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />

</manifest>

Güzel, detaylı bilgilendirme için teşekkür ederim. Bu yeni izin ve mekanizma, kullanıcıların belirli fotoğraf ve videoları geçici olarak izin vermesine olanak tanırken, belirli bir süre zarfı belirtilmemiş görünüyor. Kullanıcı uygulamayı arka plana alır veya uygulamayı sonlandırırsa, kısmi erişim hemen iptal edilecektir, bu da geçici tek seferlik izinlerin çalışma şekliyle benzerdir. Bu nedenle READ_MEDIA_VISUAL_USER_SELECTED iznini almanın durumlarını saklayamazsınız ve her seferinde kontrol etmeniz gerekecektir.

Cihazınızı Android 14'e güncellediğinizde, uygulama, uygun izinleri alarak kullanıcının fotoğraf/video verilerine tam erişime sahipse, bu düzeyde erişime sahip olmaya devam edecektir.

Belirli fotoğrafları seçmeye yeni izin eklenmiş olsa da, bu, uygulamanın işleyişini etkilemeyecektir, ancak gelecekte kullanıcıların yeni fotoğrafları seçmek isteyebileceği göz önüne alındığında uygulamanın bu yeni mekanizmayı desteklemesi gerekebilir. Bazı uygulamalar tüm medya kütüphanesi ile çalışmayı amaçladığından, bu tür uygulamaların yeniden düşünülmesi gerekebilir. Bir kullanıcı olarak, bu durumu galerimdeki her şeye erişemezler durumuna getirmesi nedeniyle büyük bir gelişme olarak görüyorum.

Uygulamanızın arka planda çalışırken fotoğraf/video erişimine ihtiyaç duyması durumunda, bu yeni izni desteklemeniz şiddetle tavsiye edilir; aksi takdirde Android 14'te bu izinlerin düzenli olarak iptal edilme riskiyle karşılaşabilirsiniz.

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

Android 14'de ekran görüntülerini algılamak için, Activity içinde özel bir API ortaya çıkar. Bu API, ekran görüntüsünün çekilmesinden sonra Callback’i çağırır. API yalnızca kullanıcının cihazda özel bir tuş kombinasyonunu kullanarak aldığı ekran görüntülerini algılayabilir. Eğer ekran test sırasında özel komutlar veya ADB ile yakalanırsa, geri çağrı çalışmayacaktır. API’nin çalışabilmesi için AndroidManifest’e DETECT_SCREEN_CAPTURE iznini eklemeniz gerekecek. Ardından onStart() içinde bir geri çağrı kaydedin ve onStop() içinde unutmayı unutmayın. Aksi takdirde, Jetpack Lifecycle’ı kullanabilirsiniz.

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
</manifest>
class MainActivity : Activity() {

private val mainExecutor = MainEcxector()

private val screenshotCallback = ScreenCaptureCallback {
// A screenshot was taken
}

override fun onStart() {
super.onStart()
registerScreenCaptureCallback(mainExecutor, screenshotCallback)
}

override fun onStop() {
super.onStop()
unregisterScreenCaptureCallback(screenshotCallback)
}
}

Uygulama Mağazalarına Yönelik İyileştirmeler

Android 14, üçüncü taraf mağazalar için yeni API’lar ekleyerek işleri kolaylaştırıyor. Uygulamaların yüklenmesi üzerindeki kısıtlamalara odaklanarak başlayalım. Artık, ilgili API’yi çağırarak uygulama yükleme herhangi bir zamanda gerçekleşebilir hale geldi. Android 14, Yükleme Kısıtlamaları API’sini ekledi, bu API sayesinde yükleme işlemini gerçekleştirebileceğiniz koşulları belirleyebilirsiniz.

PackageInstaller.InstallConstraints.Builder()
// Kullanıcı için uygulama görünür değilse
.setAppNotForegroundRequired()
// Uygulama ile etkileşim yoksa
.setAppNotInteractingRequired()
// Uygulama görünür, ancak ön planda değilse
.setAppNotTopVisibleRequired()
// Cihaz kullanılmıyorsa
.setDeviceIdleRequired()
// Şu anda telefon görüşmesi yoksa
.setNotInCallRequired()
.build()

Ardından, belirtilen uygulamaların belirtilen koşulları karşılayıp karşılamadığını kontrol etmek için checkInstallConstraints() yöntemini kullanabilirsiniz.

val packageInstaller: PackageInstaller = //...
packageInstaller.checkInstallConstraints(
packageNames = listOf("dev.androidbroadcast"),
constraints,
Executors.newSingleThreadExecutor()
) { result: PackageInstaller.InstallConstraintsResult ->
if (result.areAllConstraintsSatisfied()) {
// APK dosyalarını yükleyin
}
}

Ayrıca, belirtilen uygulamalar için koşullar karşılanana kadar bekleyen engelleyici waitForInstallConstraints() yöntemini çağırabilirsiniz.

packageInstaller.waitForInstallConstraints(
listOf("dev.androidbroadcast"),
constraints,
intentSender,
timeout = Duration.ofHours(1).toMillis()
)

koşullar karşılandığında güncellemeyi ertelemek için commitSessionAfterInstallConstraintsAreMet() yöntemini kullanabilirsiniz.

packageInstaller.commitSessionAfterInstallConstraintsAreMet(
sessionId,
intentSender,
constraints,
timeout = Duration.ofHours(1).toMillis()
)

Şimdi, PackageSession API aracılığıyla birden çok APK’yı yüklemekten önce kullanıcı izni alabilirsiniz. Bunun için yeni requestUserPreapproval() yöntemini çağırmanız gerekiyor. Bu yöntem, App Bundle ile rahatça çalışmanıza olanak tanır ve tek tek APK'ları yüklemek için tekrar tekrar izin almanız gerekmez. Bu sayede, birden çok uygulama için mağazadan gelen güncellemeler tek bir kullanıcı onayı gerektirir.

val sessionId: Int = packageInstaller.createSession(
PackageInstaller.SessionParams(SessionParams.MODE_INHERIT_EXISTING)
)
val pendingIntent: PendingIntent = // ...

val session: Session = packageInstaller.openSession(sessionId)
// Call the system dialog to request permission from the user
// intentSender determines where the result will be sent
session.requestUserPreapproval(
PreapprovalDetails.Builder()
.setIcon(iconBitmap)
.setLabel(message)
.setLocale(locale)
.build(),
pendingIntent.intentSender
)
// Wait for the user’s permission, and then the session starts
session.commit(intentSender)

Kullanıcıyı beklenmedik bir mağazadan uygulama güncellemelerinden korumak için PackageInstaller API içinde setRequestUpdateOwnership() yöntemi tanıtıldı. Bu, kullanıcının yükleyici uygulamasını gerçekten değiştirmek isteyip istemediğini onaylamasını gerektirir. Bu genellikle bir uygulamayı bir uygulamadan (örneğin, Google Play) yüklediğinizde ve ardından bunları başka bir uygulama mağazasından güncellemeye çalıştığınızda meydana gelir. İncelediğim kadarıyla, bu özellik genellikle kritik paketler için tasarlanmıştır: Google Play Hizmetleri, Sağlık Bağlantısı, Chrome WebView gibi.

Kaynaklar

--

--