/** DR Radio 2 is developed by Jacob Nordfalk, Hanafi Mughrabi and Frederik Aagaard. Some parts of the code are loosely based on Sveriges Radio Play for Android. DR Radio 2 for Android is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. DR Radio 2 for Android is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DR Radio 2 for Android. If not, see <http://www.gnu.org/licenses/>. */ package dk.dr.radio.data; import android.content.Intent; import android.os.Handler; import dk.dr.radio.afspilning.Afspiller; import dk.dr.radio.data.spiller_nu.SpillerNu; import dk.dr.radio.data.stamdata.Kanal; import dk.dr.radio.data.stamdata.Stamdata; import dk.dr.radio.data.udsendelser.Udsendelser; import dk.dr.radio.diverse.App; import dk.dr.radio.diverse.Log; import dk.dr.radio.diverse.Rapportering; /** * Det centrale objekt som alt andet bruger til */ public class DRData { public static DRData instans; public static final String STAMDATA_URL = "http://javabog.dk/privat/stamdata_android29.json"; //public static final String STAMDATA_URL = "http://www.dr.dk/tjenester/iphone/radio/settings/android29.drxml"; public static boolean udvikling; public Afspiller afspiller; private Handler handler = new Handler(); public Stamdata stamdata; public String aktuelKanalkode; public Kanal aktuelKanal; public Udsendelser udsendelser; private Udsendelser udsendelser2; public boolean udsendelser_ikkeTilgængeligt; public SpillerNu spillerNuListe; private SpillerNu spillerNuListe2; public static final String NØGLE_lydformat = "lydformat"; public static final String NØGLE_kanal = "kanal"; public final Rapportering rapportering = new Rapportering(); /** * Bruges til at sende broadcasts om nye stamdata */ public static final String OPDATERINGSINTENT_Stamdata = "dk.dr.radio.afspiller.OPDATERING_Stamdata"; /** * Bruges til at sende broadcasts om ny info om udsendelsen (programinfo) */ public static final String OPDATERINGSINTENT_Udsendelse = "dk.dr.radio.afspiller.OPDATERING_Udsendelse"; /** * Bruges til at sende broadcasts om ny info om hvad der spiller nu */ public static final String OPDATERINGSINTENT_SpillerNuListe = "dk.dr.radio.afspiller.OPDATERING_SpillerNuListe"; // // Opdateringer i baggrunden. // private boolean baggrundsopdateringAktiv = false; private boolean baggrundstrådSkalVente = true; /** * Først efter indlæstning starter vi baggrundstråden - fra splash og fra afspiller_akt. * Dette er et separat skridt da det ikke skal ske ved opstart af levende ikon */ public void tjekBaggrundstrådStartet() { if (!baggrundstråd.isAlive()) baggrundstråd.start(); } public void setBaggrundsopdateringAktiv(boolean aktiv) { if (baggrundsopdateringAktiv == aktiv) return; baggrundsopdateringAktiv = aktiv; Log.d("setBaggrundsopdateringAktiv( " + aktiv); if (baggrundsopdateringAktiv) baggrundstrådSkalOpdatereNu(); // væk baggrundtråd } private void baggrundstrådSkalOpdatereNu() { baggrundstrådSkalVente = false; synchronized (baggrundstråd) { baggrundstråd.notify(); } } final Thread baggrundstråd = new Thread() { @Override public void run() { // Hovedløkke while (true) { try { if (baggrundstrådSkalVente) synchronized (baggrundstråd) { if (baggrundsopdateringAktiv) baggrundstråd.wait(15000); // Vent 15 sekunder. Men vågn op hvis nogen kalder baggrundstråd.notify()! // baggrundsopdateringAktiv kan være sat til false inden for de sidste 15 sekunder og så skal vi vente videre if (!baggrundsopdateringAktiv) baggrundstråd.wait(); // Vent indtil tråden vækkes baggrundstråd.wait(50); // Vent kort så den aktiverende tråd kan gøre sit arbejde færdigt } baggrundstrådSkalVente = true; hentUdsendelserOgSpillerNuListe(); tjekForNyeStamdata(); } catch (Exception ex) { Log.e(ex); } } } }; private void hentUdsendelserOgSpillerNuListe() { String url = stamdata.json.optString("spiller_nu_url") + aktuelKanalkode; spillerNuListe2 = null; if (stamdata.kanalerDerSkalViseSpillerNu.contains(aktuelKanalkode)) { try { spillerNuListe2 = JsonIndlaesning.hentSpillerNuListe(url); } catch (Exception ex) { Log.d("Kunne ikke hente spillerNuListe " + url); } // Al opdatering, herunder tildeling bør ske i GUI-tråden for at undgå at // GUIen er i gang med at bruge objektet mens det opdateres handler.post(new Runnable() { public void run() { spillerNuListe = spillerNuListe2; // Send broadcast om at listen er opdateret App.instans.sendBroadcast(new Intent(OPDATERINGSINTENT_SpillerNuListe)); } }); } try { url = stamdata.json.optString("program_url") + aktuelKanalkode; udsendelser2 = JsonIndlaesning.hentUdsendelser(url); udsendelser_ikkeTilgængeligt = false; } catch (Exception ex) { Log.e("Kunne ikke hente udsendelser fra " + url, ex); //Skal ikke rapporteres: https://www.bugsense.com/dashboard/project/57c90f98#error/28786099 , https://www.bugsense.com/dashboard/project/57c90f98#error/61580882 og https://www.bugsense.com/dashboard/project/57c90f98#error/29664901 // Log.kritiskFejl(null,ex); udsendelser2 = null; udsendelser_ikkeTilgængeligt = true; } handler.post(new Runnable() { public void run() { udsendelser = udsendelser2; App.instans.sendBroadcast(new Intent(OPDATERINGSINTENT_Udsendelse)); } }); } /** * Tjek om en evt ny udgave af stamdata skal indlæses */ private void tjekForNyeStamdata() { final String STAMDATA_SIDST_INDLÆST = "stamdata_sidst_indlæst"; long sidst = App.prefs.getLong(STAMDATA_SIDST_INDLÆST, 0); long nu = System.currentTimeMillis(); long alder = (nu - sidst) / 1000 / 60; if (alder >= 30) try { // stamdata er ældre end en halv time Log.d("Stamdata er " + alder + " minutter gamle, opdaterer dem..."); // Opdater tid (hvad enten indlæsning lykkes eller ej) App.prefs.edit().putLong(STAMDATA_SIDST_INDLÆST, nu).commit(); String stamdatastr = JsonIndlaesning.hentUrlSomStreng(STAMDATA_URL); //Log.d(stamdatastr); final Stamdata stamdata2 = JsonIndlaesning.parseStamdata(stamdatastr); // Hentning og parsning gik godt - vi gemmer den nye udgave i prefs App.prefs.edit().putString(STAMDATA_URL, stamdatastr).commit(); // Al opdatering, herunder tildeling bør ske i GUI-tråden for at undgå at // GUIen er i gang med at bruge objektet mens det opdateres handler.post(new Runnable() { public void run() { stamdata = stamdata2; // Send broadcast om at stamdata er opdateret App.instans.sendBroadcast(new Intent(OPDATERINGSINTENT_Stamdata)); } }); } catch (Exception e) { Log.e("Fejl parsning af stamdata. Url=" + STAMDATA_URL, e); } } /** * Skifter til en anden kanal * * @param nyKanalkode en af "P1", "P2", "P3", "P5D", "P6B", "P7M", "RAM", etc * eller evt P4-kanal "KH4", "NV4", "AR4", "AB4", "OD4", "AL4", "HO4", "TR4", "RO4", "ES4", "NS4"], * Bemærk at "P4" eller andre uden en streamUrl IKKE er tilladt */ public void skiftKanal(String nyKanalkode) { Log.d("DRData.skiftKanal(" + nyKanalkode); aktuelKanalkode = nyKanalkode; aktuelKanal = stamdata.kanalkodeTilKanal.get(aktuelKanalkode); App.prefs.edit().putString(NØGLE_kanal, aktuelKanalkode).commit(); udsendelser = null; spillerNuListe = null; udsendelser_ikkeTilgængeligt = false; // Væk baggrundstråden så den indlæser den nye kanals udsendelser etc og laver broadcasts med nyt info baggrundstrådSkalOpdatereNu(); } public String findKanalUrlFraKode(Kanal kanal) { String lydformat = App.prefs.getString(NØGLE_lydformat, "shoutcast"); boolean højKvalitet = "høj".equals(App.prefs.getString("lydkvalitet", "standard")); rapportering.nulstil(); rapportering.lydformat = lydformat + (højKvalitet ? "_høj" : "_standard"); String url = kanal.shoutcastUrl; if ("rtsp".equals(lydformat)) url = kanal.rtspUrl; else if ("httplive".equals(lydformat)) url = kanal.aacUrl; else if ("httplive2".equals(lydformat)) url = kanal.aacUrl.replaceAll("httplive", "http"); if (højKvalitet) { url = url.replace("LQ", "HQ"); url = url.replace("quality=1", "quality=2"); // on-demand radio nyheder workaround url = url.replace("L.stream", "H.stream"); // MP3, RTSP stream navn workaround } String info = "Kanal: " + kanal.longName + "\nlydformat: " + lydformat + "\nKvalitet: " + (højKvalitet ? "Høj" : "Normal") + "\n" + url; if (DRData.udvikling) App.langToast(info); Log.d(info); //String url = kanal.shoutcastUrl; return url; } }