# 31. Hafta — Bildirim ve Paylaşım

## Bu hafta ne yapacağız?

Flutter uygulamasını işletim sisteminin iki özelliğine bağlayacağız. İlk uygulama, kullanıcı iznini yöneten gerçek bir yerel bildirim servisiyle çalışma hatırlatıcısı oluşturacak. İkinci uygulama hassas bilgileri yalnız kullanıcının açık komutuyla sistem paylaşım menüsüne gönderecek.

## Kazanımlar

- `flutter_local_notifications` paketini başlatma
- Android bildirim kanalı, önem ve öncelik değerlerini tanımlama
- Android ve iOS bildirim ayrıntılarını ayırma
- Bildirim iznini doğru zamanda isteme
- `share_plus` ile sistem paylaşım sayfasını açma
- Paylaşılacak metni model verilerinden güvenli biçimde üretme
- Eklenti bağımlılıklarını arayüz sınıflarıyla ayırma
- Sahte servislerle bildirim ve paylaşım widget testleri yazma

## Çözümlü uygulama — Ders Hatırlatıcısı

### Bildirim servisi sözleşmesi

```dart
abstract class BildirimServisi {
  Future<void> hazirla();
  Future<void> goster({
    required String baslik,
    required String govde,
  });
}
```

Arayüzün görevi bildirim paketiyle konuşmak değil, kullanıcı girdisini doğrulayıp bu sözleşmeyi çağırmaktır. Testte gerçek bildirim eklentisi yerine çağrıları kaydeden sahte servis kullanılır.

### Eklentiyi başlatma ve izin isteme

```dart
const ayarlar = InitializationSettings(
  android: AndroidInitializationSettings('@mipmap/ic_launcher'),
  iOS: DarwinInitializationSettings(),
);

await eklenti.initialize(ayarlar);

await eklenti
    .resolvePlatformSpecificImplementation<
        AndroidFlutterLocalNotificationsPlugin>()
    ?.requestNotificationsPermission();
```

Bildirim izni uygulama açılır açılmaz sebepsiz istenmez. Öğrenci “Bildirimi dene” işlemini seçtiğinde hazırlanır.

### Bildirim kanalı ve içeriği

```dart
const ayrinti = NotificationDetails(
  android: AndroidNotificationDetails(
    'ders_hatirlatmalari',
    'Ders Hatırlatmaları',
    channelDescription: 'Öğrencinin oluşturduğu çalışma bildirimleri',
    importance: Importance.high,
    priority: Priority.high,
  ),
  iOS: DarwinNotificationDetails(),
);

await eklenti.show(31, baslik, govde, ayrinti);
```

Android’de kanal kimliği sonradan rastgele değiştirilmemelidir. Kullanıcı kanal ayarlarını işletim sistemi üzerinden yönetebilir.

### Form doğrulaması ve kullanıcı geri bildirimi

```dart
if (konu.text.trim().isEmpty) {
  setState(() => durum = 'Hatırlatma konusu boş bırakılamaz');
  return;
}

await widget.servis.hazirla();
await widget.servis.goster(
  baslik: 'Çalışma zamanı',
  govde: '${konu.text.trim()} • $dakika dakika',
);
```

Bildirim içeriği sabit bir görsel değil; öğrencinin konu ve süre seçiminden oluşturulur.

![Ders Hatırlatıcısı gerçek Flutter ekranı](../../screenshots/week-31-adapted.png)

Widget testi düğmeye bastı; servisin hazırlandığını, başlığın “Çalışma zamanı” olduğunu ve gövdenin öğrenci girdisinden üretildiğini doğruladı.

## Özgün uygulama — Acil Durum Bilgi Kartı

Bu uygulama ad, yakın telefonu ve sağlık notundan bir bilgi kartı üretir. Sağlık ve iletişim bilgileri hassas olduğundan otomatik paylaşım yapılmaz.

### Paylaşım servisi

```dart
abstract class PaylasimServisi {
  Future<void> paylas(String metin);
}

class CihazPaylasimServisi implements PaylasimServisi {
  @override
  Future<void> paylas(String metin) async {
    await SharePlus.instance.share(
      ShareParams(
        text: metin,
        subject: 'Acil Durum Bilgi Kartı',
      ),
    );
  }
}
```

`share_plus` belirli bir mesaj uygulamasına zorla göndermez. İşletim sisteminin paylaşım sayfasını açar ve son seçimi kullanıcıya bırakır.

### Paylaşım metnini üretme

```dart
String get paylasimMetni => [
  'ACİL DURUM BİLGİ KARTI',
  'Ad: ${ad.text.trim()}',
  'Yakını: ${telefon.text.trim()}',
  'Sağlık notu: ${not.text.trim()}',
].join('\n');
```

