Özellikler ve API'ler

Android 17, geliştiriciler için harika yeni özellikler ve API'ler sunuyor. Aşağıdaki bölümlerde, ilgili API'leri kullanmaya başlamanıza yardımcı olmak için bu özellikler özetlenmiştir.

Yeni, değiştirilmiş ve kaldırılmış API'lerin ayrıntılı listesi için API farklılıkları raporunu inceleyin. Yeni API'lerle ilgili ayrıntılar için Android API referansını ziyaret edin. Yeni API'ler görünürlük için vurgulanmıştır.

Platform değişikliklerinin uygulamalarınızı etkileyebileceği alanları da incelemeniz gerekir. Daha fazla bilgi için aşağıdaki sayfalara göz atın:

Temel işlevler

Android 17, temel Android işlevleriyle ilgili aşağıdaki yeni özellikleri ekler.

Yeni ProfilingManager tetikleyicileri

Android 17, performans sorunlarında hata ayıklamak için ayrıntılı veriler toplamanıza yardımcı olmak amacıyla ProfilingManager'a çeşitli yeni sistem tetikleyicileri ekler.

Yeni tetikleyiciler:

  • TRIGGER_TYPE_COLD_START: Tetikleyici, uygulamanın soğuk başlatılması sırasında gerçekleşir. Yanıt hem çağrı yığını örneği hem de sistem izi içerir.
  • TRIGGER_TYPE_OOM: Bir uygulama OutOfMemoryError oluşturduğunda ve buna yanıt olarak Java Heap Dump sağladığında tetikleyici gerçekleşir.
  • TRIGGER_TYPE_KILL_EXCESSIVE_CPU_USAGE: Tetikleyici, bir uygulama anormal ve aşırı CPU kullanımı nedeniyle kapatıldığında gerçekleşir ve yanıt olarak bir çağrı yığını örneği sağlar.

Sistem tetikleyicisinin nasıl ayarlanacağını öğrenmek için tetikleyici tabanlı profilleme ve profilleme verilerini alma ve analiz etme ile ilgili dokümanlara bakın.

JobDebugInfo API'leri

Android 17, geliştiricilerin JobScheduler işlerinde hata ayıklamasına yardımcı olmak için yeni JobDebugInfo API'leri sunar. Bu API'ler, işlerin neden çalışmadığı, ne kadar süre çalıştığı ve diğer toplu bilgilerle ilgili veriler sağlar.

Genişletilmiş JobDebugInfo API'lerinin ilk yöntemi olan getPendingJobReasonStats(), işin neden bekleyen yürütme durumunda olduğuna dair nedenlerin ve ilgili kümülatif bekleyen sürelerin haritasını döndürür. Bu yöntem, planlanmış bir işin neden beklendiği gibi çalışmadığına dair bilgi edinmenizi sağlamak için getPendingJobReasonsHistory() ve getPendingJobReasons() yöntemlerini birleştirir. Ancak hem süreyi hem de iş nedenini tek bir yöntemde kullanılabilir hale getirerek bilgi almayı kolaylaştırır.

Örneğin, belirtilen bir jobId için yöntem, PENDING_JOB_REASON_CONSTRAINT_CHARGING ve 60.000 ms'lik bir süre döndürebilir. Bu, şarj kısıtlaması karşılanmadığı için işin 60.000 ms boyunca beklemede olduğunu gösterir.

Gizlilik

Android 17, kullanıcı gizliliğini iyileştirmek için aşağıdaki yeni özellikleri içerir.

Android kişi seçici

Android Kişi Seçici, kullanıcıların kişilerle ilgili bilgileri uygulamanızla paylaşması için standartlaştırılmış ve göz atılabilir bir arayüzdür. Android 17 veya sonraki sürümlerin yüklü olduğu cihazlarda kullanılabilen seçici, geniş kapsamlı READ_CONTACTS iznine gizliliği koruyan bir alternatif sunar. Uygulamanız, kullanıcının tüm adres defterine erişim isteğinde bulunmak yerine ihtiyaç duyduğu veri alanlarını (ör. telefon numaraları veya e-posta adresleri) belirtir ve kullanıcı, paylaşılacak belirli kişileri seçer. Bu sayede uygulamanız yalnızca seçilen verilere okuma erişimi kazanır. Böylece, kullanıcı arayüzünü oluşturmak veya bakımını yapmak zorunda kalmadan yerleşik arama, profil değiştirme ve çoklu seçim özellikleriyle tutarlı bir kullanıcı deneyimi sunarken ayrıntılı kontrol de sağlanır.

