<

Mobilde Arka Plan Konum: iOS ve Android'in Görünmez Duvarları

Müşteri toplantısında masaya bir harita çıktısı kondu. Saha teknisyeninin güzergâhında, öğlen 12:10 ile 12:50 arasında 40 dakikalık bir boşluk vardı. Müşteri "personel o saatte şantiyedeydi, sizin sistem çalışmıyor" dedi. Teknisyenle konuştuk: telefonu cebindeymiş, uygulamayı açmamış, ama kapatmamış da. Sunucu loglarına baktık: o cihazdan 40 dakika boyunca tek paket gelmemişti. Uygulama ölmüştü ve bunun kimseye haber verme yükümlülüğü yoktu.

Saha personeli takibi için geliştirdiğimiz mobil uygulamanın ilk sürümü, konum takibini masaüstü mantığıyla kurgulamıştı: uygulama açılır, konum dinlenir, sunucuya gönderilir. Mobil işletim sistemlerinin son yıllarda arka plandaki uygulamalara açtığı savaşı hafife almıştık. O 40 dakikalık boşluk, üç aylık bir yeniden yazma sürecinin fitilini ateşledi.

İlk Yanlış Hipotez: "GPS Çekmiyor"

İlk refleksimiz donanımı suçlamak oldu: bina içi, GPS sinyali zayıf, cihaz eski. Ama veriler bu hipotezi yalanladı. Boşluklar bina girişleriyle örtüşmüyordu; telefonun ekranının kapanmasından 15-25 dakika sonrayla örtüşüyordu. Ayrıca boşluklar cihaz markasına göre çarpıcı biçimde farklıydı: pilot gruptaki Xiaomi cihazlarda günde ortalama 6 boşluk, Samsung'larda 2, iPhone'larda desen bambaşkaydı. Sorun gökyüzünde değil, işletim sistemindeydi.

Android Cephesi: Doze ve Üreticilerin Gizli Katilleri

Android 6 ile gelen Doze modu, ekran kapalı ve cihaz hareketsizken uygulamaların ağ erişimini ve zamanlayıcılarını pencerelere hapseder. Bizim 30 saniyede bir konum gönderen servisimiz, Doze'a giren cihazda önce seyrekleşiyor, sonra tamamen susuyordu. Standart çözüm belli: kalıcı bildirimli bir foreground service. Bunu ekledik ve stok Android'lerde boşluklar neredeyse bitti.

Ama Xiaomi, Huawei ve Oppo gibi üreticilerin kendi agresif pil yöneticileri foreground service'i bile öldürüyordu. MIUI'nin "battery saver" ayarı, kullanıcı elle istisna tanımlamadıkça servisi birkaç saatte bir kesiyordu. Buna teknik çözüm yok; ürün çözümü var. Uygulamaya, cihaz markasını algılayıp o markaya özgü ayar ekranına yönlendiren ve adım adım görsel anlatan bir kurulum sihirbazı ekledik. Sıkıcı bir iş gibi görünür ama tek başına en etkili değişiklik buydu: Xiaomi cihazlardaki günlük boşluk sayısı 6'dan 0.4'e indi.

Bu arada Android'in kendi kural kitabı da sabit durmuyor. Android 8 arka plan servislerine ilk büyük kısıtları getirdi; 10 ve 11 ise arka plan konum iznini ayrı bir izin hâline getirip "her zaman izin ver" seçeneğini ilk diyalogdan çıkardı. Yani kullanıcıyı önce uygulama içinde ikna edip sonra sistem ayarlarına yönlendirmeniz gerekiyor. Her yeni Android sürümünde davranış değiştiği için test cihazı rafımız kalabalıklaştı: dört üretici, üç Android sürümü, toplam dokuz fiziksel cihazla düzenli tur atıyoruz. Doze'u beklemek yerine adb'nin deviceidle komutlarıyla anında tetiklemeyi öğrenmek, test süremizi saatlerden dakikalara indirdi; bu komutları öğrenene kadar "cihazı bırak, iki saat bekle, loglara bak" diye test yapıyorduk.

iOS Cephesi: İzin Diplomasisi

iOS tarafında duvar başkaydı. Konum izni "yalnızca kullanırken" verilmişse uygulama arka plana geçtiği anda konum akışı durur. "Her zaman" iznine giden yol ise iki aşamalı ve kullanıcının yarısı ikinci aşamada vazgeçiyordu. İzin isteme anını rastgele değil, kullanıcının değeri gördüğü âna taşıdık: ilk mesai kaydı başarıyla oluştuğunda, "mesai sırasında uygulama kapalıyken de kaydın sürmesi için" açıklamasıyla sorduk. Her zaman izni oranı yüzde 48'den 81'e çıktı.

