Files
2026-09-27 18:31:10 +02:00

634 lines
25 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Privacy Policy | RadioPlayer</title>
<meta name="description" content="Privacy policy for the RadioPlayer native Android application.">
<meta name="theme-color" content="#111318">
<link rel="manifest" href="manifest.json?v=__BUILD_STAMP__">
<link rel="icon" type="image/png" sizes="192x192" href="assets/radioplayer-logo-192.png">
<link rel="icon" type="image/png" sizes="512x512" href="assets/radioplayer-logo-512.png">
<link rel="apple-touch-icon" href="assets/radioplayer-logo-192.png">
<style>
:root {
color-scheme: dark;
--page-bg: #111318;
--panel: rgba(16, 20, 27, 0.82);
--panel-strong: rgba(12, 15, 20, 0.94);
--border: rgba(255, 255, 255, 0.12);
--text-main: #f7f8fb;
--text-muted: rgba(247, 248, 251, 0.72);
--accent: #4dd7c8;
--accent-2: #ffb45c;
--accent-3: #8fb3ff;
--shadow: 0 28px 72px rgba(0, 0, 0, 0.35);
}
* {
box-sizing: border-box;
}
html {
min-height: 100%;
background: var(--page-bg);
font-family: Inter, "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
}
body {
margin: 0;
min-height: 100vh;
color: var(--text-main);
background:
radial-gradient(circle at 18% 8%, rgba(77, 215, 200, 0.24), transparent 34%),
radial-gradient(circle at 86% 82%, rgba(255, 180, 92, 0.2), transparent 32%),
linear-gradient(180deg, #111318 0%, #101218 58%, #111821 100%);
}
body::before {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
background-image:
linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
background-size: 42px 42px;
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.72), transparent 82%);
opacity: 0.5;
}
a {
color: inherit;
}
.page-shell {
position: relative;
z-index: 1;
width: min(960px, calc(100% - 32px));
margin: 0 auto;
padding: 28px 0 64px;
}
.topbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
margin-bottom: 20px;
}
.brand {
display: inline-flex;
align-items: center;
gap: 12px;
text-decoration: none;
}
.brand img {
width: 44px;
height: 44px;
border-radius: 14px;
box-shadow: 0 12px 28px rgba(77, 215, 200, 0.18);
}
.brand-title {
display: block;
font-size: 1.02rem;
font-weight: 800;
color: var(--text-main);
}
.brand-subtitle {
display: block;
color: var(--text-muted);
font-size: 0.82rem;
font-weight: 700;
}
.language-switch {
display: inline-flex;
gap: 4px;
padding: 4px;
border: 1px solid var(--border);
border-radius: 999px;
background: rgba(255, 255, 255, 0.06);
}
.language-button {
min-width: 48px;
min-height: 40px;
padding: 0.55rem 0.85rem;
border: 0;
border-radius: 999px;
background: transparent;
color: var(--text-main);
font-size: 0.92rem;
font-weight: 700;
cursor: pointer;
}
.language-button:hover,
.language-button:focus-visible {
background: rgba(255, 255, 255, 0.1);
}
.language-button[aria-pressed="true"] {
background: var(--accent);
color: #071412;
}
.language-button:focus-visible {
outline: 2px solid var(--accent-3);
outline-offset: 2px;
}
.language-panel[hidden] {
display: none;
}
.privacy-card {
padding: clamp(24px, 4vw, 42px);
border: 1px solid var(--border);
border-radius: 28px;
background:
linear-gradient(145deg, rgba(77, 215, 200, 0.08), transparent 42%),
linear-gradient(315deg, rgba(255, 180, 92, 0.08), transparent 36%),
linear-gradient(180deg, rgba(16, 20, 27, 0.8), rgba(255, 255, 255, 0.035));
box-shadow: var(--shadow);
backdrop-filter: blur(22px) saturate(130%);
}
.eyebrow {
margin: 0 0 10px;
color: var(--accent);
font-size: 0.78rem;
font-weight: 800;
letter-spacing: 0.08em;
text-transform: uppercase;
}
h1 {
margin: 0;
font-size: clamp(2rem, 5vw, 3.25rem);
line-height: 0.98;
}
.lead {
max-width: 64ch;
margin: 18px 0 0;
color: var(--text-muted);
font-size: 1rem;
line-height: 1.7;
}
.meta {
display: inline-flex;
margin-top: 18px;
padding: 0.45rem 0.8rem;
border-radius: 999px;
background: rgba(143, 179, 255, 0.12);
color: var(--text-main);
font-size: 0.82rem;
font-weight: 700;
}
.sections {
display: grid;
gap: 16px;
margin-top: 28px;
}
section {
padding: 18px 20px;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 20px;
background: rgba(255, 255, 255, 0.045);
}
h2 {
margin: 0 0 10px;
font-size: 1.05rem;
}
p,
li {
color: var(--text-muted);
line-height: 1.7;
}
p:last-child,
ul:last-child {
margin-bottom: 0;
}
ul {
margin: 0;
padding-left: 1.2rem;
}
strong {
color: var(--text-main);
}
.note {
margin-top: 22px;
color: var(--text-muted);
font-size: 0.9rem;
}
@media (max-width: 720px) {
.page-shell {
width: min(100% - 20px, 960px);
padding-top: 16px;
}
.topbar {
flex-direction: column;
align-items: stretch;
}
.language-switch {
align-self: flex-end;
}
.privacy-card {
border-radius: 22px;
}
section {
padding: 16px;
border-radius: 18px;
}
}
</style>
</head>
<body>
<div class="page-shell">
<div class="topbar">
<a class="brand" href="./">
<img src="assets/radioplayer-logo-192.png" alt="RadioPlayer">
<span>
<span class="brand-title">RadioPlayer</span>
<span class="brand-subtitle">Native Android radio player</span>
</span>
</a>
<div class="language-switch" role="group" aria-label="Language / Jezik">
<button class="language-button" id="language-en" type="button" aria-pressed="true" lang="en">EN</button>
<button class="language-button" id="language-sl" type="button" aria-pressed="false" lang="sl">SL</button>
</div>
</div>
<main class="privacy-card">
<div class="language-panel" id="content-en" lang="en">
<p class="eyebrow">Policy</p>
<h1>Privacy Policy</h1>
<p class="lead">
This policy explains how the native RadioPlayer application for Android (<strong>net.klevze.radio</strong>)
handles information when you listen to radio stations, use Android Auto or Google Cast, and configure app
features. RadioPlayer does not require an account and does not contain advertising or analytics SDKs.
</p>
<div class="meta">Effective date: September 3, 2026</div>
<div class="sections">
<section>
<h2>Information stored on your device</h2>
<p>
RadioPlayer stores app settings and operational data locally in Android DataStore and app-private cache
files. This lets the app restore your choices without creating an online account.
</p>
<ul>
<li>favorite and recently played station identifiers;</li>
<li>the last selected station, without automatically starting playback after a normal app restart;</li>
<li>country, category, language and sorting filters, app language and visualizer preference;</li>
<li>an optional sleep-timer deadline;</li>
<li>an optional wake-alarm schedule and the station information needed to run it;</li>
<li>a local list of up to 50 recently played track titles and artists, shown on the "Recently played" screen and cleared from Settings;</li>
<li>a cached station catalog and cached station artwork needed for reliable operation.</li>
</ul>
<p>Station search text is used only for the current session and is not kept as a search history.</p>
</section>
<section>
<h2>Network connections and radio streams</h2>
<p>
The app uses HTTPS to retrieve station-catalog updates from <strong>radio.76bit.net</strong>. When you
select a station, audio and artwork are requested directly from that station's or content provider's
server. A small fixed allowlist of HTTP audio hosts may be used only when a stream does not support HTTPS.
RadioPlayer does not disable or bypass TLS certificate validation.
</p>
<p>
Those third-party servers may receive technical information required to deliver the request, such as your
IP address, device or network information, requested URL and request time. Their own privacy policies and
retention practices apply. RadioPlayer does not control the availability or logging practices of
third-party stations.
</p>
</section>
<section>
<h2>Background playback and notifications</h2>
<p>
While audio is playing, Android may display a media notification and MediaSession controls in the
notification area, on the lock screen, on Bluetooth devices or in other compatible system surfaces. On
Android 13 and later, the app may request notification permission for these controls. Notifications are
used only for playback and alarm-related functionality, not for advertising.
</p>
</section>
<section>
<h2>Sleep timer and wake alarm</h2>
<p>
The sleep timer stores an on-device deadline. If you enable the wake alarm, RadioPlayer uses Android's
exact-alarm capability so playback can start at the time you selected. Android may ask you to grant
Alarms &amp; reminders access. After a reboot, time-zone change or relevant system event, the app only
reschedules an enabled alarm; receiving the boot event does not itself start playback. Exact timing may
still be affected by device-manufacturer battery policies.
</p>
</section>
<section>
<h2>Android Auto</h2>
<p>
When connected to Android Auto, the vehicle interface can browse the on-device station catalog,
favorites and recent stations, display station artwork, search for stations and control the same playback
session used by the phone. RadioPlayer does not create a separate car account, and connecting Android
Auto does not by itself start playback. Android Auto and Google may process technical information needed
to provide the connection and voice features under their own terms.
</p>
</section>
<section>
<h2>Google Cast</h2>
<p>
Google Cast is optional and starts only when you choose a compatible receiver. Google Cast and Android's
Media Router discover receivers on your local network. RadioPlayer sends the selected station's public
stream URL and basic metadata, such as its name and artwork URL, to the selected receiver using the
Default Media Receiver. Google and the receiver may process technical information required to establish
and operate that session. RadioPlayer does not add a separate Cast analytics account.
</p>
</section>
<section>
<h2>Audio visualizer</h2>
<p>
The optional 32-band visualizer analyzes audio samples already being decoded for playback inside the app.
The analysis is used only to draw the on-screen animation. It does not use the microphone, does not
require the <strong>RECORD_AUDIO</strong> permission, is not saved as an audio recording and is not sent
to the developer.
</p>
</section>
<section>
<h2>Album / track cover art</h2>
<p>
RadioPlayer does <strong>not</strong> contact any external album-art or music-metadata service. The
artwork shown in the player, the media notification, on the lock screen and in Android Auto is the
<strong>logo or image supplied by the radio station</strong> (or the app's own placeholder when a
station provides none). The current song's artist and title, when a station broadcasts them, are shown
as text only and are never sent anywhere for an artwork lookup.
</p>
</section>
<section>
<h2>Information not collected by the developer</h2>
<p>RadioPlayer 2.0.0 does not include developer-operated:</p>
<ul>
<li>user accounts or cloud synchronization of favorites and settings;</li>
<li>advertising or user-profiling SDKs;</li>
<li>analytics SDKs;</li>
<li>sale of personal information;</li>
<li>access to your location, microphone, contacts, photos or files;</li>
<li>upload of your listening or track history to the developer &mdash; the bounded list of recently played tracks is kept only on your device.</li>
</ul>
<p>
This statement does not cover technical data processed independently by Android, Google Play, Android
Auto, Google Cast, radio stations, stream hosts or artwork providers under their own policies.
</p>
</section>
<section>
<h2>Deleting your data</h2>
<p>
RadioPlayer has no online account to delete. You can remove locally stored favorites, recent stations,
preferences, timers, alarms and cached data by opening Android Settings, selecting Apps, RadioPlayer,
Storage, and clearing the app's storage. Uninstalling the app also removes its local app data, subject to
Android or Google backup and restore settings controlled by you. You can revoke notification, alarm and
other granted app access at any time in Android Settings.
</p>
</section>
<section>
<h2>Android TV</h2>
<p>
RadioPlayer 2.0.0 does not provide a separately installable native Android TV application. You may cast
from the phone app to a compatible Google TV or Cast receiver.
</p>
</section>
<section>
<h2>Changes and contact</h2>
<p>
This policy may be updated when RadioPlayer's behavior, dependencies or external services change. The
effective date above identifies the current version. For privacy questions, use the developer contact
information published with RadioPlayer on its Google Play listing.
</p>
</section>
</div>
</div>
<div class="language-panel" id="content-sl" lang="sl" hidden>
<p class="eyebrow">Pravilnik</p>
<h1>Pravilnik o zasebnosti</h1>
<p class="lead">
Ta pravilnik pojasnjuje, kako nativna aplikacija RadioPlayer za Android
(<strong>net.klevze.radio</strong>) ravna s podatki med poslušanjem radijskih postaj, uporabo Android Auto ali
Google Cast ter nastavljanjem funkcij. RadioPlayer ne zahteva uporabniškega računa ter ne vsebuje oglaševalskih
ali analitičnih SDK-jev.
</p>
<div class="meta">Datum začetka veljavnosti: 3. september 2026</div>
<div class="sections">
<section>
<h2>Podatki, shranjeni v napravi</h2>
<p>
RadioPlayer lokalno uporablja Android DataStore in zasebni predpomnilnik aplikacije. Tako lahko obnovi
vaše izbire, ne da bi ustvaril spletni uporabniški račun.
</p>
<ul>
<li>identifikatorje priljubljenih in nedavno predvajanih postaj;</li>
<li>nazadnje izbrano postajo, brez samodejnega predvajanja po običajnem ponovnem zagonu aplikacije;</li>
<li>filtre države, kategorije, jezika in razvrščanja, jezik aplikacije ter nastavitev vizualizatorja;</li>
<li>morebitni rok časovnika spanja;</li>
<li>morebitni urnik budilnega alarma in podatke postaje, potrebne za njegovo izvedbo;</li>
<li>lokalni seznam do 50 nedavno predvajanih skladb (izvajalec in naslov), prikazan na zaslonu »Nedavno predvajano« in izbrisljiv v nastavitvah;</li>
<li>predpomnjeni katalog postaj in predpomnjene logotipe postaj za zanesljivo delovanje.</li>
</ul>
<p>Besedilo iskanja postaj se uporablja le v trenutni seji in se ne hrani kot zgodovina iskanja.</p>
</section>
<section>
<h2>Omrežne povezave in radijski pretoki</h2>
<p>
Aplikacija prek HTTPS pridobiva posodobitve kataloga z <strong>radio.76bit.net</strong>. Ob izbiri postaje
pridobiva zvok in slike neposredno s strežnika postaje oziroma ponudnika vsebine. Majhen nespremenljiv
seznam HTTP gostiteljev je dovoljen le za zvočne pretoke, ki ne podpirajo HTTPS. RadioPlayer ne izklaplja
in ne zaobide preverjanja potrdil TLS.
</p>
<p>
Zunanji strežniki lahko prejmejo tehnične podatke, potrebne za izvedbo zahteve, na primer naslov IP,
podatke o napravi ali omrežju, zahtevani URL in čas zahteve. Zanje veljajo njihovi pravilniki o zasebnosti
in roki hrambe. RadioPlayer ne nadzira razpoložljivosti ali beleženja pri zunanjih postajah.
</p>
</section>
<section>
<h2>Predvajanje v ozadju in obvestila</h2>
<p>
Med predvajanjem lahko Android prikaže medijsko obvestilo in kontrole MediaSession v obvestilih, na
zaklenjenem zaslonu, napravah Bluetooth ali drugih združljivih sistemskih površinah. Na Androidu 13 in
novejšem lahko aplikacija zahteva dovoljenje za obvestila. Obvestila se uporabljajo le za predvajanje in
funkcije alarma, ne za oglaševanje.
</p>
</section>
<section>
<h2>Časovnik spanja in budilni alarm</h2>
<p>
Časovnik spanja lokalno shrani rok. Če omogočite budilni alarm, RadioPlayer uporabi zmožnost točnega alarma
Androida, da se predvajanje lahko začne ob izbranem času. Android lahko zahteva dostop do Alarmov in
opomnikov. Po ponovnem zagonu naprave, spremembi časovnega pasu ali ustreznem sistemskem dogodku aplikacija
omogočeni alarm samo ponovno razporedi; sam prejem dogodka ob zagonu ne začne predvajanja. Na točnost lahko
vplivajo pravila proizvajalca naprave glede varčevanja z baterijo.
</p>
</section>
<section>
<h2>Android Auto</h2>
<p>
Ob povezavi z Android Auto lahko vmesnik vozila brska po lokalnem katalogu, priljubljenih in nedavnih
postajah, prikazuje logotipe, išče postaje ter upravlja isto sejo predvajanja kot telefon. RadioPlayer ne
ustvari ločenega avtomobilskega računa in povezava sama ne začne predvajanja. Android Auto in Google lahko
po svojih pravilih obdelata tehnične podatke, potrebne za povezavo in glasovne funkcije.
</p>
</section>
<section>
<h2>Google Cast</h2>
<p>
Google Cast je neobvezen in se začne le, ko izberete združljiv sprejemnik. Google Cast in Android Media
Router odkrivata sprejemnike v lokalnem omrežju. RadioPlayer izbranemu sprejemniku prek privzetega
medijskega sprejemnika pošlje javni URL pretoka ter osnovne metapodatke, kot sta ime postaje in URL slike.
Google in sprejemnik lahko obdelata tehnične podatke, potrebne za vzpostavitev in izvajanje seje.
RadioPlayer ne dodaja ločenega analitičnega računa Cast.
</p>
</section>
<section>
<h2>Zvočni vizualizator</h2>
<p>
Neobvezni 32-pasovni vizualizator analizira zvočne vzorce, ki se znotraj aplikacije že dekodirajo za
predvajanje. Analiza se uporablja le za risanje animacije na zaslonu. Ne uporablja mikrofona, ne zahteva
dovoljenja <strong>RECORD_AUDIO</strong>, se ne shranjuje kot zvočni posnetek in se ne pošilja razvijalcu.
</p>
</section>
<section>
<h2>Naslovnice albumov / skladb</h2>
<p>
RadioPlayer se <strong>ne</strong> povezuje z nobeno zunanjo storitvijo za naslovnice ali glasbene
metapodatke. Naslovnica, prikazana v predvajalniku, medijskem obvestilu, na zaklenjenem zaslonu in v
Android Auto, je <strong>logotip oziroma slika, ki jo posreduje radijska postaja</strong> (ali lastni
nadomestni znak aplikacije, kadar je postaja ne ponudi). Izvajalec in naslov trenutne skladbe, kadar
ju postaja oddaja, sta prikazana le kot besedilo in nista nikamor poslana za iskanje naslovnice.
</p>
</section>
<section>
<h2>Česa razvijalec ne zbira</h2>
<p>RadioPlayer 2.0.0 ne vključuje:</p>
<ul>
<li>uporabniških računov ali sinhronizacije priljubljenih in nastavitev v oblaku;</li>
<li>oglaševalskih SDK-jev ali profiliranja uporabnikov;</li>
<li>analitičnih SDK-jev;</li>
<li>prodaje osebnih podatkov;</li>
<li>dostopa do lokacije, mikrofona, stikov, fotografij ali datotek;</li>
<li>pošiljanja zgodovine poslušanja ali skladb razvijalcu &mdash; omejen seznam nedavno predvajanih skladb se hrani samo v napravi.</li>
</ul>
<p>
Ta navedba ne zajema tehničnih podatkov, ki jih Android, Google Play, Android Auto, Google Cast, radijske
postaje, gostitelji pretokov ali ponudniki slik samostojno obdelujejo po svojih pravilnikih.
</p>
</section>
<section>
<h2>Brisanje podatkov</h2>
<p>
RadioPlayer nima spletnega računa, ki bi ga bilo treba izbrisati. Lokalno shranjene priljubljene, nedavne
postaje, nastavitve, časovnike, alarme in predpomnilnik odstranite v nastavitvah Androida: Aplikacije,
RadioPlayer, Shramba, nato izbrišite podatke aplikacije. Odstranitev aplikacije prav tako izbriše njene
lokalne podatke, ob upoštevanju nastavitev Android oziroma Google varnostnega kopiranja in obnovitve, ki
jih upravljate sami. Dovoljenja za obvestila, alarme in druge dostope lahko kadar koli prekličete v
nastavitvah Androida.
</p>
</section>
<section>
<h2>Android TV</h2>
<p>
RadioPlayer 2.0.0 nima ločene nativne aplikacije za namestitev na Android TV. Iz telefonske aplikacije
lahko predvajate na združljiv sprejemnik Google TV ali Cast.
</p>
</section>
<section>
<h2>Spremembe in stik</h2>
<p>
Ta pravilnik se lahko posodobi, če se spremenijo delovanje, odvisnosti ali zunanje storitve RadioPlayerja.
Datum začetka veljavnosti zgoraj označuje trenutno različico. Za vprašanja o zasebnosti uporabite kontaktne
podatke razvijalca, objavljene ob aplikaciji RadioPlayer v trgovini Google Play.
</p>
</section>
</div>
</div>
</main>
</div>
<script>
(() => {
const panels = {
en: document.getElementById("content-en"),
sl: document.getElementById("content-sl")
};
const buttons = {
en: document.getElementById("language-en"),
sl: document.getElementById("language-sl")
};
function setLanguage(language) {
const selected = language === "sl" ? "sl" : "en";
Object.keys(panels).forEach((key) => {
panels[key].hidden = key !== selected;
buttons[key].setAttribute("aria-pressed", String(key === selected));
});
document.documentElement.lang = selected;
document.title = selected === "sl"
? "Pravilnik o zasebnosti | RadioPlayer"
: "Privacy Policy | RadioPlayer";
}
buttons.en.addEventListener("click", () => setLanguage("en"));
buttons.sl.addEventListener("click", () => setLanguage("sl"));
const browserLanguage = (navigator.languages && navigator.languages[0]) || navigator.language || "en";
setLanguage(browserLanguage.toLowerCase().startsWith("sl") ? "sl" : "en");
})();
</script>
</body>
</html>