Daha fazla bilgi için kişi seçici dokümanlarına bakın.

Güvenlik

Android 17, cihaz ve uygulama güvenliğini artırmak için aşağıdaki yeni özellikleri ekler.

Android Gelişmiş Koruma Modu (AAPM)

Android Gelişmiş Koruma Modu, Android kullanıcılarına güçlü bir yeni güvenlik özellikleri paketi sunarak kullanıcıları, özellikle de daha yüksek risk altındaki kullanıcıları gelişmiş saldırılardan koruma konusunda önemli bir adım atıyor. İsteğe bağlı bir özellik olarak tasarlanan AAPM, kullanıcıların istediği zaman etkinleştirerek güvenlik korumaları uygulayabileceği tek bir yapılandırma ayarıyla etkinleştirilir.

Bu temel yapılandırmalar arasında bilinmeyen kaynaklardan uygulama yüklenmesini engelleme (yan yükleme), USB veri sinyalini kısıtlama ve Google Play Protect taramasını zorunlu kılma yer alır. Bu yapılandırmalar, cihazın saldırı yüzey alanını önemli ölçüde azaltır. Geliştiriciler, modun durumunu algılamak için AdvancedProtectionManager API'sini kullanarak bu özellikle entegrasyon yapabilir. Böylece, kullanıcı modu etkinleştirdiğinde uygulamalar otomatik olarak daha sıkı bir güvenlik duruşu benimseyebilir veya yüksek riskli işlevleri kısıtlayabilir.

Bağlantı

Android 17, cihaz ve uygulama bağlantısını iyileştirmek için aşağıdaki özellikleri ekler.

Kısıtlanmış uydu ağları

Uygulamaların düşük bant genişliğine sahip uydu ağlarında etkili bir şekilde çalışmasını sağlamak için optimizasyonlar uygular.

Kullanıcı deneyimi ve sistem arayüzü

Android 17, kullanıcı deneyimini iyileştirmek için aşağıdaki değişiklikleri içerir.

Aktarma

Handoff, Android 17'de kullanıma sunulacak yeni bir özellik ve API'dir. Uygulama geliştiriciler, kullanıcılarına cihazlar arası süreklilik sağlamak için bu özelliği entegre edebilir. Kullanıcının bir Android cihazda uygulama etkinliği başlatmasına ve bunu başka bir Android cihaza aktarmasına olanak tanır. Devretme, kullanıcının cihazının arka planında çalışır ve kullanıcının yakındaki diğer cihazlarındaki kullanılabilir etkinlikleri, alıcı cihazdaki başlatıcı ve görev çubuğu gibi çeşitli giriş noktaları üzerinden gösterir.

Uygulamalar, alıcı cihaza yüklenmiş ve bu cihazda kullanılabilirse aynı yerel Android uygulamasını başlatmak için Handoff'u kullanabilir. Bu uygulama içi akışta, kullanıcı belirlenen etkinliğe derin bağlantıyla yönlendirilir. Alternatif olarak, uygulamadan web'e geçiş, yedek seçenek olarak sunulabilir veya doğrudan URL ile geçiş ile uygulanabilir.

Aktarma desteği, etkinlik bazında uygulanır. Devretme'yi etkinleştirmek için etkinlik için setHandoffEnabled() yöntemini çağırın. Alıcı cihazda yeniden oluşturulan etkinliğin uygun durumu geri yükleyebilmesi için devretme işlemiyle birlikte ek verilerin de iletilmesi gerekebilir. Devretme işleminin, etkinliği alıcı cihazda nasıl ele alıp yeniden oluşturacağını belirten ayrıntıları içeren bir HandoffActivityData nesnesi döndürmek için onHandoffActivityRequested() geri çağırma işlevini uygulayın.

Canlı Güncelleme - Semantic Color API

Android 17 ile Live Update, evrensel anlamı olan renkleri desteklemek için Semantic Coloring API'lerini kullanıma sunuyor.

Aşağıdaki sınıflar semantik renklendirmeyi destekler:

Boyama

  • Yeşil: Güvenlikle ilişkilidir. Bu renk, kullanıcılara güvenli bir durumda olduğunuzu bildirmek için kullanılmalıdır.
  • Turuncu: Dikkat çekmek ve fiziksel tehlikeleri işaretlemek için kullanılır. Bu renk, kullanıcıların daha iyi koruma ayarları yapmak için dikkat etmesi gereken durumlarda kullanılmalıdır.
  • Kırmızı: Genellikle tehlikeyi gösterir, durdurma. Kullanıcıların dikkatini acilen çekmeniz gereken durumlarda gösterilmelidir.
  • Mavi: Bilgilendirici olan ve diğer içeriklerden ayrılması gereken içerikler için nötr renk.

Aşağıdaki örnekte, bir bildirimdeki metne anlamsal stillerin nasıl uygulanacağı gösterilmektedir:

  val ssb = SpannableStringBuilder()
        .append("Colors: ")
        .append("NONE", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_UNSPECIFIED), 0)
        .append(", ")
        .append("INFO", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_INFO), 0)
        .append(", ")
        .append("SAFE", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_SAFE), 0)
        .append(", ")
        .append("CAUTION", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_CAUTION), 0)
        .append(", ")
        .append("DANGER", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_DANGER), 0)

    Notification.Builder(context, channelId)
          .setSmallIcon(R.drawable.ic_icon)
          .setContentTitle("Hello World!")
          .setContentText(ssb)
          .setOngoing(true)
              .setRequestPromotedOngoing(true)

Android 17 için UWB Downlink-TDoA API'si

Aşağı bağlantı geliş zamanı farkı (DL-TDoA) aralığı, bir cihazın sinyallerin göreli geliş zamanlarını ölçerek birden fazla sabite göre konumunu belirlemesine olanak tanır.

Aşağıdaki snippet'te Ranging Manager'ın nasıl başlatılacağı, cihaz özelliklerinin nasıl doğrulanacağı ve DL-TDoA oturumunun nasıl başlatılacağı gösterilmektedir:

Kotlin

class RangingApp {

    fun initDlTdoa(context: Context) {
        // Initialize the Ranging Manager
        val rangingManager = context.getSystemService(RangingManager::class.java)

        // Register for device capabilities
        val capabilitiesCallback = object : RangingManager.CapabilitiesCallback {
            override fun onRangingCapabilities(capabilities: RangingCapabilities) {
                // Make sure Dl-TDoA is supported before starting the session
                if (capabilities.uwbCapabilities != null && capabilities.uwbCapabilities!!.isDlTdoaSupported) {
                    startDlTDoASession(context)
                }
            }
        }
        rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback)
    }

    fun startDlTDoASession(context: Context) {

        // Initialize the Ranging Manager
        val rangingManager = context.getSystemService(RangingManager::class.java)

        // Create session and configure parameters
        val executor = Executors.newSingleThreadExecutor()
        val rangingSession = rangingManager.createRangingSession(executor, RangingSessionCallback())
        val rangingRoundIndexes = intArrayOf(0)
        val config: ByteArray = byteArrayOf() // OOB config data
        val params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes)

        val rangingDevice = RangingDevice.Builder().build()
        val rawTagDevice = RawRangingDevice.Builder()
            .setRangingDevice(rangingDevice)
            .setDlTdoaRangingParams(params)
            .build()

        val dtTagConfig = RawDtTagRangingConfig.Builder(rawTagDevice).build()

        val preference = RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig)
            .setSessionConfig(SessionConfig.Builder().build())
            .build()

        // Start the ranging session
        rangingSession.start(preference)
    }
}

private class RangingSessionCallback : RangingSession.Callback {
    override fun onDlTdoaResults(peer: RangingDevice, measurement: DlTdoaMeasurement) {
        // Process measurement results here
    }
}

Java

public class RangingApp {

