Gereksinimler ve Ön Hazırlık
İleri düzey sensör entegrasyonu için Flutter SDK'nın en güncel sürümünü (2026 standartları) kullanmanız önerilir. Projenize sensör verilerini dahil etmek için "sensors_plus" paketini kullanacağız. Bu paket, Android ve iOS platformlarında düşük gecikmeli veri akışı sağlar.
Öncelikle pubspec.yaml dosyanıza gerekli bağımlılığı ekleyin:
dependencies:
flutter:
sdk: flutter
sensors_plus: ^6.0.0
Paketi ekledikten sonra terminalinizde flutter pub get komutunu çalıştırarak bağımlılıkları projenize dahil edin. İvmeölçer verileri, cihazın X, Y ve Z eksenlerindeki ivmelenmesini m/s² cinsinden döndürür.
Adım Adım İvmeölçer Verisi Okuma
Sensör verilerini dinlemek için accelerometerEventStream metodunu kullanırız. Bu akış, cihaz hareket ettikçe sürekli veri yayar. Bellek sızıntılarını (memory leaks) önlemek için stream aboneliğini yönetmek kritik öneme sahiptir.
import 'package:sensors_plus/sensors_plus.dart';
import 'dart:async';
class SensorManager {
StreamSubscription? _streamSubscription;
void startListening() {
_streamSubscription = accelerometerEventStream().listen((AccelerometerEvent event) {
print("X: ${event.x}, Y: ${event.y}, Z: ${event.z}");
});
}
void stopListening() {
_streamSubscription?.cancel();
}
}
Yukarıdaki kodda, StreamSubscription kullanarak sensör akışını başlatıyor ve ihtiyaç duyulmadığında cancel() metodu ile sonlandırıyoruz. Bu, uygulamanızın arka planda gereksiz pil tüketmesini engeller.
Gürültü Filtreleme ve Düşük Geçiren Filtre (Low-Pass Filter)
İvmeölçer verileri doğası gereği "gürültülüdür" (titreşimler, el titremesi vb.). Bu gürültüyü temizlemek için Düşük Geçiren Filtre (Low-Pass Filter) algoritması kullanılır. Bu yöntem, ani ve kısa süreli değişimleri yok sayarak daha pürüzsüz bir veri akışı sağlar.
double x = 0, y = 0, z = 0;
final double alpha = 0.8; // Filtre katsayısı
void applyFilter(double newX, double newY, double newZ) {
x = alpha * x + (1 - alpha) * newX;
y = alpha * y + (1 - alpha) * newY;
z = alpha * z + (1 - alpha) * newZ;
}
Buradaki alpha değeri, filtrenin ne kadar "sert" olacağını belirler. 0.8 değeri, geçmiş veriye daha fazla ağırlık vererek ani sarsıntıları yumuşatır.
Sensör Verilerini Arayüzle Senkronize Etme
Sensörden gelen veriyi setState ile arayüze yansıtmak, yüksek frekanslı güncellemelerde performans sorunlarına yol açabilir. Bunun yerine ValueNotifier veya StreamBuilder kullanarak sadece ilgili widget'ı güncelleyebilirsiniz.
StreamBuilder(
stream: accelerometerEventStream(),
builder: (context, snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return Text("İvme: ${snapshot.data!.x.toStringAsFixed(2)}");
},
)
StreamBuilder, sensör verisi her değiştiğinde arayüzü günceller. Ancak, çok yüksek hızda veri geliyorsa Stream'i throttle (kısıtlama) metoduna tabi tutarak güncelleme sıklığını düşürebilirsiniz.
İvmeölçer Entegrasyon Yöntemleri Karşılaştırması
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Ham Akış (Stream) | Anlık tepki süresi | Yüksek gürültü |
| Low-Pass Filtre | Pürüzsüz hareket | Hafif gecikme |
| UserAccelerometer | Yerçekiminden arındırılmış | Daha az veri tipi |
Kritik Uyarılar ve Güvenlik
Dikkat: Sensör verileri, cihazın fiziksel konumunu ve hareket alışkanlıklarını takip etmek için kullanılabilir. Kullanıcının gizliliğine saygı duyun ve sensör verilerini sadece uygulama işlevi için gerekli olduğunda işleyin. Üretim ortamında (production), verileri yerel olarak işleyip sunucuya göndermeden önce anonimleştirin.
Güvenlik açısından, sensörden gelen veriyi asla doğrudan bir veritabanı sorgusuna veya dış komut çalıştırma fonksiyonuna (eval vb.) parametre olarak göndermeyin. Verileri her zaman doğrulayın (validation) ve tip dönüşümlerini kontrol edin.
Sıkça Sorulan Sorular
İvmeölçer ile jiroskop arasındaki fark nedir?
İvmeölçer doğrusal ivmeyi (hız değişimi) ölçerken, jiroskop cihazın açısal dönüş hızını (rotasyon) ölçer. İleri düzey uygulamalarda ikisi birlikte kullanılır.
Sensör verileri neden pil tüketir?
Sensörler sürekli olarak donanımdan veri çeker ve işlemciyi uyandırır. Kullanıcı uygulamayı kapattığında veya arka plana attığında mutlaka cancel() metodunu çağırarak stream'i kapatmalısınız.
Filtre katsayısı (alpha) nasıl belirlenir?
Alpha değeri tamamen uygulamanızın hassasiyet ihtiyacına bağlıdır. 0.1 ile 0.9 arasında deneyerek, cihazın hareketine en uygun tepkiyi veren değeri seçebilirsiniz.
Tüm cihazlarda sensör hassasiyeti aynı mıdır?
Hayır, giriş seviyesi cihazların sensörleri daha düşük frekansta (Hz) çalışabilir. Uygulamanızı farklı cihazlarda test etmeniz önemlidir.
Sensör verilerini kaydetmek güvenli midir?
Kullanıcı verisi hassas bir konudur. Eğer verileri yerel cihazda saklayacaksanız, verileri şifrelenmiş bir veritabanında (örneğin SQLCipher) tutmanız önerilir.
İleri Düzey İpucu: Sensör Füzyonu (Sensor Fusion) ile Hassasiyeti Artırma
İvmeölçer verileri, statik durumlarda yerçekimi vektörünü belirlemek için mükemmel olsa da, dinamik hareketlerde "gürültü" ve "drift" (sapma) sorunları yaşar. Profesyonel uygulamalarda, ivmeölçer verilerini jiroskop ve manyetometre verileriyle birleştiren Complementary Filter veya Kalman Filter algoritmaları kullanılır. Bu yöntem, sensörlerin birbirinin zayıf yönlerini kapatmasını sağlar.
Aşağıdaki örnek, ivmeölçer ve jiroskop verilerini basit bir tamamlayıcı filtre ile birleştirerek daha kararlı bir açı değeri elde etmenizi sağlar:
double alpha = 0.98;
double angle = 0.0;
// Sensör verileri geldikçe çağrılır
void updateOrientation(double accAngle, double gyroRate, double dt) {
// Tamamlayıcı Filtre: (alpha * (önceki_açı + jiroskop_değişimi)) + ((1 - alpha) * ivmeölçer_açısı)
angle = alpha * (angle + gyroRate * dt) + (1 - alpha) * accAngle;
print("Filtrelenmiş Açı: $angle");
}
Performans Optimizasyonu ve Bellek Yönetimi
Sensör verileri saniyede onlarca kez güncellenir. Bu yoğun veri akışı, yanlış yönetildiğinde uygulamanın UI thread'ini kitleyebilir veya yüksek pil tüketimine neden olabilir. Performansı korumak için şu stratejileri uygulayın:
- Stream Throttling: Sensör verilerini doğrudan UI'a yansıtmak yerine,
rxdartkütüphanesini kullanarak veri akışını belirli aralıklarla (örneğin 60ms) örnekleyin. - Isolate Kullanımı: Eğer veriler üzerinde ağır matematiksel hesaplamalar (matris çarpımları, karmaşık filtreler) yapıyorsanız, bu işlemleri ana thread'den ayırarak
Isolateiçerisinde çalıştırın. - Bellek Sızıntılarını Önleme:
StreamSubscriptionnesnelerini, widget yaşam döngüsü sona erdiğinde mutlakacancel()metodu ile sonlandırın.
// StreamSubscription yönetimi örneği
StreamSubscription? _sensorSubscription;
@override
void dispose() {
// Bellek sızıntısını önlemek için aboneliği iptal et
_sensorSubscription?.cancel();
super.dispose();
}
Sensör Verileri İçin Birim Testi Stratejileri
Sensör tabanlı uygulamalarda, fiziksel cihaz olmadan mantıksal testler yapmak zordur. Bu sorunu aşmak için "Mocking" (taklit etme) yöntemini kullanmalısınız. Sensör verilerini bir Abstract Class arkasına gizleyerek, test ortamında gerçek sensör yerine önceden kaydedilmiş veri setlerini (JSON veya CSV dosyaları) akıtabilirsiniz.
| Test Türü | Odak Noktası | Araç |
|---|---|---|
| Birim Testi | Filtreleme algoritmalarının matematiksel doğruluğu | Dart Test Package |
| Entegrasyon Testi | Sensör akışının UI ile senkronizasyonu | Flutter Integration Test |
Bu yaklaşımlar, uygulamanızın farklı donanım konfigürasyonlarında bile tutarlı ve kararlı çalışmasını garanti altına alacaktır.
Sonuç
Flutter ile ivmeölçer entegrasyonu, doğru filtreleme ve yönetim teknikleriyle oldukça güçlü bir araçtır. Bu makalede öğrendiğiniz düşük geçiren filtreleme, stream yönetimi ve performans optimizasyonları ile profesyonel seviyede hareket algılayan mobil uygulamalar geliştirebilirsiniz. Bir sonraki adım olarak, ivmeölçer verilerini Gyroscope verileriyle birleştirerek "Sensor Fusion" (Sensör Füzyonu) tekniklerini araştırmanızı öneririm.


Yorumlar (0)
Yorum Yaz