JavaScript köprü API'si
Medya ve yayınlama
Sayfanızın yönettiği kilit ekranı medya bildirimi ve bir videoyu televizyona aktarma.
requestPictureInPicture web standardı#
video.requestPictureInPicture() — Picture-in-Picture
Örnek
Standart Resim içinde Resim API'si: kullanıcı başka bir şey yaparken bir videoyu küçük bir pencerede yüzdürün. Android'deki Chrome'da vardır, Android'in WebView'ında yoktur; uygulamada video, Chrome'daki gibi yüzen pencereyi doldurur.
Döndürür: bir PictureInPictureWindow için Promise (width, height, resize olayı). Video önce enterpictureinpicture, kullanıcı pencereyi kapatınca veya genişletince leavepictureinpicture alır; bu arada document.pictureInPictureElement videodur. Dokunma olmadan NotAllowedError, videonun meta verileri yüklenmeden önce veya disablePictureInPicture olduğunda InvalidStateError ile reddedilir. Gerekenler: derlemede Resim içinde resim açık (kodunuz requestPictureInPicture çağırınca kendiliğinden açılır), Android 8 veya daha yeni.
<video id="v" src="clip.mp4" controls playsinline></video>
<button id="pip">Pop out</button>
<script>
const v = document.getElementById('v');
const btn = document.getElementById('pip');
btn.hidden = !document.pictureInPictureEnabled;
btn.addEventListener('click', async () => {
try {
if (document.pictureInPictureElement) await document.exitPictureInPicture();
else await v.requestPictureInPicture();
} catch (e) {
console.warn('Picture-in-Picture:', e.name);
}
});
v.addEventListener('enterpictureinpicture', () => { btn.textContent = 'Back to app'; });
v.addEventListener('leavepictureinpicture', () => { btn.textContent = 'Pop out'; });
</script>Kullanıcı ayrıldığında otomatik olarak açılın ve desteklenmeyen bir derlemeyi bildirin:
const v = document.getElementById('v');
if (!document.pictureInPictureEnabled || v.disablePictureInPicture) {
document.getElementById('pip').hidden = true; // this build has no picture-in-picture
}
document.addEventListener('visibilitychange', async () => {
if (document.hidden && !v.paused && !document.pictureInPictureElement) {
try { await v.requestPictureInPicture(); }
catch (e) { console.warn(e.name); } // NotAllowedError without a tap
}
});Meta verileri bekleyin ve pencereyle birlikte yeniden boyutlandırın:
async function popOut(video) {
if (video.readyState < 1) await new Promise((r) => video.addEventListener('loadedmetadata', r, { once: true }));
try {
const pipWin = await video.requestPictureInPicture();
pipWin.addEventListener('resize', () => console.log(pipWin.width, pipWin.height));
} catch (e) {
if (e.name === 'InvalidStateError') showMessage('This video cannot float.');
else if (e.name === 'NotAllowedError') showMessage('Tap the button to pop out.');
}
}
document.getElementById('pip').onclick = () => popOut(document.getElementById('v'));Notlar: Android tüm uygulamayı kayan pencereye koyar; bu yüzden video önce tek başına (tam ekran) gösterilir ve pencere videonun şeklini alır; pencereden çıkınca video sayfaya geri döner. document.exitPictureInPicture() uygulamayı tam ekrana geri getirir. Derlemede pencere içinde pencere (PiP) yoksa document.pictureInPictureEnabled değeri, bu özelliği olmayan bir tarayıcıdaki gibi false olur. Mod değişikliği sayfaya appmint:pip olarak ulaşır. Dahili aktarım yolları: __pipEnter, __pipExit, __pipAvailable, __pipPrepare.
__pipAvailable köprü#
window.WebToApk.__pipAvailable(): Boolean
video.requestPictureInPicture() çalışabilir mi: derlemede PiP açık, Android 8+.
Örnek
WebToApk.__pipEnter ile birlikte belgelenmiştir - oradaki örnek bunu da gösterir.
video.requestPictureInPicture() ve document.exitPictureInPicture() arkasındaki dahili aktarım. Sayfalar standart API'yi kullanır; bunları asla doğrudan çağırmayın, çünkü __ yöntemleri haber verilmeden değişebilir.
Döndürür: __pipEnter(width, height), Android pencereyi kabul ettiğinde (videonun en-boy oranıyla) "ok", aksi halde "unsupported" / "failed" döndürür. Pencerenin açılıp kapanması {inPip} ile appmint:pip olarak gelir. __pipAvailable(), derlemede Android 8+ üzerinde resim içinde resim açıksa doğrudur. Gerekenler: derlemede Resim içinde resim açık.
Genel API'yi kullanın:
const video = document.querySelector('video');
button.addEventListener('click', () => video.requestPictureInPicture());Önce desteği denetleyin ve reddi bildirin:
async function floatVideo(video) {
if (!document.pictureInPictureEnabled) { showMessage('Picture-in-picture is not on in this app.'); return; }
try {
await video.requestPictureInPicture();
} catch (err) {
showMessage('Could not open the floating window.');
}
}Tekrar çıkın ve durumu standart olaylarla izleyin:
video.addEventListener('enterpictureinpicture', () => hideControls());
video.addEventListener('leavepictureinpicture', () => showControls());
closeBtn.onclick = () => { if (document.pictureInPictureElement) document.exitPictureInPicture(); };Notlar: Uygulama kabuğunda (PictureInPictureShim.kt) uygulanır. __pipPrepare, kabuğun pencereye geçerken tam ekran adımı için ekranı yana çevirmesini engeller.
__pipEnter köprü#
window.WebToApk.__pipEnter(width: Int, height: Int): String
PiP penceresini [width]×[height] boyutlu bir videonun en boy oranıyla açar: "ok" veya "unsupported" / "failed". Mod değişikliği şu olarak gelir: `appmint:pip`.
Örnek
video.requestPictureInPicture() ve document.exitPictureInPicture() arkasındaki dahili aktarım. Sayfalar standart API'yi kullanır; bunları asla doğrudan çağırmayın, çünkü __ yöntemleri haber verilmeden değişebilir.
Döndürür: __pipEnter(width, height), Android pencereyi kabul ettiğinde (videonun en-boy oranıyla) "ok", aksi halde "unsupported" / "failed" döndürür. Pencerenin açılıp kapanması {inPip} ile appmint:pip olarak gelir. __pipAvailable(), derlemede Android 8+ üzerinde resim içinde resim açıksa doğrudur. Gerekenler: derlemede Resim içinde resim açık.
Genel API'yi kullanın:
const video = document.querySelector('video');
button.addEventListener('click', () => video.requestPictureInPicture());Önce desteği denetleyin ve reddi bildirin:
async function floatVideo(video) {
if (!document.pictureInPictureEnabled) { showMessage('Picture-in-picture is not on in this app.'); return; }
try {
await video.requestPictureInPicture();
} catch (err) {
showMessage('Could not open the floating window.');
}
}Tekrar çıkın ve durumu standart olaylarla izleyin:
video.addEventListener('enterpictureinpicture', () => hideControls());
video.addEventListener('leavepictureinpicture', () => showControls());
closeBtn.onclick = () => { if (document.pictureInPictureElement) document.exitPictureInPicture(); };Notlar: Uygulama kabuğunda (PictureInPictureShim.kt) uygulanır. __pipPrepare, kabuğun pencereye geçerken tam ekran adımı için ekranı yana çevirmesini engeller.
__pipExit köprü#
window.WebToApk.__pipExit()
document.exitPictureInPicture(): uygulamayı tam ekrana geri getirir.
Örnek
WebToApk.__pipEnter ile birlikte belgelenmiştir - oradaki örnek bunu da gösterir.
video.requestPictureInPicture() ve document.exitPictureInPicture() arkasındaki dahili aktarım. Sayfalar standart API'yi kullanır; bunları asla doğrudan çağırmayın, çünkü __ yöntemleri haber verilmeden değişebilir.
Döndürür: __pipEnter(width, height), Android pencereyi kabul ettiğinde (videonun en-boy oranıyla) "ok", aksi halde "unsupported" / "failed" döndürür. Pencerenin açılıp kapanması {inPip} ile appmint:pip olarak gelir. __pipAvailable(), derlemede Android 8+ üzerinde resim içinde resim açıksa doğrudur. Gerekenler: derlemede Resim içinde resim açık.
Genel API'yi kullanın:
const video = document.querySelector('video');
button.addEventListener('click', () => video.requestPictureInPicture());Önce desteği denetleyin ve reddi bildirin:
async function floatVideo(video) {
if (!document.pictureInPictureEnabled) { showMessage('Picture-in-picture is not on in this app.'); return; }
try {
await video.requestPictureInPicture();
} catch (err) {
showMessage('Could not open the floating window.');
}
}Tekrar çıkın ve durumu standart olaylarla izleyin:
video.addEventListener('enterpictureinpicture', () => hideControls());
video.addEventListener('leavepictureinpicture', () => showControls());
closeBtn.onclick = () => { if (document.pictureInPictureElement) document.exitPictureInPicture(); };Notlar: Uygulama kabuğunda (PictureInPictureShim.kt) uygulanır. __pipPrepare, kabuğun pencereye geçerken tam ekran adımı için ekranı yana çevirmesini engeller.
__pipPrepare köprü#
window.WebToApk.__pipPrepare()
Sayfa, PiP için bir videoyu tam ekrana almak üzere: bunun için yatay yönü zorlamayın.
Örnek
WebToApk.__pipEnter ile birlikte belgelenmiştir - oradaki örnek bunu da gösterir.
video.requestPictureInPicture() ve document.exitPictureInPicture() arkasındaki dahili aktarım. Sayfalar standart API'yi kullanır; bunları asla doğrudan çağırmayın, çünkü __ yöntemleri haber verilmeden değişebilir.
Döndürür: __pipEnter(width, height), Android pencereyi kabul ettiğinde (videonun en-boy oranıyla) "ok", aksi halde "unsupported" / "failed" döndürür. Pencerenin açılıp kapanması {inPip} ile appmint:pip olarak gelir. __pipAvailable(), derlemede Android 8+ üzerinde resim içinde resim açıksa doğrudur. Gerekenler: derlemede Resim içinde resim açık.
Genel API'yi kullanın:
const video = document.querySelector('video');
button.addEventListener('click', () => video.requestPictureInPicture());Önce desteği denetleyin ve reddi bildirin:
async function floatVideo(video) {
if (!document.pictureInPictureEnabled) { showMessage('Picture-in-picture is not on in this app.'); return; }
try {
await video.requestPictureInPicture();
} catch (err) {
showMessage('Could not open the floating window.');
}
}Tekrar çıkın ve durumu standart olaylarla izleyin:
video.addEventListener('enterpictureinpicture', () => hideControls());
video.addEventListener('leavepictureinpicture', () => showControls());
closeBtn.onclick = () => { if (document.pictureInPictureElement) document.exitPictureInPicture(); };Notlar: Uygulama kabuğunda (PictureInPictureShim.kt) uygulanır. __pipPrepare, kabuğun pencereye geçerken tam ekran adımı için ekranı yana çevirmesini engeller.
castMedia köprü#
window.WebToApk.castMedia(mediaUrl: String)
[mediaUrl] adresini, bu telefonda onu başka bir ekranda oynatabilen her şeye - Chromecast, bir Akıllı TV uygulaması, yerel bir oynatıcı - sistem seçicisi üzerinden sunar. Tür URL'den alınır ([CastMediaType]): bir ses dosyası (.mp3, .m4a, .aac, .ogg, .opus, .wav, .flac …) veya bir ses `data:` URL'si ses uygulamalarına, diğer her şey - video dosyaları, akış bildirimleri, uzantısız URL'ler - video uygulamalarına sunulur. Bu bir devir işlemidir, yayın oturumu değil: uygulama oynatmanın denetimini elinde tutmaz ve geri çağrı yoktur. Gerçek oturuma ihtiyaç duyan bir sayfa bunun yerine JavaScript'te Cast SDK'sını kullanmalıdır.
Örnek
Bir video veya ses adresini, telefondaki onu başka bir ekranda oynatabilen uygulamalara (bir Chromecast uygulaması, bir Akıllı TV uygulaması, bir video oynatıcı) Android "Yayınla..." seçicisi üzerinden sunar.
Döndürür: hiçbir şey ve geri çağırma yok. Gerekenler: açılacak bir şey yok. Telefonda bağlantıyı kabul eden bir uygulama olmalı.
function castToTv(url) {
if (window.WebToApk && typeof window.WebToApk.castMedia === 'function') {
window.WebToApk.castMedia(url); // opens the "Cast to..." chooser
} else {
alert('Casting is only available in the app');
}
}
document.getElementById('cast-btn').addEventListener('click', function () {
var video = document.querySelector('video');
var url = video && video.currentSrc ? video.currentSrc : 'https://example.com/movie.mp4';
castToTv(url);
});Listeden bir podcast bölümünü bir hoparlör veya TV uygulamasına gönderin (bir .mp3 bağlantısı ses uygulamalarına sunulur):
// <li><button class="cast" data-src="https://example.com/ep12.mp3">Cast</button> Episode 12</li>
document.getElementById('episodes').addEventListener('click', function (e) {
var btn = e.target.closest('button.cast');
if (!btn) return;
var src = btn.getAttribute('data-src') || '';
if (src.indexOf('https://') !== 0) {
alert('This episode cannot be cast'); // files inside the app cannot be handed over
return;
}
if (window.WebToApk && typeof window.WebToApk.castMedia === 'function') {
window.WebToApk.castMedia(src);
}
});Yayın düğmesini yalnızca uygulamanın içinde gösterin ve canlı yayını devretmeden önce sayfanın kendi oynatıcısını duraklatın:
var castBtn = document.getElementById('cast-live');
var canCast = !!(window.WebToApk && typeof window.WebToApk.castMedia === 'function');
castBtn.hidden = !canCast;
castBtn.addEventListener('click', function () {
var video = document.getElementById('live');
video.pause(); // avoid playing twice, here and on the TV
window.WebToApk.castMedia('https://example.com/live/stream.m3u8'); // offered to video apps
});Notlar:
- Bu bir devretmedir, yayın oturumu değildir: kullanıcı bir uygulama seçtikten sonra sayfanız oynatmayı denetlemez.
- Adres, diğer uygulamaların açabileceği tam bir
https://bağlantısı olmalıdır. Uygulama ZIP'inizdeki bir dosya, birblob:URL'si veya bir web sayfası adresi oynatılmaz. - Tür bağlantıdan gelir: bir ses dosyası (
.mp3,.m4a,.aac,.ogg,.opus,.wav,.flac…) veya biraudio/data:URL'si ses uygulamalarına sunulur; diğer her şey - video dosyaları,.m3u8akışları, dosya uzantısı olmayan bağlantılar - video uygulamalarına.
clearMediaNotification köprü#
window.WebToApk.clearMediaNotification()
Web içeriğinin Android medya tarzı bildirimini yönetmesini ve kilit ekranından ile bildirim panelinden aktarım denetimi geri çağırmalarını (oynat/duraklat/sonraki/önceki) almasını sağlar. JavaScript'ten kullanım: window.WebToApk.setMediaMetadata('Song Title', 'Artist Name', 'https://…/art.jpg') window.WebToApk.setPlaybackState(true, 30000, 240000) // oynuyor, konum ms, süre ms window.WebToApk.clearMediaNotification() Android → JS geri çağırması: window.WebToApkOnMediaAction('play'|'pause'|'next'|'prev'|'stop')
Tek başına değil, grubu olan Medya Bildirim Köprüsü altında açıklanır.
Örnek
Medya bildirimini ve kilit ekranı denetimlerini kaldırır; örneğin kullanıcı oynatıcınızı kapattığında.
Döndürür: hiçbir şey. Gerekenler: derleme sırasında 4. Adım'da (Erişim) Medya Bildirimi seçeneğini açın. Açık değilse çağrı hiçbir şey yapmaz.
Bunun için standart bir web çağrısı yoktur, bu yüzden köprüyü kullanın:
function closePlayer() {
var audio = document.getElementById('player');
audio.pause();
audio.currentTime = 0;
if (window.WebToApk && typeof window.WebToApk.clearMediaNotification === 'function') {
window.WebToApk.clearMediaNotification();
}
}
document.getElementById('close-player').addEventListener('click', closePlayer);
// The notification's own Stop button already removes it; just stop your audio:
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('stop', function () {
var audio = document.getElementById('player');
audio.pause();
audio.currentTime = 0;
});
}Seçilen dakika sayısı sonunda sesi durduran ve bildirimi kaldıran bir uyku zamanlayıcısı:
var sleepTimer = null;
function setSleepTimer(minutes) {
clearTimeout(sleepTimer);
sleepTimer = setTimeout(function () {
var audio = document.getElementById('player');
audio.pause();
if (window.WebToApk && typeof window.WebToApk.clearMediaNotification === 'function') {
window.WebToApk.clearMediaNotification();
}
}, minutes * 60 * 1000);
}
document.getElementById('sleep-30').addEventListener('click', function () { setSleepTimer(30); });Bir oynatma listesinin son parçası bittiğinde, boşuna bir Oynat düğmesi bırakmak yerine bildirimi kaldırın:
var audio = document.getElementById('player');
var playlist = ['https://example.com/1.mp3', 'https://example.com/2.mp3'];
var current = 0;
audio.addEventListener('ended', function () {
current++;
if (current < playlist.length) {
audio.src = playlist[current];
audio.play();
} else if (window.WebToApk && typeof window.WebToApk.clearMediaNotification === 'function') {
window.WebToApk.clearMediaNotification();
}
});Notlar: Bunu "duraklat" için değil, "durdur" için kullanın (duraklatmak için setPlaybackState(false, ...) gönderin; böylece Oynat düğmesi kalır). navigator.mediaSession.metadata = null ayarı bildirimi kaldırmaz. Sonraki setMediaMetadata / setPlaybackState (veya yeni navigator.mediaSession meta verisi / durumu) bildirimi ve kilit ekranı denetimlerini geri getirir.
setMediaMetadata köprü#
window.WebToApk.setMediaMetadata(title: String, artist: String, artworkUrl: String)
Web içeriğinin Android medya tarzı bildirimini yönetmesini ve kilit ekranından ile bildirim panelinden aktarım denetimi geri çağırmalarını (oynat/duraklat/sonraki/önceki) almasını sağlar. JavaScript'ten kullanım: window.WebToApk.setMediaMetadata('Song Title', 'Artist Name', 'https://…/art.jpg') window.WebToApk.setPlaybackState(true, 30000, 240000) // oynuyor, konum ms, süre ms window.WebToApk.clearMediaNotification() Android → JS geri çağırması: window.WebToApkOnMediaAction('play'|'pause'|'next'|'prev'|'stop')
Tek başına değil, grubu olan Medya Bildirim Köprüsü altında açıklanır.
Örnek
Medya bildiriminin ve kilit ekranı oynatıcısının başlığını, sanatçısını ve kapak resmini ayarlar. Sayfalar normalde bunu sizin için çağıran navigator.mediaSession.metadata özelliğini ayarlar.
Döndürür: hiçbir şey. Gerekenler: derleme sırasında 4. Adım'da (Erişim) Medya Bildirimi seçeneğini açın. Açık değilse çağrı hiçbir şey yapmaz.
Herkese açık yol (bunu kullanın):
if ('mediaSession' in navigator && window.MediaMetadata) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'Episode 12', artist: 'My Podcast',
artwork: [{ src: 'https://example.com/cover.jpg', sizes: '512x512' }]
});
}Ham çağrı. Argümanlar: title, artist, artworkUrl (resim yoksa '' kullanın):
function showNowPlaying(track) {
if (!(window.WebToApk && typeof window.WebToApk.setMediaMetadata === 'function')) return;
window.WebToApk.setMediaMetadata(track.title, track.artist || '', track.cover || '');
window.WebToApk.setPlaybackState(true, 0, Math.round(track.seconds * 1000));
}
// Buttons in the notification come back through the standard API:
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('nexttrack', function () { playNext(); });
navigator.mediaSession.setActionHandler('previoustrack', function () { playPrevious(); });
}Şarkının yeni bir dosya yüklemeden değiştiği canlı bir radyo yayını için bildirimin başlığını güncel tutun:
var lastSong = '';
function refreshNowPlaying() {
fetch('https://example.com/radio/now-playing.json')
.then(function (r) { return r.json(); })
.then(function (np) { // e.g. { "title": "...", "artist": "...", "cover": "https://..." }
var key = np.title + '|' + np.artist;
if (key === lastSong) return; // only update when the song really changed
lastSong = key;
if (window.WebToApk && typeof window.WebToApk.setMediaMetadata === 'function') {
window.WebToApk.setMediaMetadata(np.title || 'Live radio', np.artist || '', np.cover || '');
}
})
.catch(function () { /* try again on the next tick */ });
}
document.getElementById('radio').addEventListener('play', function () {
refreshNowPlaying();
setInterval(refreshNowPlaying, 30000);
}, { once: true });Notlar:
- Bildirim bu çağrıyla görünür (veya güncellenir). Boş bir başlık uygulama adını gösterir.
artworkUrlinternet üzerindeki tam birhttps://adresi olmalıdır. Uygulama onu indirir (4 saniye sınırı); başarısız olursa uygulama simgesi gösterilir.- Düğme basışlarını
navigator.mediaSession.setActionHandlerile (bkz.navigator.mediaSession) veya kendiwindow.WebToApkOnMediaAction = function (action) { ... }işlevinizle (play,pause,next,prev,stop) alın - ikisinden birini kullanın.clearMediaNotification()sonrasında, buna (veyasetPlaybackState) yapılan bir sonraki çağrı bildirimi ve kilit ekranı denetimlerini geri getirir.
setPlaybackState köprü#
window.WebToApk.setPlaybackState(isPlaying: Boolean, positionMs: Long, durationMs: Long)
Web içeriğinin Android medya tarzı bildirimini yönetmesini ve kilit ekranından ile bildirim panelinden aktarım denetimi geri çağırmalarını (oynat/duraklat/sonraki/önceki) almasını sağlar. JavaScript'ten kullanım: window.WebToApk.setMediaMetadata('Song Title', 'Artist Name', 'https://…/art.jpg') window.WebToApk.setPlaybackState(true, 30000, 240000) // oynuyor, konum ms, süre ms window.WebToApk.clearMediaNotification() Android → JS geri çağırması: window.WebToApkOnMediaAction('play'|'pause'|'next'|'prev'|'stop')
Tek başına değil, grubu olan Medya Bildirim Köprüsü altında açıklanır.
Örnek
Medya bildirimine oynatıp oynatmadığınızı veya duraklatıp duraklatmadığınızı ve parçada nerede olduğunuzu söyler. Sayfalar normalde bunu sizin için çağıran navigator.mediaSession.playbackState ayarlar ve setPositionState çağırır.
Döndürür: hiçbir şey. Gerekenler: derleme sırasında 4. Adım'da (Erişim) Medya Bildirimi seçeneğini açın. Açık değilse çağrı hiçbir şey yapmaz.
Herkese açık yol (bunu kullanın):
var audio = document.getElementById('player');
function publish() {
if (!('mediaSession' in navigator)) return;
navigator.mediaSession.playbackState = audio.paused ? 'paused' : 'playing';
if (audio.duration > 0 && navigator.mediaSession.setPositionState) {
navigator.mediaSession.setPositionState({ duration: audio.duration, position: audio.currentTime });
}
}
audio.addEventListener('play', publish);
audio.addEventListener('pause', publish);Ham çağrı. Argümanlar: isPlaying (true/false), positionMs, durationMs (tam milisaniye):
function publishRaw(audio) {
if (!(window.WebToApk && typeof window.WebToApk.setPlaybackState === 'function')) return;
window.WebToApk.setPlaybackState(
!audio.paused,
Math.floor(audio.currentTime * 1000),
Math.floor((audio.duration || 0) * 1000)
);
}Kullanıcı atladıktan sonra yeni konumu bildirin ve parça bittiğinde bildirimi Oynat'a geçirin:
var audio = document.getElementById('player');
function report(playing) {
if (!(window.WebToApk && typeof window.WebToApk.setPlaybackState === 'function')) return;
var durMs = Math.floor((audio.duration || 0) * 1000);
var posMs = Math.floor(audio.currentTime * 1000);
window.WebToApk.setPlaybackState(playing, Math.min(posMs, durMs || posMs), durMs);
}
audio.addEventListener('seeked', function () { report(!audio.paused); });
audio.addEventListener('ended', function () { report(false); }); // Play button, notification can be swiped awayNotlar: true Duraklat düğmesini gösterir ve bildirimin kaydırılıp kapatılmasını engeller; false Oynat düğmesini gösterir. Bildirimin bir başlığı olması için önce setMediaMetadata çağırın. Kullanıcı durdurduğunda bildirimi kaldırmak için şunu çağırın: clearMediaNotification().