/** 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.akt; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.res.Resources; import android.graphics.PorterDuff; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.media.AudioManager; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.Html; import android.text.util.Linkify; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnFocusChangeListener; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.ViewFlipper; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.WeakHashMap; import dk.dr.radio.R; import dk.dr.radio.afspilning.Afspiller; import dk.dr.radio.afspilning.AfspillerListener; import dk.dr.radio.akt_v3.ListeAkt; import dk.dr.radio.data.DRData; import dk.dr.radio.data.spiller_nu.SpillerNuElement; import dk.dr.radio.data.stamdata.Kanal; import dk.dr.radio.diverse.App; import dk.dr.radio.diverse.Log; public class Afspilning_akt extends Activity implements AfspillerListener { private ViewFlipper flipper; private ImageButton playStopButton; private ImageView previousImageView; private ImageView nextImageView; private Afspiller afspiller; private TextView currentProgramTitleTextView; private TextView currentProgramDescriptionTextView; private TextView currentChannelTextView; private TextView nextProgramTitleTextView; private LinearLayout tracksLinearLayout; private TextView status; private SharedPreferences prefs; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); prefs = PreferenceManager.getDefaultSharedPreferences(this); // Fuld skærm skjuler den notification vi sætter op så brugeren ikke opdager den, // og det er lidt forvirrende så vi slår det fra for nu //getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN) ; setContentView(R.layout.afspilning_akt); initControls(); DRData.instans.tjekBaggrundstrådStartet(); afspiller = DRData.instans.afspiller; registerReceiver(stamdataOpdateretReciever, new IntentFilter(DRData.OPDATERINGSINTENT_Stamdata)); registerReceiver(udsendelserOpdateretReciever, new IntentFilter(DRData.OPDATERINGSINTENT_Udsendelse)); registerReceiver(spillerNuListeOpdateretReciever, new IntentFilter(DRData.OPDATERINGSINTENT_SpillerNuListe)); TextView nextProgramHeaderTextView = (TextView) findViewById(R.id.player_next_program_textview); nextProgramHeaderTextView.setText(DRData.instans.stamdata.json.optString("text_footerTitle")); INGEN_LASTFM = getResources().getDrawable(R.drawable.nolastfm); try { visAktuelKanal(); visAktuelUdsendelse(); visNæsteUdsendelse(); visSpillerNuInfo(); } catch (Exception e) { Log.rapporterFejl(e); } visStartStopKnap(); // Volumen op/ned skal styre lydstyrken af medieafspilleren, uanset som noget spilles lige nu eller ej setVolumeControlStream(AudioManager.STREAM_MUSIC); // Vis korrekt knap og/eller start afspilning // når aktivitet startes men ikke hvis den genoptages (dvs kun når savedInstanceState==null) boolean startAfspilningMedDetSammme = prefs.getBoolean("startAfspilningMedDetSammme", false); if (savedInstanceState == null && startAfspilningMedDetSammme && afspiller.getAfspillerstatus() == Afspiller.STATUS_STOPPET) { startAfspilning(); } else { visStartStopKnap(); } //XXX TODO xxx Garmin A50 skal bruge RTSP som standard. mp3/shoutcast virker ikke afspiller.addAfspillerListener(Afspilning_akt.this); afspiller.addAfspillerListener(DRData.instans.rapportering); } @Override public void onBackPressed() { super.onBackPressed(); AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); int volumen = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); //boolean lukAfspillerServiceVedAfslutning = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("lukAfspillerServiceVedAfslutning", false); // Hvis der er skruet helt ned så stop afspilningen if (volumen == 0 && afspiller.afspillerstatus != Afspiller.STATUS_STOPPET) { afspiller.stopAfspilning(); super.onBackPressed(); } else if (afspiller.afspillerstatus == Afspiller.STATUS_STOPPET) { super.onBackPressed(); } else { // Spørg brugeren om afspilningen skal stoppes showDialog(1); } } @Override protected void onDestroy() { afspiller.addAfspillerListener(Afspilning_akt.this); afspiller.addAfspillerListener(DRData.instans.rapportering); unregisterReceiver(stamdataOpdateretReciever); unregisterReceiver(udsendelserOpdateretReciever); unregisterReceiver(spillerNuListeOpdateretReciever); super.onDestroy(); } AlertDialog internetforbindelseManglerDialog; @Override protected void onResume() { // se om vi er online if (App.erOnline()) { // hurra - opdater data fra server DRData.instans.setBaggrundsopdateringAktiv(true); } else { // Informer brugeren hvis vi er offline if (internetforbindelseManglerDialog == null) { internetforbindelseManglerDialog = new AlertDialog.Builder(this).create(); internetforbindelseManglerDialog.setTitle("Internetforbindelse mangler"); internetforbindelseManglerDialog.setMessage("Din telefon er ikke tilsluttet internettet. For at høre radio skal du åbne op for forbindelser via WIFI eller mobildata."); } if (!internetforbindelseManglerDialog.isShowing()) { internetforbindelseManglerDialog.show(); } } super.onResume(); } @Override protected void onPause() { DRData.instans.setBaggrundsopdateringAktiv(false); super.onPause(); } private void initControls() { flipper = (ViewFlipper) findViewById(R.id.flipper); currentProgramTitleTextView = (TextView) findViewById(R.id.player_current_program_title_textview); currentProgramDescriptionTextView = (TextView) findViewById(R.id.player_current_program_description_textview); currentChannelTextView = (TextView) findViewById(R.id.player_current_program_channel_textview); nextProgramTitleTextView = (TextView) findViewById(R.id.player_next_program_title_textview); tracksLinearLayout = (LinearLayout) findViewById(R.id.player_tracks_linearlayout); status = (TextView) findViewById(R.id.status); try { // DRs skrifttyper er ikke offentliggjort i SVN, derfor kan følgende fejle: Typeface skrift_DRiRegular = Typeface.createFromAsset(getAssets(), "DRiRegular.otf"); status.setTypeface(skrift_DRiRegular); } catch (Exception e) { Log.e("DRs skrifttyper er ikke tilgængelige", e); } Button selectChannelButton = (Button) findViewById(R.id.player_select_channel_button); selectChannelButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { startActivityForResult(new Intent(Afspilning_akt.this, Kanalvalg_akt.class), 117); } }); playStopButton = (ImageButton) findViewById(R.id.start_stop_knap); playStopButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (afspiller.getAfspillerstatus() == Afspiller.STATUS_STOPPET) { startAfspilning(); } else { stopAfspilning(); } } }); playStopButton.setOnFocusChangeListener(new OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { playStopButton.setColorFilter(0xFFC0C0C0, PorterDuff.Mode.MULTIPLY); } else { playStopButton.setColorFilter(null); } } }); Button playerAboutButton = (Button) findViewById(R.id.player_about_button); playerAboutButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { startActivity(new Intent(Afspilning_akt.this, Om_DRRadio_akt.class)); } }); Button formatKnap = (Button) findViewById(R.id.player_format_button); formatKnap.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent i = new Intent(Afspilning_akt.this, Indstillinger_akt.class); i.putExtra(Indstillinger_akt.åbn_formatindstilling, true); startActivity(i); } }); previousImageView = (ImageView) findViewById(R.id.previous); previousImageView.setAlpha(200); nextImageView = (ImageView) findViewById(R.id.next); nextImageView.setAlpha(200); nextImageView.setVisibility(ImageButton.GONE); } /** * Denne metode kaldes når der er valgt en kanal */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d("onActivityResult " + requestCode + " " + resultCode + " " + data); // requestCode er 117 if (resultCode != RESULT_OK) { return; // Hvis brugeren trykkede på tilbage-knappen eller valgte den samme kanal } // Afspilning skal starte så når brugeren har valgt kanal // sætKanal(); startAfspilning(); // Kald for at nulstille skærmen try { visAktuelUdsendelse(); visNæsteUdsendelse(); visSpillerNuInfo(); } catch (Exception e) { Log.rapporterOgvisFejl(this, e); } } private void startAfspilning() { Log.d("startAfspilning"); try { sætKanal(); afspiller.startAfspilning(); DRData.instans.rapportering.afspilningForsøgtStartet = System.currentTimeMillis(); visStartStopKnap(); } catch (Exception e) { Log.e(e); } } private void sætKanal() { String url = DRData.instans.findKanalUrlFraKode(DRData.instans.aktuelKanal); afspiller.setKanal(DRData.instans.aktuelKanal.longName, url); //startStopButton.setImageResource(R.drawable.buffer_white); visAktuelKanal(); } private void stopAfspilning() { afspiller.stopAfspilning(); } private void visStatus(String txt) { status.setText(txt); Log.d(txt); } private void visStartStopKnap() { if (afspiller == null) { return; } if (afspiller.getAfspillerstatus() == Afspiller.STATUS_STOPPET) { playStopButton.setImageResource(R.drawable.afspilning_start); } else { playStopButton.setImageResource(R.drawable.afspilning_stop); } } private void sætForbinderProcent(int procent) { //Log.d( "sætforbinderProcent( " + procent + " )" ); int afspillerstatus = afspiller.getAfspillerstatus(); if (procent <= 0) { if (afspillerstatus == Afspiller.STATUS_FORBINDER) { visStatus("Forbinder..."); } else { visStatus(""); } } else { visStatus("Forbinder... " + procent + "%"); } } public void onAfspilningStartet() { visStatus("Afspiller"); visStartStopKnap(); } public void onAfspilningStoppet() { visStatus("Stoppet"); visStartStopKnap(); } public void onAfspilningForbinder(int procent) { if (procent >= 100) { onAfspilningStartet(); } else { sætForbinderProcent(procent); } } final static String drift_statusmeddelelse_NØGLE = "drift_statusmeddelelse"; static int drift_statusmeddelelse_hash = 0; static String drift_statusmeddelelse = ""; // static necesas por certigi ke la valoro pluiros al venonta aktiveco se oni turnas la ekranon private BroadcastReceiver stamdataOpdateretReciever = new BroadcastReceiver() { @Override public void onReceive(Context ctx, Intent i) { Log.d("stamdataOpdateretReciever"); drift_statusmeddelelse = DRData.instans.stamdata.json.optString(drift_statusmeddelelse_NØGLE).trim(); // Tjek i prefs om denne drifmeddelelse allerede er vist. // Der er 1 ud af en millards chance for at hashkoden ikke er ændret, den risiko tør vi godt løbe drift_statusmeddelelse_hash = drift_statusmeddelelse.hashCode(); final int gammelHashkode = prefs.getInt(drift_statusmeddelelse_NØGLE, 0); Log.d("drift_statusmeddelelse='" + drift_statusmeddelelse + "' nyHashkode=" + drift_statusmeddelelse_hash + " gammelHashkode=" + gammelHashkode); if (gammelHashkode != drift_statusmeddelelse_hash && !"".equals(drift_statusmeddelelse)) { // Driftmeddelelsen er ændret. Vis den... showDialog(0); } } }; @Override protected Dialog onCreateDialog(final int id) { AlertDialog.Builder ab = new AlertDialog.Builder(this); if (id == 0) { ab.setMessage(drift_statusmeddelelse); ab.setPositiveButton("OK", new AlertDialog.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { prefs.edit().putInt(drift_statusmeddelelse_NØGLE, drift_statusmeddelelse_hash).commit(); // ...og gem ny hashkode i prefs } }); } else { // if (id == 1) ab.setMessage("Stop afspilningen?"); ab.setPositiveButton("Stop\nradioen", new AlertDialog.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { stopAfspilning(); finish(); } }); ab.setNeutralButton("Fortsæt i\nbaggrunden", new AlertDialog.OnClickListener() { public void onClick(DialogInterface arg0, int arg1) { finish(); } }); //ab.setNegativeButton("Annullér", null); } return ab.create(); } @Override public void onPrepareDialog(int id, Dialog d) { if (id == 0) ((AlertDialog) d).setMessage(drift_statusmeddelelse); } private BroadcastReceiver udsendelserOpdateretReciever = new BroadcastReceiver() { @Override public void onReceive(Context ctx, Intent i) { //Log.d("udsendelserOpdateretReciever"); try { visAktuelUdsendelse(); visNæsteUdsendelse(); } catch (Exception e) { Log.rapporterFejl(e); } } }; private BroadcastReceiver spillerNuListeOpdateretReciever = new BroadcastReceiver() { String forrigeSpillerNu = ""; @Override public void onReceive(Context ctx, Intent i) { //Log.d("spillerNuListeOpdateretReciever"); // visSpillerNuInfo() er dyr at kalde så den kalder vi kun hvis data er ændret String spillerNu = "null"; if (DRData.instans.spillerNuListe != null && DRData.instans.spillerNuListe.liste.size() > 0) { spillerNu = String.valueOf(DRData.instans.spillerNuListe.liste.get(0).title); } if (!forrigeSpillerNu.equals(spillerNu)) { forrigeSpillerNu = spillerNu; Log.d("spillerNuListeOpdateretReciever opdatering " + spillerNu); visSpillerNuInfo(); } } }; private void visAktuelKanal() { String kanal = DRData.instans.aktuelKanalkode; ImageView aktuelKanalImageView = (ImageView) findViewById(R.id.kanalbillede); TextView aktuelKanalTextView = (TextView) findViewById(R.id.kanaltekst); Resources res = getResources(); int id = res.getIdentifier("kanal_" + kanal.toLowerCase(), "drawable", getPackageName()); if (id == 0) { String visningsnavn = DRData.instans.stamdata.kanalkodeTilKanal.get(kanal).longName; aktuelKanalTextView.setText(visningsnavn); aktuelKanalTextView.setVisibility(View.VISIBLE); aktuelKanalImageView.setVisibility(View.GONE); } else { aktuelKanalImageView.setImageResource(id); aktuelKanalTextView.setVisibility(View.GONE); aktuelKanalImageView.setVisibility(View.VISIBLE); } } private void visAktuelUdsendelse() { String aboveHeader = DRData.instans.stamdata.json.optString("text_aboveHeader"); Kanal kanal = DRData.instans.aktuelKanal; String tekst = aboveHeader + " " + kanal.longName + ":"; currentChannelTextView.setText(tekst); if (DRData.instans.udsendelser_ikkeTilgængeligt) { currentProgramTitleTextView.setText("Kunne ikke hente programinfo"); currentProgramDescriptionTextView.setText(""); } else if (DRData.instans.udsendelser == null || DRData.instans.udsendelser.currentProgram == null) { currentProgramTitleTextView.setText("Venter på programinfo"); currentProgramDescriptionTextView.setText(""); } else { String currentProgamTitle = DRData.instans.udsendelser.currentProgram.title; currentProgramTitleTextView.setText(currentProgamTitle); String currentProgamDescription = DRData.instans.udsendelser.currentProgram.description; currentProgramDescriptionTextView.setText(Html.fromHtml(currentProgamDescription)); // Konverter tekst-links i programinfo til rigtige links - frederik Linkify.addLinks(currentProgramDescriptionTextView, Linkify.WEB_URLS); } } private void visNæsteUdsendelse() { if (DRData.instans.udsendelser != null && DRData.instans.udsendelser.nextProgram != null) { String nextProgramTitle = DRData.instans.udsendelser.nextProgram.title; String nextProgramTitleLimited = nextProgramTitle; String nextProgramStartTime = DRData.instans.udsendelser.nextProgram.start; String nextProgramStopTime = DRData.instans.udsendelser.nextProgram.stop; String nextProgramTime = "(" + nextProgramStartTime + " - " + nextProgramStopTime + ")"; nextProgramTitleTextView.setText(nextProgramTitleLimited + " " + nextProgramTime); } else { nextProgramTitleTextView.setText("Ingen programinfo"); } } //@SuppressWarnings("unchecked") private void visSpillerNuInfo() { boolean showChannel = DRData.instans.stamdata.kanalerDerSkalViseSpillerNu.contains(DRData.instans.aktuelKanalkode); if (!showChannel || DRData.instans.spillerNuListe == null || DRData.instans.spillerNuListe.liste == null || DRData.instans.spillerNuListe.liste.isEmpty()) { tracksLinearLayout.setVisibility(LinearLayout.GONE); return; } tracksLinearLayout.setVisibility(LinearLayout.VISIBLE); final List<SpillerNuElement> tracks = new ArrayList<SpillerNuElement>(DRData.instans.spillerNuListe.liste); synchronized (flipper) { flipper.removeAllViews(); Collections.rotate(tracks, -1); Collections.reverse(tracks); int index = 0; for (SpillerNuElement track : tracks) { View view = buildViewFromTrack(track, index); flipper.addView(view); index++; } //On reload of songs show only the left arrow previousImageView.setVisibility(ImageView.VISIBLE); nextImageView.setVisibility(ImageView.GONE); } } WeakHashMap<String, Drawable> urlTilDrawable = new WeakHashMap<String, Drawable>(); Drawable INGEN_LASTFM; private View buildViewFromTrack(SpillerNuElement track, int index) { LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = mInflater.inflate(R.layout.flipper_internallayout, null); LinearLayout flipperLinearLayout = (LinearLayout) view.findViewById(R.id.FlipperLinearLayout); TextView flipperLastFmTextTextView = (TextView) view.findViewById(R.id.FlipperLastFmTextTextView); String lastFm = DRData.instans.stamdata.json.optString("text_trackPhoto"); flipperLastFmTextTextView.setText(lastFm); TextView flipperTrackTitleHeaderTextView = (TextView) view.findViewById(R.id.FlipperTrackTitleHeaderTextView); int numberOfTracks = DRData.instans.spillerNuListe.liste.size(); String trackHeader; if (index == 0) { trackHeader = DRData.instans.stamdata.json.optString("text_trackLast"); } else if (index == numberOfTracks - 1) { trackHeader = DRData.instans.stamdata.json.optString("text_trackBeforeLast"); } else { trackHeader = DRData.instans.stamdata.json.optString("text_trackPrevious"); } flipperTrackTitleHeaderTextView.setText(trackHeader); TextView flipperTrackTitleTextView = (TextView) view.findViewById(R.id.FlipperTrackTitleTextView); flipperTrackTitleTextView.setText(track.title); TextView flipperTrackDisplayArtistTextView = (TextView) view.findViewById(R.id.FlipperTrackDisplayArtistTextView); flipperTrackDisplayArtistTextView.setText(track.displayArtist); TextView flipperTrackStartTimeTextView = (TextView) view.findViewById(R.id.FlipperTrackStartTimeTextView); flipperTrackStartTimeTextView.setText("Afspillet kl. " + track.start); return flipperLinearLayout; } /** * Håndtering af MENU-knappen */ @Override public boolean onCreateOptionsMenu(Menu menu) { //Log.d("onCreateOptionsMenu!!!"); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.afspilning_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.om) { startActivity(new Intent(this, Om_DRRadio_akt.class)); } else if (id == R.id.v3) { startActivity(new Intent(this, ListeAkt.class)); //startActivity(new Intent(this, VisFragmentAkt.class).putExtra(VisFragmentAkt.KLASSE, MineOpkaldFrag.class)); } else if (id == R.id.indstillinger) { startActivity(new Intent(this, Indstillinger_akt.class)); } else if (id == R.id.sluk) { if (afspiller.getAfspillerstatus() != Afspiller.STATUS_STOPPET) { stopAfspilning(); } finish(); } return true; } }