Android 7.0, yeni özellikler ve olanakların yanı sıra çeşitli sistem ve API davranışı değişiklikleri içerir. Bu dokümanda, uygulamalarınızda anlamanız ve hesaba katmanız gereken bazı önemli değişiklikler vurgulanmaktadır.
Daha önce Android için uygulama yayınladıysanız uygulamanızın platformdaki bu değişikliklerden etkilenebileceğini unutmayın.
Pil ve Bellek
Android 7.0, cihazların pil ömrünü uzatmayı ve RAM kullanımını azaltmayı amaçlayan sistem davranışı değişikliklerini içerir. Bu değişiklikler uygulamanızın sistem kaynaklarına erişimini ve belirli örtülü amaçlar aracılığıyla uygulamanızın diğer uygulamalarla etkileşim kurma şeklini etkileyebilir.
Doz
Android 6.0'da (API düzeyi 23) kullanıma sunulan Doz, kullanıcı cihazı fişe takılı değilken, hareketsiz ve ekranı kapalı halde bıraktığında CPU ve ağ etkinliklerini erteleyerek pil ömrünü iyileştirir. Android 7.0, cihaz sabit durumdayken kullanıcı fişe takılı değilken CPU ve ağ kısıtlamalarının alt kümesi uygulayarak Doz'a daha fazla geliştirme sağlar. Örneğin, ekran kapalıyken kullanıcı cihazı takılı değilken de bu kullanım zorunlu değildir.
![Doz'un, pil ömrünü iyileştirmek için ilk sistem etkinliği kısıtlamalarını nasıl uyguladığını gösteren resim](https://developer.android.com/static/images/android-7.0/doze-diagram-1.png?authuser=6&hl=tr)
Şekil 1. Doz'un, pil ömrünü iyileştirmek için ilk sistem etkinliği kısıtlamalarını nasıl uyguladığını gösteren resim.
Cihaz pille çalışırken ve ekran belirli bir süre kapalı olduğunda cihaz Doz'a girer ve ilk kısıtlama alt kümesini uygular: Uygulama ağ erişimini kapatır, işleri ve senkronizasyonu erteler. Cihaz, Doz'a girdikten sonra belirli bir süre hareketsiz kalırsa sistem, geri kalan Doz kısıtlamalarını PowerManager.WakeLock
, AlarmManager
alarmları, GPS ve kablosuz taramalarına uygular. Sistem, Doz kısıtlamalarının bir kısmının veya tamamının uygulanmasından bağımsız olarak, kısa bakım dönemlerinde cihazı uyandırır. Bu dönem sırasında uygulamalara ağ erişimine izin verilir ve ertelenmiş işleri/senkronizasyonları gerçekleştirebilirler.
![Doz'un, cihaz belirli bir süre hareketsiz kaldıktan sonra ikinci bir sistem etkinliği kısıtlamaları düzeyini nasıl uyguladığını gösteren resim](https://developer.android.com/static/images/android-7.0/doze-diagram-2.png?authuser=6&hl=tr)
2. Şekil. Doz'un, cihaz belirli bir süre hareketsiz kaldıktan sonra ikinci düzeyde sistem etkinliği kısıtlamalarını nasıl uyguladığını gösteren resim.
Ekranı etkinleştirdiğinizde veya cihazı fişe taktığınızda Doz'dan çıkacağınızı ve bu işleme kısıtlamalarını kaldıracağınızı unutmayın. Bu ek davranış, Doz ve Uygulamayı Beklemeye Alma için Optimize Etme bölümünde açıklandığı gibi, uygulamanızı Android 6.0'da kullanıma sunulan önceki Doz sürümüne (API seviyesi 23) uyarlamayla ilgili önerileri ve en iyi uygulamaları etkilemez. Bu önerileri yine de uygulamalısınız. Örneğin, mesaj gönderip almak için Firebase Cloud Messaging'i (FCM) kullanmalı ve ek Doz davranışına uyum sağlamak için güncellemeler planlamaya başlamalısınız.
Project Svelte: Arka Plan Optimizasyonları
Android 7.0, hem bellek kullanımını hem de güç tüketimini optimize etmeye yardımcı olmak için üç örtülü yayını kaldırır. Örtülü yayınlar, genellikle arka planda kendilerini dinlemek üzere kaydedilmiş uygulamaları başlattığından bu değişiklik gereklidir. Bu yayınların kaldırılması cihaz performansı ve kullanıcı deneyimi için önemli ölçüde fayda sağlayabilir.
Mobil cihazlarda, kablosuz ağ ve mobil veri arasında geçiş yapılması gibi sık sık bağlantı değişiklikleri yaşanır. Şu anda uygulamalar, manifest dosyalarında örtülü CONNECTIVITY_ACTION
yayını için bir alıcı kaydederek bağlantıdaki değişiklikleri izleyebiliyor. Birçok uygulama bu yayını almak için kaydolduğundan, tek bir ağ anahtarı tüm uygulamaların aynı anda uyanmasına ve yayını işlemesine neden olabilir.
Benzer şekilde, Android'in önceki sürümlerinde uygulamalar Kamera gibi diğer uygulamalardan dolaylı ACTION_NEW_PICTURE
ve ACTION_NEW_VIDEO
yayınları almak için kaydolabiliyordu. Bir kullanıcı Kamera uygulamasıyla resim çektiğinde, bu uygulamalar uyanarak yayını işleme alır.
Android 7.0, bu sorunları gidermek için aşağıdaki optimizasyonları uygular:
- Android 7.0 (API düzeyi 24) ve sonraki sürümleri hedefleyen uygulamalar, manifest dosyasında yayın alıcısını belirttiği takdirde
CONNECTIVITY_ACTION
yayınlarını almaz. Uygulamalar,BroadcastReceiver
öğeleriniContext.registerReceiver()
ile kaydederlerse ve bu bağlam hâlâ geçerliyseCONNECTIVITY_ACTION
yayınlarını almaya devam eder. - Sistem artık
ACTION_NEW_PICTURE
veyaACTION_NEW_VIDEO
yayını göndermiyor. Bu optimizasyon yalnızca Android 7.0'ı hedefleyen uygulamaları değil, tüm uygulamaları etkiler.
Uygulamanız bu amaçlardan birini kullanıyorsa Android 7.0 cihazları doğru bir şekilde hedefleyebilmek için bu amaçlara olan bağımlılıkları en kısa sürede kaldırmalısınız.
Android çerçevesi, bu örtülü yayınlara olan ihtiyacı azaltmak için çeşitli çözümler sunar. Örneğin JobScheduler
API, belirtilen koşullar (ör. sınırsız bir ağa bağlantı) karşılandığında ağ işlemlerinin planlanması için sağlam bir mekanizma sunar. İçerik sağlayıcılarda yapılan değişikliklere tepki vermek için JobScheduler
bile kullanabilirsiniz.
Android 7.0'da (API düzeyi 24) arka plan optimizasyonları ve uygulamanızı nasıl uyarlayacağınız hakkında daha fazla bilgi için Arka Plan Optimizasyonları bölümüne bakın.
İzin Değişiklikleri
Android 7.0'da, uygulamanızı etkileyebilecek izin değişiklikleri yer almaktadır.
Dosya sistemi izin değişiklikleri
Gizli dosyaların güvenliğini iyileştirmek için, Android 7.0 veya sonraki sürümleri hedefleyen uygulamaların yer aldığı gizli dizinde erişim kısıtlanmıştır (0700
). Bu ayar, gizli dosyaların boyutları veya varlıkları gibi meta verilerin sızdırılmasını önler. Bu izin değişikliğinin birden fazla yan etkisi vardır:
-
Gizli dosyaların dosya izinleri artık dosya sahibi tarafından rahatlatılmamalıdır ve
MODE_WORLD_READABLE
ve/veyaMODE_WORLD_WRITEABLE
kullanılarak bu şekilde yapılmaya çalışıldığındaSecurityException
tetiklenir.Not: Şu an için bu kısıtlama tam olarak uygulanmamaktadır. Uygulamalar yine de yerel API'leri veya
File
API'yi kullanarak özel dizinlerindeki izinleri değiştirebilir. Ancak özel dizin izinlerinin gevşetilmesini kesinlikle önermiyoruz. -
file://
URI'larının paket alanının dışına geçirilmesi, alıcıya erişilemeyen bir yol bırakabilir. Bu nedenle,file://
URI'sı iletmeye çalışıldığındaFileUriExposedException
tetiklenir. Gizli bir dosyanın içeriğini paylaşmak için önerilen yolFileProvider
kullanmaktır. -
DownloadManager
, artık gizli olarak depolanan dosyaları dosya adına göre paylaşamayacak.COLUMN_LOCAL_FILENAME
erişimi sırasında eski uygulamalar erişilemeyebilir. Android 7.0 veya sonraki sürümleri hedefleyen uygulamalar,COLUMN_LOCAL_FILENAME
özelliğine erişmeye çalışırkenSecurityException
tetikler. İndirme konumunuDownloadManager.Request.setDestinationInExternalFilesDir()
veyaDownloadManager.Request.setDestinationInExternalPublicDir()
kullanarak herkese açık bir konuma ayarlayan eski uygulamalar,COLUMN_LOCAL_FILENAME
üzerinden yola erişmeye devam edebilir ancak bu yöntem kesinlikle önerilmez.DownloadManager
tarafından açığa çıkarılan bir dosyaya erişmek için tercih edilen yolContentResolver.openFileDescriptor()
kullanmaktır.
Uygulamalar Arasında Dosya Paylaşma
Android 7.0'ı hedefleyen uygulamalar için Android çerçevesi, file://
URI'larının uygulamanızın dışına gösterilmesini yasaklayan StrictMode
API politikasını uygular. Dosya URI'si içeren bir amaç uygulamanızdan ayrılırsa uygulama, FileUriExposedException
istisnasıyla başarısız olur.
Uygulamalar arasında dosya paylaşmak için bir content://
URI'sı göndermeli ve URI'da geçici erişim izni vermelisiniz. Bu izni vermenin en kolay yolu FileProvider
sınıfını kullanmaktır. İzinler ve dosya paylaşımı hakkında daha fazla bilgi için Dosya Paylaşımı bölümüne bakın.
Yeni Erişilebilirlik Özellikleri
Android 7.0, görme bozukluğu olan veya az gören kullanıcılar için platformun kullanılabilirliğini iyileştirmek amacıyla yapılan değişiklikler içermektedir. Bu değişiklikler genellikle uygulamanızda kod değişikliği gerektirmez, ancak kullanıcı deneyimi üzerindeki olası etkilerini değerlendirmek için bu özellikleri inceleyip uygulamanızla test etmeniz gerekir.
Ekran Yakınlaştırma
Android 7.0, kullanıcıların ekrandaki tüm öğeleri büyüten veya küçülten, böylece az gören kullanıcılar için cihaz erişilebilirliğini iyileştiren Görüntü boyutu ayarlamasına olanak tanır. Kullanıcılar, ekranı sw320dp'lik minimum ekran genişliğini geçecek şekilde yakınlaştıramaz. Bu boyut, yaygın olarak kullanılan orta boyutlu bir telefon olan Nexus 4'ün genişliğidir.
![Android 7.0 sistem görüntüsü çalıştıran cihazın yakınlaştırılmamış ekran boyutunu gösteren ekran](https://developer.android.com/static/images/android-7.0/screen-zoom-1.png?authuser=6&hl=tr)
![Android 7.0 sistem görüntüsü çalıştıran bir cihazın ekran boyutunu büyütme etkisini gösteren ekran](https://developer.android.com/static/images/android-7.0/screen-zoom-2.png?authuser=6&hl=tr)
3. Şekil. Sağ taraftaki ekranda, Android 7.0 sistem görüntüsü çalıştıran bir cihazın Ekran boyutunu büyütmenin etkisi gösterilmektedir.
Cihaz yoğunluğu değiştiğinde sistem çalışan uygulamaları aşağıdaki şekillerde bilgilendirir:
- Bir uygulama, API düzeyi 23 veya altını hedefliyorsa sistem, arka plandaki tüm işlemleri otomatik olarak sonlandırır. Yani bir kullanıcı bu tür bir uygulamadan ayrılıp Ayarlar ekranını açar ve Görüntü boyutu ayarını değiştirirse sistem, uygulamayı düşük bellekte olduğu gibi kapatır. Uygulamanın ön planda herhangi bir işlemi varsa sistem, Çalışma Zamanı Değişikliklerini İşleme bölümünde açıklandığı gibi, cihazın yönü değişmiş gibi yapılandırma değişikliğiyle ilgili olarak bu süreçleri bilgilendirir.
- Bir uygulama Android 7.0'ı hedefliyorsa Çalışma Zamanı Değişikliklerini İşleme bölümünde açıklandığı gibi uygulamanın tüm süreçleri (ön plan ve arka plan) yapılandırma değişikliğiyle ilgili olarak bilgilendirilir.
Çoğu uygulamanın bu özelliği desteklemek için herhangi bir değişiklik yapması gerekmez (Android en iyi uygulamalarını takip etmeleri şartıyla). Kontrol edilecek belirli noktalar:
- Uygulamanızı
sw320dp
ekran genişliğine sahip bir cihazda test edin ve yeterli performans gösterdiğinden emin olun. - Cihaz yapılandırması değiştiğinde, önbelleğe alınmış bit eşlemler veya ağdan yüklenen kaynaklar gibi yoğunluğa bağlı önbelleğe alınmış bilgileri güncelleyin. Uygulama duraklatılmış durumdan devam ettirildiğinde yapılandırma değişikliklerini kontrol edin.
Not: Yapılandırmaya bağlı verileri önbelleğe alıyorsanız bu veriler için uygun ekran boyutu veya piksel yoğunluğu gibi alakalı meta verileri eklemek iyi bir fikirdir. Bu meta verileri kaydetmek, yapılandırma değişikliğinden sonra önbelleğe alınan verileri yenilemeniz gerekip gerekmediğine karar vermenizi sağlar.
- Ekran yoğunluğuyla ölçeklenmedikleri için boyutları piksel birimleriyle belirtmekten kaçının. Bunun yerine, boyutları yoğunluktan bağımsız piksel (
dp
) birimleriyle belirtin.
Kurulum Sihirbazı'nda Görüş Ayarları
Android 7.0'ın Karşılama ekranında Görüş Ayarları özelliği bulunur. Kullanıcılar burada yeni cihazlarda şu erişilebilirlik ayarlarını yapabilir: Büyütme hareketi, Yazı tipi boyutu, Görüntü boyutu ve TalkBack. Bu değişiklik, farklı ekran ayarlarıyla ilgili hataların görünürlüğünü artırır. Bu özelliğin etkisini değerlendirmek için bu ayarları etkinleştirerek uygulamalarınızı test etmeniz gerekir. Ayarları Ayarlar > Erişilebilirlik bölümünde bulabilirsiniz.
Platform Kitaplıklarına Bağlanan NDK Uygulamaları
Sistem, Android 7.0 sürümünden itibaren uygulamaların NDK olmayan kitaplıklara dinamik bir şekilde bağlanmasını engeller. Bu durum, uygulamanızın kilitlenmesine neden olabilir. Davranıştaki bu değişikliğin amacı, platform güncellemeleri ve farklı cihazlar genelinde tutarlı bir uygulama deneyimi oluşturmaktır. Kodunuz özel kitaplıklara bağlantı vermiyor olsa da uygulamanızdaki bir üçüncü taraf statik kitaplığı bunu yapıyor olabilir. Bu nedenle, tüm geliştiriciler uygulamalarının Android 7.0 çalıştıran cihazlarda kilitlenmediğinden emin olmak için bunları kontrol etmelidir. Uygulamanız yerel kod kullanıyorsa yalnızca herkese açık NDK API'lerini kullanmalısınız.
Uygulamanız gizli platform API'lerine erişmeye çalışıyor olabilir:
- Uygulamanız özel platform kitaplıklarına doğrudan erişiyor. Uygulamanızı bu kitaplıkların kendi kopyasını içerecek şekilde güncellemeniz veya genel NDK API'lerini kullanmanız gerekir.
- Uygulamanız, özel platform kitaplıklarına erişen üçüncü taraf kitaplığı kullanıyor. Uygulamanızın özel kitaplıklara doğrudan erişmediğinden emin olsanız bile uygulamanızı bu senaryo için yine de test etmeniz gerekir.
- Uygulamanız, APK'sında bulunmayan bir kitaplığa referans veriyor. Örneğin, kendi OpenSSL kopyanızı kullanmaya çalıştıysanız ancak bunu uygulamanızın APK'sı ile paketlemeyi unuttuysanız bu durumla karşılaşabilirsiniz. Uygulama, Android platformunun
libcrypto.so
içeren sürümlerinde normal şekilde çalışabilir. Ancak uygulama, bu kitaplığı içermeyen sonraki Android sürümlerinde (ör. Android 6.0 ve sonraki sürümler) kilitlenebilir. Bunu düzeltmek için NDK olmayan tüm kitaplıklarınızı APK'nızla paketlediğinizden emin olun.
Uygulamalar, Android'in farklı sürümleri arasında değişebileceği veya kaldırılabileceğinden NDK'ya dahil olmayan yerel kitaplıkları kullanmamalıdır. OpenSSL'den BoringSSL'ye geçiş, böyle bir değişikliğe örnek olarak gösterilebilir. Ayrıca NDK'ya dahil olmayan platform kitaplıkları için uyumluluk gereksinimleri olmadığından farklı cihazlar farklı uyumluluk düzeyleri sunabilir.
Bu kısıtlamanın halihazırda yayınlanmış uygulamalar üzerindeki etkisini azaltmak amacıyla, API düzeyi 23 veya altını hedefleyen uygulamalar için önemli ölçüde kullanım görüldüğü bir dizi kitaplık (ör. libandroid_runtime.so
, libcutils.so
, libcrypto.so
ve libssl.so
) geçici olarak Android 7.0 (API düzeyi 24) üzerinden erişilebilir durumdadır. Uygulamanız bu kitaplıklardan birini yüklerse logcat bir uyarı oluşturur ve hedef cihazda sizi bilgilendirmek için bir durum mesajı gösterilir. Bu uyarıları görürseniz uygulamanızı bu kitaplıkların kendi kopyasını içerecek veya yalnızca herkese açık NDK API'lerini kullanacak şekilde güncellemeniz gerekir. Android platformunun gelecekteki sürümleri, özel kitaplıkların kullanımını tamamen kısıtlayabilir ve uygulamanızın kilitlenmesine neden olabilir.
Tüm uygulamalar, herkese açık veya geçici olarak erişilemeyen bir API'yi çağırdıklarında çalışma zamanı hatası oluşturur. Sonuç olarak hem System.loadLibrary
hem de dlopen(3)
, NULL
değerini döndürür ve uygulamanızın kilitlenmesine neden olabilir. Özel platform API'lerinin kullanımını kaldırmak için uygulama kodunuzu gözden geçirmeniz ve Android 7.0 (API düzeyi 24) çalıştıran bir cihaz veya emülatör kullanarak uygulamalarınızı kapsamlı bir şekilde test etmeniz gerekir. Uygulamanızın özel kitaplıkları kullanıp kullanmadığından emin değilseniz çalışma zamanı hatasını belirlemek için logcat'i kontrol edebilirsiniz.
Aşağıdaki tabloda, özel yerel kitaplıkların kullanımına ve hedef API düzeyine (android:targetSdkVersion
) bağlı olarak bir uygulamadan beklemeniz gereken davranış açıklanmaktadır.
Kitaplıklar | Hedef API düzeyi | Dinamik bağlayıcı üzerinden çalışma zamanı erişimi | Android 7.0 (API düzeyi 24) davranışı | Gelecekteki Android platformu davranışı |
---|---|---|---|---|
NDK Halk | Tümü | Erişilebilir | Beklendiği gibi çalışıyor | Beklendiği gibi çalışıyor |
Özel (geçici olarak erişilebilen özel kitaplıklar) | 23 veya altı | Geçici olarak erişilebilir | Beklendiği gibi çalışır ancak logcat uyarısı alırsınız. | Çalışma zamanı hatası |
Özel (geçici olarak erişilebilen özel kitaplıklar) | 24 veya üzeri | Kısıtlanmış | Çalışma zamanı hatası | Çalışma zamanı hatası |
Gizli (diğer) | Tümü | Kısıtlanmış | Çalışma zamanı hatası | Çalışma zamanı hatası |
Uygulamanızın özel kitaplıkları kullanıp kullanmadığını kontrol etme
Özel kitaplık yükleme sorunlarını tanımlamanıza yardımcı olmak için logcat, uyarı veya çalışma zamanı hatası oluşturabilir. Örneğin, uygulamanız API düzeyi 23 veya altını hedefliyorsa ve Android 7.0 çalıştıran bir cihazda gizli bir kitaplığa erişmeye çalışıyorsa şuna benzer bir uyarı görebilirsiniz:
03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so" ("/system/lib/libandroid_runtime.so") needed or dlopened by "/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible for the namespace "classloader-namespace" - the access is temporarily granted as a workaround for http://b/26394120
Bu logcat uyarıları, hangi kitaplığın özel bir platform API'ye erişmeye çalıştığını size bildirir ancak uygulamanızın kilitlenmesine neden olmaz. Ancak uygulama API düzeyi 24 veya üstünü hedefliyorsa logcat aşağıdaki çalışma zamanı hatasını oluşturur ve uygulamanız kilitlenebilir:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so" ("/system/lib/libcutils.so") needed or dlopened by "/system/lib/libnativeloader.so" is not accessible for the namespace "classloader-namespace" at java.lang.Runtime.loadLibrary0(Runtime.java:977) at java.lang.System.loadLibrary(System.java:1602)
Bu logcat çıkışlarını, uygulamanız özel platform API'lerine dinamik olarak bağlanan üçüncü taraf kitaplıklar kullanıyorsa da görebilirsiniz. Android 7.0DK'daki Readelf aracı, aşağıdaki komutu çalıştırarak belirli bir .so
dosyasının dinamik olarak bağlantılı tüm paylaşılan kitaplıklarının listesini oluşturmanıza imkan tanır:
aarch64-linux-android-readelf -dW libMyLibrary.so
Uygulamanızı güncelleme
Bu tür hataları düzeltmek ve uygulamanızın gelecekteki platform güncellemelerinde kilitlenmesini önlemek için uygulayabileceğiniz bazı adımlar şunlardır:
- Uygulamanız özel platform kitaplıkları kullanıyorsa uygulamanızı bu kitaplıkların kendi kopyasını içerecek şekilde güncellemeniz veya genel NDK API'lerini kullanmanız gerekir.
- Uygulamanız özel simgelere erişen bir üçüncü taraf kitaplığı kullanıyorsa kitaplığı güncellemesi için kitaplık yazarıyla iletişime geçin.
- NDK olmayan tüm kitaplıklarınızı APK'nızla paketlediğinizden emin olun.
getJavaVM
velibandroid_runtime.so
tarihleri arasındakigetJNIEnv
yerine standart JNI işlevlerini kullanın:AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h> AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or JavaVM::AttachCurrentThread from <jni.h>.
libcutils.so
içindeki özelproperty_get
sembolü yerine__system_property_get
kodunu kullanın. Bunun için__system_property_get
özelliğini aşağıdakilerle birlikte kullanın:#include <sys/system_properties.h>
Not: Sistem özelliklerinin kullanılabilirliği ve içeriği CTS aracılığıyla test edilmez. Bu özellikleri hiç kullanmamak daha iyi bir çözüm olacaktır.
SSL_ctrl
simgesinin yerel bir sürümünü (libcrypto.so
) kullanın. Örneğin,.so
dosyanıza statik olaraklibcyrpto.a
bağlantısı vermeniz veya BoringSSL/OpenSSL'den dinamik olarak bağlantılı birlibcrypto.so
sürümünü dahil edip APK'nızda paketlemeniz gerekir.
Android for Work
Android 7.0, Android for Work'ü hedefleyen uygulamalar için sertifika yükleme, şifre sıfırlama, ikincil kullanıcı yönetimi ve cihaz tanımlayıcılarına erişim ile ilgili değişiklikler de dahil olmak üzere değişiklikler içermektedir. Android for Work ortamları için uygulama oluşturuyorsanız bu değişiklikleri inceleyip uygulamanızda gerekli değişiklikleri yapmanız gerekir.
- DPC'nin ayarlayabilmesi için önce yetki verilmiş bir sertifika yükleyicisi yüklemeniz gerekir. Android 7.0'ı (API düzeyi 24) hedefleyen profil ve cihaz sahibi uygulamaları için cihaz politikası denetleyicinin (DPC)
DevicePolicyManager.setCertInstallerPackage()
yöntemini çağırmadan önce yetki verilmiş sertifika yükleyicisini yüklemeniz gerekir. Yükleyici önceden yüklenmemişse sistem birIllegalArgumentException
bildirir. - Cihaz yöneticilerine yönelik şifre sıfırlama kısıtlamaları artık profil sahipleri için de geçerli. Cihaz yöneticileri, şifreleri temizlemek veya önceden ayarlanmış olanları değiştirmek için artık
DevicePolicyManager.resetPassword()
uygulamasını kullanamaz. Cihaz yöneticileri, yalnızca cihazda şifre, PIN veya desen olmadığında şifre ayarlamaya devam edebilir. - Cihaz ve profil sahipleri, kısıtlamalar ayarlanmış olsa bile hesapları yönetebilir. Cihaz sahipleri ve profil sahipleri,
DISALLOW_MODIFY_ACCOUNTS
kullanıcı kısıtlaması geçerli olsa bile Account Management API'leri çağırabilir. - Cihaz sahipleri ikincil kullanıcıları daha kolay bir şekilde yönetebilir. Bir cihaz, cihaz sahibi modunda çalışırken
DISALLOW_ADD_USER
kısıtlaması otomatik olarak ayarlanır. Bu, kullanıcıların yönetilmeyen ikincil kullanıcılar oluşturmasını engeller. Ayrıca,CreateUser()
vecreateAndInitializeUser()
yöntemleri kullanımdan kaldırılmıştır; bunların yerini yeniDevicePolicyManager.createAndManageUser()
yöntemi alır. - Cihaz sahipleri cihaz tanımlayıcılara erişebilir. Cihaz sahibi,
DevicePolicyManager.getWifiMacAddress()
kullanarak cihazın kablosuz MAC adresine erişebilir. Cihazda Kablosuz özelliği hiç etkinleştirilmemişse bu yöntemnull
değerini döndürür. - İş Modu ayarı, iş uygulamalarına erişimi kontrol eder. İş modu kapalı olduğunda sistem başlatıcı, iş uygulamalarını devre dışı bırakarak bu uygulamaların kullanılamadığını belirtir. Çalışma modunu tekrar etkinleştirdiğinizde normal davranış geri yüklenir.
- İstemci sertifikası zinciri ve Ayarlar kullanıcı arayüzündeki karşılık gelen özel anahtarı içeren bir PKCS #12 dosyası yüklenirken zincirdeki CA sertifikası artık güvenilir kimlik bilgileri depolama alanına yüklenmez. Bu, uygulamalar daha sonra istemci sertifikası zincirini almaya çalıştığında
KeyChain.getCertificateChain()
sonucunu etkilemez. Gerekirse CA sertifikası, Ayarlar Kullanıcı Arayüzü aracılığıyla güvenilir kimlik bilgileri depolama alanına ayrı olarak, .crt veya .cer dosya uzantısı altında DER kodlamalı bir biçimle yüklenmelidir. - Android 7.0 sürümünden itibaren, parmak izi kaydı ve depolama alanı kullanıcı başına yönetilir. Bir profil sahibinin Device Policy İstemcisi (DPC) Android 7.0 (API düzeyi 24) çalıştıran bir cihazda API düzeyi 23'ü (veya daha altını) hedefliyorsa kullanıcı cihazda parmak izini ayarlamaya devam edebilir ancak iş uygulamaları cihaz parmak izine erişemez. DPC, API düzeyi 24 ve sonraki sürümleri hedeflediğinde kullanıcı, Ayarlar > Güvenlik > İş profili güvenliği bölümüne giderek özellikle iş profili için parmak izi ayarlayabilir.
DevicePolicyManager.getStorageEncryptionStatus()
, şifrelemenin etkin olduğunu ve şifreleme anahtarının kullanıcıya bağlı olduğunu belirtmek için yeni bir şifreleme durumu (ENCRYPTION_STATUS_ACTIVE_PER_USER
) döndürür. Yeni durum yalnızca DPC, API Düzeyi 24 ve sonraki sürümleri hedefliyorsa döndürülür. Daha önceki API düzeylerini hedefleyen uygulamalar için şifreleme anahtarı kullanıcıya veya profile özel olsa bileENCRYPTION_STATUS_ACTIVE
döndürülür.- Android 7.0'da, cihaza ayrı bir iş sorgulaması ile yüklenmiş bir iş profili varsa normalde cihazın tamamını etkileyen çeşitli yöntemler farklı şekilde davranır. Bu yöntemler cihazın tamamını etkilemek yerine yalnızca iş profili için geçerlidir. (Bu yöntemlerin tam listesini
DevicePolicyManager.getParentProfileInstance()
dokümanlarında bulabilirsiniz.) Örneğin,DevicePolicyManager.lockNow()
tüm cihazı kilitlemek yerine yalnızca iş profilini kilitler. Bu yöntemlerin her biri içinDevicePolicyManager
öğesinin üst örneğindeki yöntemi çağırarak eski davranışı elde edebilirsiniz. Bu üst etiketiDevicePolicyManager.getParentProfileInstance()
yöntemini çağırarak alabilirsiniz. Örneğin, üst örneğinlockNow()
yöntemini çağırırsanız cihazın tamamı kilitlenir.
Ek Açıklamaları Saklama
Android 7.0, ek açıklamaların görünürlüğünün yoksayılmasına neden olan hatayı düzeltir. Bu sorun, çalışma zamanının erişememesi gereken ek açıklamalara erişmesini sağladı. Bu ek açıklamalar:
VISIBILITY_BUILD
: Yalnızca derleme sırasında görünür olması amaçlanmıştır.VISIBILITY_SYSTEM
: Çalışma zamanında yalnızca temel sistemde görünür olacak şekilde tasarlanmıştır.
Uygulamanız bu davranışı kullandıysa lütfen ek açıklamalara, çalışma zamanında kullanılabilir olması gereken bir saklama politikası ekleyin. Bunu @Retention(RetentionPolicy.RUNTIME)
kullanarak yapabilirsiniz.
TLS/SSL Varsayılan Yapılandırma Değişiklikleri
Android 7.0, uygulamaların HTTPS ve diğer TLS/SSL trafiği için kullandığı varsayılan TLS/SSL yapılandırmasında aşağıdaki değişiklikleri yapar:
- RC4 şifre paketleri artık devre dışı bırakıldı.
- CHACHA20-POLY1305 şifre paketleri artık etkin.
RC4'ün varsayılan olarak devre dışı bırakılması, sunucu modern şifre paketleri üzerinde anlaşma yapmadığında HTTPS veya TLS/SSL bağlantısının kesilmesine neden olabilir. Tercih edilen düzeltme, sunucunun yapılandırmasını daha güçlü ve modern şifre paketleri ile protokolleri sağlayacak şekilde iyileştirmektir. İdeal olarak TLSv1.2 ve AES-GCM etkinleştirilmelidir. Ayrıca İletim Gizliliği şifre paketleri (ECDHE) etkinleştirilip tercih edilmelidir.
Alternatif bir yöntem de, uygulamayı, sunucuyla iletişim kurmak için özel bir SSLSocketFactory
kullanacak şekilde değiştirmektir. Fabrika, varsayılan şifre paketlerinin yanı sıra sunucunun gerektirdiği bazı şifre paketlerine sahip SSLSocket
örnekleri oluşturacak şekilde tasarlanmalıdır.
Not: Bu değişiklikler WebView
ile ilgili değildir.
Android 7.0'ı hedefleyen uygulamalar
Bu davranış değişiklikleri yalnızca Android 7.0 (API düzeyi 24) veya sonraki sürümleri hedefleyen uygulamalar için geçerlidir. Android 7.0'a göre derlenen veya targetSdkVersion
uygulamasını Android 7.0 ya da sonraki bir sürüme ayarlayan uygulamalar, uygun olduğu durumlarda bu davranışları doğru bir şekilde desteklemek için uygulamalarını değiştirmelidir.
Serileştirme Değişiklikleri
Android 7.0 (API düzeyi 24), varsayılan seriVersionUID değerinin hesaplanmasında spesifikasyonla eşleşmediği bir hatayı düzeltmiştir.
Serializable
uygulayan ve açık bir serialVersionUID
alanı belirtmeyen sınıflar, varsayılan seriVersionUID değerlerinde bir değişiklik görebilir. Bu değişiklik, sınıfın önceki bir sürümde serileştirilmiş veya daha eski bir sürümü hedefleyen bir uygulama tarafından serileştirilmiş örnekleri seri haline getirilmeye çalışıldığında istisnanın oluşmasına neden olur. Hata mesajı aşağıdakine benzer:
local class incompatible: stream classdesc serialVersionUID = 1234, local class serialVersionUID = 4567
Bu sorunları düzeltmek için, etkilenen tüm sınıflara hata mesajından stream classdesc
serialVersionUID
değerine sahip bir serialVersionUID
alanı (ör. bu örnekte 1234
) eklenmesi gerekir. Bu değişiklik, serileştirme kodu yazmaya yönelik tüm iyi uygulama önerileriyle uyumludur ve Android'in tüm sürümlerinde çalışacaktır.
Düzeltilen hata, <clinit>
gibi statik başlatıcı yöntemlerinin varlığıyla ilgiliydi. Spesifikasyona göre sınıfta bir statik başlatıcı yönteminin bulunması veya olmaması, bu sınıf için hesaplanan varsayılan seriSürümUID'ini etkiler.
Hata düzeltmesinden önce hesaplamada, bir sınıfta yoksa bir statik başlatıcı olup olmadığı kontrol edilir.
Daha açık bir ifadeyle, bu değişiklik API düzeyi 23 veya altını hedefleyen uygulamaları, serialVersionUID
alanı olan sınıfları veya statik başlatıcı yöntemi olan sınıfları etkilemeyecektir.
Diğer Önemli Noktalar
- Bir uygulama Android 7.0'da çalışıyor ancak daha düşük bir API düzeyini hedeflediğinde kullanıcı, görüntü boyutunu değiştirdiğinde uygulama işlemi sonlandırılır. Uygulama, bu senaryoyu sorunsuz bir şekilde ele alabilmelidir. Aksi takdirde, kullanıcı uygulamayı Son Kullanılanlar'dan
geri yüklediğinde kilitlenir.
Bu davranışın yaşanmadığından emin olmak için uygulamanızı test etmelisiniz. Uygulamayı DDMS aracılığıyla manuel olarak kapatırken aynı kilitlenmeye neden olarak bunu yapabilirsiniz.
Android 7.0 (API düzeyi 24) ve sonraki sürümleri hedefleyen uygulamalar, yoğunluk değişikliklerinde otomatik olarak devre dışı bırakılmaz ancak yapılandırma değişikliklerine yine de kötü yanıt verebilir.
- Android 7.0 üzerindeki uygulamalar, yapılandırma değişikliklerini sorunsuz şekilde işleyebilmeli ve sonraki başlatmalarda kilitlenmemelidir. Yazı tipi boyutunu değiştirerek (Ayarlar > Ekran > Yazı tipi boyutu) uygulama davranışını doğrulayıp uygulamayı Son Kullanılanlar'dan geri yükleyebilirsiniz.
-
Android'in önceki sürümlerindeki bir hata nedeniyle sistem, ana iş parçacığındaki bir TCP soketine yazmayı katı mod ihlali olarak işaretlemedi. Android 7.0 bu hatayı düzeltir.
Bu davranışı gösteren uygulamalar artık
android.os.NetworkOnMainThreadException
uyarısı verir. Ağ işlemlerinin ana iş parçacığında gerçekleştirilmesi genellikle kötü bir fikirdir. Çünkü bu işlemler genellikle ANR'lere ve jank'a neden olan yüksek bir gecikmeye sahiptir. -
Debug.startMethodTracing()
yöntem ailesi artık varsayılan olarak çıktıları SD kartın üst düzeyi yerine, paylaşılan depolama alanındaki pakete özel dizininizde depolar. Bu, uygulamaların söz konusu API'leri kullanmak için artıkWRITE_EXTERNAL_STORAGE
izni istemesine gerek olmadığı anlamına gelir. -
Birçok platform API'si artık
Binder
işlemleri genelinde gönderilen büyük yük olup olmadığını kontrol etmeye başladı ve sistem artıkTransactionTooLargeExceptions
öğelerini sessizce günlüğe kaydetmek veya gizlemek yerineRuntimeExceptions
olarak yeniden yayınlıyor. Yaygın bir örnek,Activity.onSaveInstanceState()
'de çok fazla veri depolamaktır. Bu da, uygulamanız Android 7.0'ı hedeflediğindeActivityThread.StopInfo
tarafındanRuntimeException
hatası verilmesine neden olur. -
Bir uygulama
View
öğesineRunnable
görevleri yayınlar veView
bir pencereye bağlı değilse sistem,Runnable
göreviniView
ile sıraya alır.View
bir pencereye eklenene kadarRunnable
görevi yürütülmez. Bu davranışla birlikte, aşağıdaki hatalar düzeltilir:- Bir uygulama, istenen pencerenin kullanıcı arayüzü iş parçacığından farklı bir iş parçacığından
View
öğesine yayın yaparsaRunnable
, sonuç olarak yanlış iş parçacığında çalışabilir. Runnable
görevi, döngücü iş parçacığından farklı bir iş parçacığından yayınlandıysa uygulama,Runnable
görevini açığa çıkarabilir.
- Bir uygulama, istenen pencerenin kullanıcı arayüzü iş parçacığından farklı bir iş parçacığından
-
Android 7.0'da
DELETE_PACKAGES
iznine sahip bir uygulama bir paketi silmeye çalışıyorsa ancak bu paketi farklı bir uygulama yüklemişse sistem kullanıcının onayını gerektirir. Bu senaryoda uygulamalar,PackageInstaller.uninstall()
çağrısı yaptıklarında döndürme durumununSTATUS_PENDING_USER_ACTION
olmasını bekler. - Tek algoritması SHA1PRNG, kriptografik açıdan zayıf olduğu için Crypto adlı JCA sağlayıcısı kullanımdan kaldırıldı. Bu sağlayıcı artık kullanılamadığından uygulamalar, anahtarları (güvenli olmayan bir şekilde) türetmek için artık SHA1PRNG kullanamaz. Daha fazla bilgi için Android N'de güvenlik "Kripto" sağlayıcısı kullanımdan kaldırıldı başlıklı blog yayınına göz atın.