    public void initDlTdoa(Context context) {

        // Initialize the Ranging Manager
        RangingManager rangingManager = context.getSystemService(RangingManager.class);

        // Register for device capabilities
        RangingManager.CapabilitiesCallback capabilitiesCallback = new RangingManager.CapabilitiesCallback() {
            @Override
            public void onRangingCapabilities(RangingCapabilities capabilities) {
                // Make sure Dl-TDoA is supported before starting the session
                if (capabilities.getUwbCapabilities() != null && capabilities.getUwbCapabilities().isDlTdoaSupported) {
                    startDlTDoASession(context);
                }
            }
        };
        rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback);
    }

    public void startDlTDoASession(Context context) {
        RangingManager rangingManager = context.getSystemService(RangingManager.class);

        // Create session and configure parameters
        Executor executor = Executors.newSingleThreadExecutor();
        RangingSession rangingSession = rangingManager.createRangingSession(executor, new RangingSessionCallback());
        int[] rangingRoundIndexes = new int[] {0};
        byte[] config = new byte[0]; // OOB config data
        DlTdoaRangingParams params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes);

        RangingDevice rangingDevice = new RangingDevice.Builder().build();
        RawRangingDevice rawTagDevice = new RawRangingDevice.Builder()
                .setRangingDevice(rangingDevice)
                .setDlTdoaRangingParams(params)
                .build();

        RawDtTagRangingConfig dtTagConfig = new RawDtTagRangingConfig.Builder(rawTagDevice).build();

        RangingPreference preference = new RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig)
                .setSessionConfig(new SessionConfig.Builder().build())
                .build();

        // Start the ranging session
        rangingSession.start(preference);
    }

    private static class RangingSessionCallback implements RangingSession.Callback {

        @Override
        public void onDlTdoaResults(RangingDevice peer, DlTdoaMeasurement measurement) {
            // Process measurement results here
        }
    }
}

Bant dışı (OOB) yapılandırmalar

Aşağıdaki snippet'te, Wi-Fi ve BLE için DL-TDoA OOB yapılandırma verilerine örnek verilmiştir:

Java

// Wifi Configuration
byte[] wifiConfig = {
    (byte) 0xDD, (byte) 0x2D, (byte) 0x5A, (byte) 0x18, (byte) 0xFF, // Header
    (byte) 0x5F, (byte) 0x19, // FiRa Sub-Element
    (byte) 0x02, (byte) 0x00, // Profile ID
    (byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address
    (byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index
    (byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID
    (byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV
    (byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration
    (byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR
    (byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration
    (byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01  // Session ID
};

// BLE Configuration
byte[] bleConfig = {
    (byte) 0x2D, (byte) 0x16, (byte) 0xF4, (byte) 0xFF, // Header
    (byte) 0x5F, (byte) 0x19, // FiRa Sub-Element
    (byte) 0x02, (byte) 0x00, // Profile ID
    (byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address
    (byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index
    (byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID
    (byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV
    (byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration
    (byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR
    (byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration
    (byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01  // Session ID
};

Eksik olduğu için kullanıma hazır yapılandırmayı kullanamıyorsanız veya kullanıma hazır yapılandırmada olmayan varsayılan değerleri değiştirmeniz gerekiyorsa aşağıdaki snippet'te gösterildiği gibi DlTdoaRangingParams.Builder ile parametreler oluşturabilirsiniz. DlTdoaRangingParams.createFromFiraConfigPacket() yerine aşağıdaki parametreleri kullanabilirsiniz:

Kotlin

val dlTdoaParams = DlTdoaRangingParams.Builder(1)
    .setComplexChannel(UwbComplexChannel.Builder()
            .setChannel(9).setPreambleIndex(10).build())
    .setDeviceAddress(deviceAddress)
    .setSessionKeyInfo(byteArrayOf(0x01, 0x02, 0x03, 0x04))
    .setRangingIntervalMillis(240)
    .setSlotDuration(UwbRangingParams.DURATION_2_MS)
    .setSlotsPerRangingRound(20)
    .setRangingRoundIndexes(byteArrayOf(0x01, 0x05))
    .build()

Java

DlTdoaRangingParams dlTdoaParams = new DlTdoaRangingParams.Builder(1)
    .setComplexChannel(new UwbComplexChannel.Builder()
            .setChannel(9).setPreambleIndex(10).build())
    .setDeviceAddress(deviceAddress)
    .setSessionKeyInfo(new byte[]{0x01, 0x02, 0x03, 0x04})
    .setRangingIntervalMillis(240)
    .setSlotDuration(UwbRangingParams.DURATION_2_MS)
    .setSlotsPerRangingRound(20)
    .setRangingRoundIndexes(new byte[]{0x01, 0x05})
    .build();