### Eksik alanları engelleme

```dart
if ([ad, telefon, not].any((alan) => alan.text.trim().isEmpty)) {
  setState(() => durum = 'Karttaki bütün alanları doldurun');
  return;
}

await widget.servis.paylas(paylasimMetni);
```

![Acil Durum Bilgi Kartı gerçek Flutter ekranı](../../screenshots/week-31-original.png)

Test, uygulama açıldığında paylaşım yapılmadığını doğruladı. Yalnız “Kartı paylaş” düğmesine basıldıktan sonra üretilen metnin ad ve sağlık notunu içerdiğini ve başarı geri bildiriminin ekrana geldiğini denetledi.

## Bildirim ile paylaşımın farkı

| Özellik | Bildirim | Paylaşım |
|---|---|---|
| Amaç | Kullanıcıya uygulama dışından bilgi vermek | İçeriği başka uygulamaya aktarmak |
| İzin | Platform ve sürüme göre bildirim izni gerekir | Genellikle sistem menüsünü açmak için ayrı izin gerekmez |
| Son işlem | Uygulama bildirimi gösterir | Hedefi kullanıcı seçer |
| Hassas veri | Bildirim kilit ekranında görünebilir | İçerik seçilen hedefe gönderilebilir |
| Test | Sahte bildirim servisi | Sahte paylaşım servisi |

## Güvenlik ve kullanıcı deneyimi

- Bildirim başlığında hassas öğrenci bilgisi göstermeyin.
- Kullanıcının istemediği sık bildirimleri göndermeyin.
- Bildirim kanalının amacını açıkça yazın.
- Paylaşım öncesinde gönderilecek içeriği kullanıcıya gösterin.
- Sağlık, konum ve iletişim bilgilerini otomatik paylaşmayın.
- Hedef uygulamanın davranışının sizin kontrolünüzde olmadığını unutmayın.
- İzin reddedildiğinde uygulamanın temel işlevleri çalışmaya devam etmelidir.

## Sık yapılan hatalar

- Eklentiyi başlatmadan bildirim göstermeye çalışmak
- Kanal kimliğini her bildirimde değiştirmek
- İzin reddini yakalamamak
- Bildirim kimliğini yönetmeden aynı kaydı istenmeden ezmek
- Paylaşımı sayfa açılır açılmaz başlatmak
- Boş veya doğrulanmamış içeriği paylaşmak
- Gerçek eklentiyi widget testinde çağırıp testi platforma bağımlı yapmak

## Üç uygulama görevi

### Kolay — Su içme hatırlatıcısı

Kullanıcıdan bardak hedefi ve hatırlatma metni alın. Bildirim izni reddedilirse ekranda çalışan sayaç özelliğini koruyun.

### Orta — Ödev paylaşım özeti

Ders, ödev başlığı ve teslim tarihinden biçimlendirilmiş metin üretin. Paylaşım öncesinde önizleme ve eksik alan denetimi sunun.

### İleri — Bildirim merkezi

Birden fazla ders için farklı bildirim kanalları oluşturun. Bildirimi açma, kapatma ve yenileme seçenekleri ekleyin; geçmiş bildirimleri yerel veritabanında tutun. Hassas içeriği kilit ekranına yazmayın.

## Test ve kontrol

- Bildirim paketi platform ayarlarıyla başlatılıyor mu?
- Android kanal kimliği ve açıklaması anlamlı mı?
- İzin yalnız kullanıcı bildirim istediğinde soruluyor mu?
- Başlık ve gövde gerçek form verisinden oluşuyor mu?
- Boş konu bildirimi engelliyor mu?
- Paylaşım metni bütün gerekli alanları içeriyor mu?
- Paylaşım yalnız düğme işlemi sonrasında başlıyor mu?
- Hata durumunda kullanıcı anlaşılır geri bildirim alıyor mu?
- Testler gerçek platform kanalı yerine sahte servis kullanıyor mu?

## Geri bildirim ve çözüm erişimi

Öğrenci uygulamasını gönderdikten sonra **İpucunu göster**, eklentiyi başlatma–izin–işlem sırasını açıklar. **Örnek çözümü göster**, gerçek bildirim kanalı, `SharePlus`, form doğrulama ve servis soyutlama kodlarını sunar. İndirme bağlantıları iki bağımsız Flutter projesini içerir.

## Kaynak projeler

- Konu uygulaması: `08 - Cihaz Özellikleri ve Kalite/Uygulamalar/Uygulama-31-Hatırlatma`
- Özgün uygulama: `08 - Cihaz Özellikleri ve Kalite/Uygulamalar/Ozgun-31-Acil Durum Bilgi Kartı`