İkinci iOS numarası significant location change servisiydi. Uygulama iOS tarafından bellekten atılsa bile, cihaz yaklaşık 500 metre yer değiştirince sistem uygulamayı arka planda yeniden başlatıp konumu teslim ediyor. Bu, öldürülen uygulamanın kendini dirilteceği bir çapa görevi görüyor. Ayrıca allowsBackgroundLocationUpdates bayrağını ve otomatik duraklatmayı kapatan ayarı unutan olursa, her şey doğru görünürken akış yine kesilir; biz bir haftamızı tam olarak buna verdik.

Kesintiyle barışmanın teknik karşılığı, cihaz tarafında sağlam bir store-and-forward katmanıydı. Uygulama, topladığı her noktayı önce yerel SQLite tamponuna yazıyor; gönderim başarılı olursa tampondan siliyor, olmazsa nokta orada bekliyor. Tampon 10 bin nokta ile sınırlı ve dolarsa en eski kayıtlar seyreltilerek — silinerek değil, her ikinci nokta atılarak — yer açılıyor; böylece uzun bir çevrimdışılıkta bile güzergâhın iskeleti korunuyor. Sunucuya gönderimde her pakete cihazda üretilmiş bir sıra numarası eşlik ediyor; sunucu bu sayede mükerrer göndermeleri eliyor ve hangi aralıkların hâlâ eksik olduğunu cihaza bildirebiliyor. Bu katman olmadan arka plan savaşının kazanılmış her cephesi, tek bir tünel geçişinde anlamını yitiriyor.

Batarya: Karşı Tarafın da Haklı Olduğu Yer

İşletim sistemlerini düşman gibi anlattım ama savundukları şey meşru: pilot sürümümüz 8 saatlik mesaide bataryanın yüzde 31'ini yiyordu. Kimse böyle bir uygulamayı telefonunda yaşatmaz; kullanıcılar onu öldüren ayarları hakkıyla açıyordu. Yani teknik savaşın yarısı kendi tüketimimizi düşürmekti. GPS'i sabit aralıkla değil harekete duyarlı örnekledik: ivmeölçer hareketsizlik bildirdiğinde konum isteğini dakikada bire düşürdük, hareket başlayınca 15 saniyeye çıkardık. Paketleri tek tek değil 20'lik gruplar hâlinde, radyoyu bir kez uyandırarak gönderdik. Tüketim yüzde 31'den 9'a indi ve ilginç biçimde, kullanıcıların uygulamayı elle öldürme oranı da düştü.

Teknik savaşın yanında bir de insan cephesi vardı ve onu görmezden gelen çözüm yaşamıyor. Takip edilen kişi bir çalışan ve iOS, arka planda konum kullanan uygulamayı mavi çubukla, Android kalıcı bildirimle zaten ilan ediyor; gizlice izleme diye bir seçenek hem hukuken hem teknik olarak yok. Müşterilerimize kurulum paketinin yanında bir de aydınlatma metni şablonu ve "mesai dışı takip kapalı" varsayılanı verdik. Uygulamada mesai penceresi tanımlı: vardiya bitince konum toplama duruyor ve bunu kullanıcı da ekranda görüyor. İlginç olan şu ki bu şeffaflık teknik metrikleri de düzeltti; ne zaman izlendiğini bilen ve buna rızası olan kullanıcı, uygulamayı elle öldürmeyi bırakıyor.

Boşluksuz Veri Diye Bir Şey Yok

Bir de işin ölçüm tarafı var: bu üç aylık savaşta neyin işe yarayıp neyin yaramadığını ancak metrikle görebildik. Her cihazdan günlük bir sağlık özeti topluyoruz: kaç nokta üretildi, kaçı zamanında ulaştı, en uzun sessizlik kaç dakikaydı, uygulama kaç kez yeniden başladı. Bu özetler olmadan "Xiaomi'de düzeldi mi" sorusunun cevabı ancak müşteri şikâyetinin gelmemesi olurdu ki bu, en pahalı ölçüm yöntemidir. Sağlık panosu sayesinde bir üreticinin yeni ROM güncellemesinin servisimizi yeniden öldürmeye başladığını, ilk şikâyetten günler önce gördük.

Üç ayın sonunda boşluklar bitmedi; yönetilebilir hâle geldi. Günlük ortalama kesinti, cihaz başına 47 dakikadan 4 dakikanın altına indi. Ama asıl olgunlaşma sunucu tarafında oldu: sistemin geri kalanını, verinin gecikebileceği ve delik olabileceği varsayımıyla yeniden kurduk. Cihaz çevrimdışı biriktirip sonra topluca gönderiyor, sunucu geç gelen noktaları zaman damgasına göre yerine oturtuyor, raporlar "veri yok" ile "hareket yok" ayrımını açıkça gösteriyor. Mobil arka plan konumunda hedef kesintisizlik değil; kesintiyle dürüstçe yaşamak. Saha uygulamanızda benzer boşluklarla uğraşıyorsanız şuradan ulaşın; marka marka hangi ayarın ne kırdığına dair epey birikmiş defterimiz var.

📅 Yayınlanma:  ·  Yakup Zengin