/* * File: TICO.java * This file is part of Tico, an application to create and perform * interactive communication boards to be used by people with * severe motor disabilities. * * Author: Eduardo Ferrer * * Date: Nov, 2011 * * Company: Dept. of Computer Sciences and Systems Engineering, Universidad de Zaragoza, Spain * * * License: * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program 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 this program. If not, see . */ package android.TICO; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.view.Window; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; import android.widget.HorizontalScrollView; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Element; //import org.xml.sax.SAXException; import configuration.SetupScreen; import configuration.TSetup; import android.graphics.Color; //import android.graphics.Rect; //import android.graphics.RectF; import android.graphics.Typeface; import android.graphics.drawable.GradientDrawable; import android.TICO.AsyncTasks.playSentence; import android.TICO.AsyncTasks.playSound; import android.TICO.Views.*; /** * The class that defines the main activity of Tico Interpreter. */ public class TICO extends Activity { /** Called when the activity is first created. */ int LayoutVisible=0; int initialBoard=0; String fileName; String url; File root=Environment.getExternalStorageDirectory(); int tableroAnterior=-1; //objeto gestor de las celdas acumuladas accumulated_cells accumulated; RelativeLayout layPGeneral; RelativeLayout layPLandscape; LinearLayout ticoLayout; control_area/*RelativeLayout*/ controlLayout; control_area /*RelativeLayout*/ controlLayoutLandscape; NodeList boards; NodeList boardsLandscape; //tamanyos de las distintas partes que conforman la pantalla portrait RelativeLayout.LayoutParams panelSize; RelativeLayout.LayoutParams accumulatedSize; RelativeLayout.LayoutParams controlSize; //tamanyos en Landscape RelativeLayout.LayoutParams panelSizeLandscape; RelativeLayout.LayoutParams accumulatedSizeLandscape; RelativeLayout.LayoutParams controlSizeLandscape; //celdas de control /* private cell inicio; private cell inicioLandscape; private cell volver; private cell volverLandscape; private cell leer; private cell leerLandscape; private cell borrar1; private cell borrar1Landscape; private cell borrarTodas; private cell borrarTodasLandscape;*/ //datos de la pantalla del dispositivo Display displayActual; DisplayMetrics metrics; protected PowerManager.WakeLock wakelock; PowerManager pm; //tareas asincronas playSound reproductorSonido=null; playSentence reproductorFrase=null; automaticScan barredor; int[] vectorOrderedCells; textArea[] vectorTextAreas; AlertDialog alertPrincipal; //recursos pasados en el xml config.xml, publico y estatico para el acceso general public static Resources res; //para escaneo automatico la vista (celda) que esta seleccionada en este momento int vistaActual; HorizontalScrollView scroll; HorizontalScrollView scrollLandscape; private Intent intent; private boolean backEnabled=true; private long backEventTime=0; //codigos de tipo int para opciones e intents private static final int SETUP=123; private static final int VIDEO=223; private static final int ABRIR=0; private static final int CONFIGURACION=1; private static final int ACCIONES=2; private static final int READ=3; private static final int REMOVE_CELL=4; private static final int REMOVE_ALL_CELLS=5; private static final int AYUDA=6; private static final int EXIT=7; private static final int BACK=8; private static final int HOME=9; private static final int RESOLUTIONS=10; //cuando dejamos en segundo plano la pantalla se podrá apagar automaticamente protected void onResume(){ super.onResume(); if(!wakelock.isHeld()) this.wakelock.acquire(); } public void onSaveInstanceState(Bundle icicle) { super.onSaveInstanceState(icicle); if(wakelock.isHeld()) this.wakelock.release(); } /** * Change the orientation of interpreter * when the orientation of the device changes if it's necessary. */ @Override public void onConfigurationChanged(Configuration newConfig) { //paramos el barrido automatico si esta activado if(barredor!=null){ barredor.cancel(true); barredor=null; } super.onConfigurationChanged(newConfig); if(controlLayout!=null && LayoutVisible>=0){ //ya tenemos creado un proyecto displayActual.getMetrics(metrics); if(metrics.heightPixels>metrics.widthPixels){ //cambiamos a Portrait //ponemos todas las celdas de control que vamos a mostrar a su imagen principal for(int i=0;i<5;i++){ ((cell)controlLayout.getChildAt(i)).showMainCell(); } ticoLayout.removeAllViews(); ticoLayout.addView(scroll); ticoLayout.addView(layPGeneral); ticoLayout.addView(controlLayout); try { if(boards.getLength()>0) MostrarPanel(layPGeneral,boards,accumulated,LayoutVisible); else //solo se ha definido tableros en landscape y cargamos de ahi MostrarPanel(layPGeneral,boardsLandscape,accumulated,LayoutVisible); } catch (OutOfMemoryError e) { // TODO Auto-generated catch block outOfMemoryRecover(); e.printStackTrace(); //reactivamos los botones listenersOn(); }catch(NullPointerException e){ readErrorRecover(); //reactivamos los botones listenersOn(); } catch(Exception e){ readErrorRecover(); //reactivamos los botones listenersOn(); } } else{ //cambiamos a Landscape //ponemos todas las celdas de control a su imagen principal for(int i=0;i<5;i++){ ((cell)controlLayoutLandscape.getChildAt(i)).showMainCell(); } ticoLayout.removeAllViews(); ticoLayout.addView(scrollLandscape); ticoLayout.addView(layPLandscape); ticoLayout.addView(controlLayoutLandscape); try { if(boardsLandscape.getLength()>0) MostrarPanel(layPLandscape,boardsLandscape,accumulated,LayoutVisible); else //solo se han definido los tableros en portrait MostrarPanel(layPLandscape,boards,accumulated,LayoutVisible); } catch (OutOfMemoryError e) { // TODO Auto-generated catch block outOfMemoryRecover(); e.printStackTrace(); //reactivamos los botones listenersOn(); }catch(NullPointerException e){ readErrorRecover(); //reactivamos los botones listenersOn(); } catch(Exception e){ readErrorRecover(); //reactivamos los botones listenersOn(); } } } } /**************************************************************************************************************************************/ /** * Redefine the behavior of the back button * for back in the boards */ //reescribimos el uso del back button @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && !event.isLongPress()) { if(event.getEventTime()>backEventTime){ if(accumulated!=null && backEnabled){ if(metrics.heightPixels>metrics.widthPixels){//portrait if(controlLayout!=null) controlLayout.volver().performClick();//if(controlLayout.volver()!=null) controlLayout.volver().performClick(); }else{//landscape if(controlLayoutLandscape!=null) controlLayoutLandscape.volver().performClick();//if(volverLandscape!=null) volverLandscape.performClick(); } } backEventTime=SystemClock.uptimeMillis(); } return true; } if(keyCode==KeyEvent.KEYCODE_BACK) return true; return super.onKeyDown(keyCode, event); } /**********************************************************************************************************************************/ /** * onCreate behavior of the main activity of * the interpreter. * It calls to the activity fileDialog for * select the .tcoa file. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //quitar barra de titulo requestWindowFeature(Window.FEATURE_NO_TITLE); //quitar barra de estado (bateria, hora...) getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); //configurar los botones fisicos de sonido al audio multimedia this.setVolumeControlStream(AudioManager.STREAM_MUSIC); res=getResources();//<-----una sola vez alertPrincipal=new AlertDialog.Builder(this).create();//creamos ya el dialogo de error al que llamaremos en caso //de encontrar alguno (sin inicializar mensajes) //bloqueamos el brillo de pantalla para que no se apague pm=(PowerManager)getSystemService(Context.POWER_SERVICE); this.wakelock=pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bloqueoBrillo"); this.wakelock.acquire(); setLayoutSizes(); try { TSetup.load(getApplicationContext()); //leemos el archivo de configuracion tico.conf, en caso de error lo creamos } catch (ParserConfigurationException e) { TSetup.createInitialConfig(getApplicationContext()); } catch (IOException e) { // TODO Auto-generated catch block TSetup.createInitialConfig(getApplicationContext()); } catch (Exception e) { // TODO Auto-generated catch block TSetup.createInitialConfig(getApplicationContext()); } //llamamos a fileDialog intent=new Intent(TICO.this,fileDialog.class); startActivityForResult(intent,1); setContentView(R.layout.main); } /**************************************************************************************************************************************/ /** * Redefine the behavior of the onActivityResult * for the results of activities fileDialog, * SetupScreen and videoPlayer. * @param requestCode The integer request code originally supplied to startActivityForResult(), allowing you to identify who this result came from. * @param resultCode The integer result code returned by the child activity through its setResult(). * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). */ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch(requestCode) { case (1) : { //Todo correcto if (resultCode == Activity.RESULT_OK) { LayoutVisible=-1; setContentView(R.layout.loading); //recuperamos el fichero con el proyecto de la activity fileDialog url = data.getStringExtra("fichero"); new loadingProject().execute(); }else{ refresh(); } break; } case(SETUP) : refresh(); break; case(VIDEO) : refresh(); break; } } /******************************************************************************************************************************************/ /** * Shows the correct board on the screen * @param layP The RelativeLayout where we load the board. * @param boards The NodeList with all the boards definition. * @param accumulated The accumulated_cells where we accumulate the sentence. * @param i The int that identificates the board to show. */ public void MostrarPanel(final RelativeLayout layP,final NodeList boards, final accumulated_cells accumulated, int i) throws OutOfMemoryError,NullPointerException,Exception{ //para evitar clicks compulsivos desactivamos los botones mientras cargamos el panel listenersOff(); //paramos, si existe, el barrido del anterior tablero if(barredor!=null){ barredor.cancel(true); barredor=null; for(int cont=0;cont<5;cont++){ ((cell)controlLayout.getChildAt(cont)).showMainCell(); ((cell)controlLayoutLandscape.getChildAt(cont)).showMainCell(); } } layP.removeAllViews(); System.gc();//garbage collector Node board=boards.item(i); NodeList orderedCells=null; NodeList modelList = ((Element)board).getElementsByTagName("model"); Element model = (Element)modelList.item(0); NodeList attributesList = model.getElementsByTagName("attributes"); Element attributes = (Element)attributesList.item(0); NodeList attributeBoard = attributes.getChildNodes(); float panelHeight=100; float panelWidth=100; int resizeStyle=1; String imagePanelURL=null; int backgroundColorP=res.getColor(R.color.background_default_color); int gradientP=Color.TRANSPARENT; for(int ii=0;ii=0){ cellView.setAlternateFrameSize(frameAlternateSize); } if(soundURL!=null){ cellView.setSound(soundURL); } if(videoURL!=null){ cellView.setVideo(videoURL); } if(orderedCells!=null){ int cont=0; while(cont< orderedCells.getLength() && !((Element)orderedCells.item(cont)).getTextContent().equals(id) ){ cont++; } if(contpreviousLength){ accumulated.accumulatedCells.removeViewAt(previousLength); } if(accumulated.accumulatedCellsLandscape.getChildCount()>previousLength){ accumulated.accumulatedCellsLandscape.removeViewAt(previousLength); } accumulated.imagesVector[previousLength]=null; accumulated.imagesVectorLandscape[previousLength]=null; accumulated.soundsVector[previousLength]=null; accumulated.length=previousLength; System.gc();//garbage collector //MENSAJE alertPrincipal.setTitle(res.getString(R.string.error)); alertPrincipal.setMessage("Problema de memoria al acumular celda.\nNo se ha podido acumular\nPruebe a tener menos celdas en el panel o poner imagenes menos pesadas"); alertPrincipal.setButton(res.getString(R.string.accept),new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); alertPrincipal.show(); e.printStackTrace(); } } //reproduccion de sonido if(cellView.getSound()!=null){ if(reproductorFrase!=null){ reproductorFrase.cancel(true); reproductorFrase=null; } reproductorSonido=new playSound(); reproductorSonido.execute(cellView.getSound()); } //reproduccion de video if(cellView.getVideo()!=null){ intent=new Intent(getApplicationContext(),videoPlayer.class); intent.putExtra("ruta",cellView.getVideo()); startActivityForResult(intent,VIDEO); //paramos el barrido progresivo si esta activado if(barredor!=null){ barredor.cancel(true); barredor=null; for(int cont=0;cont<5;cont++){ ((cell)controlLayout.getChildAt(cont)).showMainCell(); ((cell)controlLayoutLandscape.getChildAt(cont)).showMainCell(); } } } //si navega entre distintos tableros if(cellView.getDestiny()>=0){ tableroAnterior=LayoutVisible; LayoutVisible=cellView.getDestiny(); try { MostrarPanel(layP,boards,accumulated, LayoutVisible); } catch (OutOfMemoryError e) { outOfMemoryRecover(); e.printStackTrace(); //reactivamos los botones listenersOn(); }catch(NullPointerException e){ readErrorRecover(); //reactivamos los botones listenersOn(); } catch(Exception e){ readErrorRecover(); //reactivamos los botones listenersOn(); } } } }); layP.addView(cellView); if(ordenCelda>=0){ vectorOrderedCells[ordenCelda]=layP.indexOfChild(cellView); } } //celda de control if(componentType.equals("controllerCell")){ int action=0; Element attributesLabel = (Element)component.getElementsByTagName("attributes").item(0); NodeList attributesLabelList = attributesLabel.getElementsByTagName("attribute"); for(int jj=0;jj=0){ cellView.setAlternateFrameSize(frameAlternateSize); } if(soundAlternateURL!=null){ cellView.setSoundAlternate(soundAlternateURL); } if(orderedCells!=null){ int cont=0; while(cont< orderedCells.getLength() && !((Element)orderedCells.item(cont)).getTextContent().equals(id) ){ cont++; } if(contmetrics.widthPixels){ controlLayout.leer().performClick(); }else{ controlLayoutLandscape.leer().performClick();//leerLandscape.performClick(); } } }else if (cellView.getDestiny() == 5){//Volver if(accumulated!=null){ if(metrics.heightPixels>metrics.widthPixels){ controlLayout.volver().performClick();//volver.performClick(); }else{ controlLayoutLandscape.volver().performClick();//volverLandscape.performClick(); } } }else if (cellView.getDestiny() == 7){//Volver if(accumulated!=null){ if(metrics.heightPixels>metrics.widthPixels){ controlLayout.inicio().performClick();//inicio.performClick(); }else{ controlLayoutLandscape.inicio().performClick();//inicioLandscape.performClick(); } } } } }); layP.addView(cellView); if(ordenCelda>=0){ vectorOrderedCells[ordenCelda]=layP.indexOfChild(cellView); } } //etiqueta else if(componentType.equals("label")){ Element attributesLabel = (Element)component.getElementsByTagName("attributes").item(0); NodeList attributesLabelList = attributesLabel.getElementsByTagName("attribute"); for(int jj=0;jj=-5){ //si no barremos celdas de control if(metrics.heightPixels>metrics.widthPixels){//esta en portrait controlLayout.getChildAt(vistaActual+5).performClick(); } else{//esta en landscape controlLayoutLandscape.getChildAt(vistaActual+5).performClick(); } } } else if((vistaActual=0)){ layP.getChildAt(vectorOrderedCells[vistaActual]).performClick(); } //} } }); //iniciamos el barrido barredor=new automaticScan(); barredor.execute(layP); } //reactivamos los botones listenersOn(); } /***************************************************************************************************************************************************/ /** * AsyncTask for unzip and loading of the .tcoa file * * The result Element contains the xml structure of the .tcoa file */ private class loadingProject extends AsyncTask { protected Element doInBackground(Void... urls) { try{ //paramos el barredor si esta en marcha if(barredor!=null){ barredor.cancel(true); barredor=null; } //liberamos la memoria de imagenes layPGeneral=null; layPLandscape=null; controlLayout=null; controlLayoutLandscape=null; accumulated=null; System.gc(); DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder= factory.newDocumentBuilder(); File filezip = new File(url); File tempDirectory=new File(root+"/TMPtico"); tempDirectory.mkdir(); readProject.loadZip(filezip, tempDirectory); File file=new File(tempDirectory + "/project.xml"); //Layout de la pantalla completa ticoLayout=new LinearLayout(getApplicationContext()); ticoLayout.setOrientation(LinearLayout.VERTICAL); //anyadimos imagenes de control controlLayout=new control_area(getApplicationContext(),controlSize); /* controlLayout=new RelativeLayout(getApplicationContext()); controlLayout.setLayoutParams(controlSize); controlLayout.setBackgroundColor(res.getColor(R.color.bars_background_color)); */ controlLayoutLandscape=new control_area(getApplicationContext(),controlSizeLandscape); /* controlLayoutLandscape=new RelativeLayout(getApplicationContext()); controlLayoutLandscape.setLayoutParams(controlSizeLandscape); controlLayoutLandscape.setBackgroundColor(res.getColor(R.color.bars_background_color)); */ //Layout de las celdas acumuladas portrait RelativeLayout accumulatedCells=new RelativeLayout(getApplicationContext()); accumulatedCells.setLayoutParams(accumulatedSize); accumulatedCells.setBackgroundColor(res.getColor(R.color.bars_background_color)); scroll=new HorizontalScrollView(getApplicationContext()); scroll.setLayoutParams(accumulatedSize); scroll.addView(accumulatedCells); //Layout de las celdas acumuladas Landscape RelativeLayout accumulatedCellsLandscape=new RelativeLayout(getApplicationContext()); accumulatedCellsLandscape.setLayoutParams(accumulatedSizeLandscape); accumulatedCellsLandscape.setBackgroundColor(res.getColor(R.color.bars_background_color)); scrollLandscape=new HorizontalScrollView(getApplicationContext()); scrollLandscape.setLayoutParams(accumulatedSizeLandscape); scrollLandscape.addView(accumulatedCellsLandscape); //objeto gestor de las celdas acumuladas accumulated=new accumulated_cells(accumulatedCells,accumulatedCellsLandscape); accumulatedCells.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //reproduccion de sonido de la frase if(reproductorSonido!=null){ //cancelamos reproduccion de sonido reproductorSonido.cancel(true); reproductorSonido=null; } if(reproductorFrase!=null){ //cancelamos reproduccion de frase anterior reproductorFrase.cancel(true); reproductorFrase=null; } reproductorFrase=new playSentence(); reproductorFrase.execute(accumulated);//reproductorFrase.execute(); } }); //listener de las celdas acumuladas en landscape accumulated.accumulatedCellsLandscape.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //reproduccion de sonido de la frase acumulada if(reproductorSonido!=null){//cancelamos reproduccion de sonido reproductorSonido.cancel(true); reproductorSonido=null; } if(reproductorFrase!=null){ //cancelamos reproduccion de frase anterior reproductorFrase.cancel(true); reproductorFrase=null; } reproductorFrase=new playSentence(); reproductorFrase.execute(accumulated);//reproductorFrase.execute(); } }); //Leemos el xml con el proyecto Document doc = builder.parse(file); Element raiz=doc.getDocumentElement(); return raiz; }catch(Exception E){ //si hay excepcion devolvemos null return null; } } @Override protected void onPostExecute(Element raiz) { if(raiz==null){ //fallo al leer el proyecto setContentView(R.layout.main); layPGeneral=null; layPLandscape=null; controlLayout=null; controlLayoutLandscape=null; accumulated=null; alertPrincipal.setTitle(res.getString(R.string.error)); alertPrincipal.setMessage(res.getString(R.string.format_error)); alertPrincipal.setButton(res.getString(R.string.accept),new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); alertPrincipal.show(); } else{//lectura correcta hasta ahora NamedNodeMap raizatr=raiz.getAttributes(); if(raizatr.getNamedItem("orientation") != null){ if(raizatr.getNamedItem("orientation").getNodeValue().equals("portrait")){ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); }else{ //equals("landscape") setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } }else setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); boards = raiz.getElementsByTagName("board"); boardsLandscape = raiz.getElementsByTagName("boardLandscape"); //detectar panel inicial try{ if(boards!=null){ LayoutVisible=0; while(LayoutVisible=boards.getLength()) LayoutVisible=0; initialBoard=LayoutVisible; }else{ LayoutVisible=0; while(LayoutVisible=boardsLandscape.getLength()) LayoutVisible=0; initialBoard=LayoutVisible; } }catch(Exception e){ readErrorRecover(); return; } displayActual.getMetrics(metrics); //Mostramos el panel inicial layPGeneral=new RelativeLayout(getApplicationContext()); layPGeneral.setLayoutParams(panelSize); layPLandscape=new RelativeLayout(getApplicationContext()); layPLandscape.setLayoutParams(panelSizeLandscape); try { if(metrics.heightPixels>metrics.widthPixels){ //portrait ticoLayout.addView(scroll); ticoLayout.addView(layPGeneral); ticoLayout.addView(controlLayout); setContentView(ticoLayout); tableroAnterior=-1; if(boards.getLength()>0) MostrarPanel(layPGeneral,boards,accumulated, LayoutVisible); else //solo se han definido paneles en landscape MostrarPanel(layPGeneral,boardsLandscape,accumulated,LayoutVisible); }else{ //landscape ticoLayout.addView(scrollLandscape); ticoLayout.addView(layPLandscape); ticoLayout.addView(controlLayoutLandscape); setContentView(ticoLayout); if(boardsLandscape.getLength()>0)MostrarPanel(layPLandscape,boardsLandscape,accumulated, LayoutVisible); else //solo se han definido tableros en portrait MostrarPanel(layPLandscape,boards,accumulated,LayoutVisible); } } catch (OutOfMemoryError e) { // TODO Auto-generated catch block outOfMemoryRecover(); e.printStackTrace(); //reactivamos los botones listenersOn(); return; }catch(NullPointerException e){ readErrorRecover(); //reactivamos los botones listenersOn(); return; } catch(Exception e){ readErrorRecover(); //reactivamos los botones listenersOn(); return; } //anyadimos acciones a los botones de control controlLayout.inicio().setOnClickListener(new View.OnClickListener() {//inicio.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { tableroAnterior=LayoutVisible; LayoutVisible=initialBoard; try{ if(metrics.heightPixels>metrics.widthPixels){ if(boards.getLength()>0) MostrarPanel(layPGeneral,boards,accumulated,LayoutVisible); else //solo hemos definido paneles en landscape MostrarPanel(layPGeneral,boardsLandscape,accumulated,LayoutVisible); } else{ if(boardsLandscape.getLength()>0)MostrarPanel(layPLandscape,boardsLandscape,accumulated,LayoutVisible); else //solo hemos definido paneles en portrait MostrarPanel(layPLandscape,boards,accumulated,LayoutVisible); } } catch (OutOfMemoryError e) { // TODO Auto-generated catch block outOfMemoryRecover(); e.printStackTrace(); //reactivamos los botones listenersOn(); }catch(NullPointerException e){ readErrorRecover(); //reactivamos los botones listenersOn(); } catch(Exception e){ readErrorRecover(); //reactivamos los botones listenersOn(); } //despues del click en barrido volvemos a la celda principal if(TSetup.getSelectionMode().equals("automatic")) controlLayout.inicio().showMainCell(); } }); controlLayout.volver().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(tableroAnterior>=0){ int aux=tableroAnterior; tableroAnterior=LayoutVisible; LayoutVisible=aux; try { if(metrics.heightPixels>metrics.widthPixels){//portrait if(boards.getLength()>0) MostrarPanel(layPGeneral,boards,accumulated,LayoutVisible); else //solo hemos definido paneles en landscape MostrarPanel(layPGeneral,boardsLandscape,accumulated,LayoutVisible); } else{//landscape if(boardsLandscape.getLength()>0) MostrarPanel(layPLandscape,boardsLandscape,accumulated,LayoutVisible); else //solo hemos definido paneles en portrait MostrarPanel(layPLandscape,boards,accumulated,LayoutVisible); } } catch (OutOfMemoryError e) { // TODO Auto-generated catch block outOfMemoryRecover(); //reactivamos los botones listenersOn(); }catch(NullPointerException e){ readErrorRecover(); //reactivamos los botones listenersOn(); } catch(Exception e){ readErrorRecover(); //reactivamos los botones listenersOn(); } //si esta en automatico despues de pulsar deseleccionamos la celda de control if(TSetup.getSelectionMode().equals("automatic")) controlLayout.volver().showMainCell(); } } }); controlLayout.borrar1().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { accumulated.deleteCell(); //movemos el scroll para que se vea la última celda añadida (si no entra en pantalla) Handler handler = new Handler(); handler.postDelayed(new Runnable() { public void run() { scroll.fullScroll(HorizontalScrollView.FOCUS_RIGHT); } }, 100L); } }); controlLayout.borrarTodas().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { accumulated.deleteAllCells(); } }); controlLayout.leer().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(reproductorSonido!=null){ reproductorSonido.cancel(true); reproductorSonido=null; } if(reproductorFrase!=null){ reproductorFrase.cancel(true); reproductorFrase=null; } reproductorFrase=new playSentence(); reproductorFrase.execute(accumulated);//reproductorFrase.execute(); } }); //anyadimos acciones a los botones de control Landscape controlLayoutLandscape.inicio().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { tableroAnterior=LayoutVisible; LayoutVisible=initialBoard; try{ if(metrics.heightPixels>metrics.widthPixels){//portrait if(boards.getLength()>0) MostrarPanel(layPGeneral,boards,accumulated,LayoutVisible); else//solo hemos definido tableros en landscape MostrarPanel(layPGeneral,boardsLandscape,accumulated,LayoutVisible); } else{//landscape if(boardsLandscape.getLength()>0) MostrarPanel(layPLandscape,boardsLandscape,accumulated,LayoutVisible); else//solo hemos definido tableros en portrait MostrarPanel(layPLandscape,boards,accumulated,LayoutVisible); } } catch (OutOfMemoryError e) { // TODO Auto-generated catch block outOfMemoryRecover(); e.printStackTrace(); //reactivamos los botones listenersOn(); }catch(NullPointerException e){ readErrorRecover(); //reactivamos los botones listenersOn(); } catch(Exception e){ readErrorRecover(); //reactivamos los botones listenersOn(); } //si esta en automatico despues de pulsar deseleccionamos la celda de control if(TSetup.getSelectionMode().equals("automatic")) controlLayoutLandscape.inicio().showMainCell(); } }); controlLayoutLandscape.volver().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(tableroAnterior>=0){ int aux=tableroAnterior; tableroAnterior=LayoutVisible; LayoutVisible=aux; try{ if(metrics.heightPixels>metrics.widthPixels){//portrait if(boards.getLength()>0)MostrarPanel(layPGeneral,boards,accumulated,LayoutVisible); else//solo hemos definido tableros en landscape MostrarPanel(layPGeneral,boardsLandscape,accumulated,LayoutVisible); } else{//landscape if(boardsLandscape.getLength()>0)MostrarPanel(layPLandscape,boardsLandscape,accumulated,LayoutVisible); else//solo hemos definido tableros en portrait MostrarPanel(layPLandscape,boards,accumulated,LayoutVisible); } } catch (OutOfMemoryError e) { // TODO Auto-generated catch block outOfMemoryRecover(); e.printStackTrace(); //reactivamos los botones listenersOn(); }catch(NullPointerException e){ readErrorRecover(); //reactivamos los botones listenersOn(); } catch(Exception e){ readErrorRecover(); //reactivamos los botones listenersOn(); } //si esta en automatico despues de pulsar deseleccionamos la celda de control if(TSetup.getSelectionMode().equals("automatic")) controlLayoutLandscape.volver().showMainCell(); } } }); controlLayoutLandscape.borrar1().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { accumulated.deleteCell(); //movemos el scroll para que se vea la última celda añadida (si no entra en pantalla) Handler handler = new Handler(); handler.postDelayed(new Runnable() { public void run() { scroll.fullScroll(HorizontalScrollView.FOCUS_RIGHT); } }, 100L); } }); controlLayoutLandscape.borrarTodas().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { accumulated.deleteAllCells(); } }); controlLayoutLandscape.leer().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(reproductorSonido!=null){ reproductorSonido.cancel(true); reproductorSonido=null; } if(reproductorFrase!=null){ reproductorFrase.cancel(true); reproductorFrase=null; } reproductorFrase=new playSentence(); reproductorFrase.execute(accumulated);//reproductorFrase.execute(); } }); } } } /****************************************************************************************************************************************/ /** * AsyncTask for the automatic scan behavior * * @param vistas RelativeLayout panel that contains the cells to scanning * @param values[0] cell new cell to scan (publishProgress) * @param values[1] cell last cell scanned (publishProgress) */ //Ejecucion en paralelo de el barrido automático protected class automaticScan extends AsyncTask{ @Override protected Void doInBackground(RelativeLayout... vistas){ //ponemos la vista a un valor que no hace nada si pulsamos vistaActual=-6; //esperamos un segundo para dar tiempo a que se cierre la anterior ejecucion de automaticScan try { Thread.sleep(1000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } if(TSetup.getControlScanning().equals("first")){ //si escaneamos primero celdas de control vistaActual=-5; } else{ vistaActual=0; } boolean seguir=true; cell aux; cell ant=null; while(seguir){ if(vistaActual>=vectorOrderedCells.length){ if(!TSetup.getControlScanning().equals("no_scanning")){ vistaActual=-5; }else if(vectorOrderedCells.length>0){//hay celdas en el tablero y no escaneamos las de control inferiores vistaActual=0; }else{//no hay ninguna celda para escanear y salimos vistaActual=-6;//para que no haga nada al hacer click return null; } } if(isCancelled()){ publishProgress(null,ant); return null; } if(vistaActual>=0){ //estamos en el panel if(vectorOrderedCells[vistaActual]>=0){ aux=(cell)(vistas[0].getChildAt(vectorOrderedCells[vistaActual])); if(aux.getOrdered()){ //reproducimos sonido alternativo if(TSetup.getAlternativeSound() && (reproductorFrase==null || reproductorFrase.getStatus()!=Status.RUNNING) && aux.alternativeSoundURL!=null && !aux.alternativeSoundURL.equals("")){ if(reproductorSonido!=null) reproductorSonido.cancel(true); reproductorSonido=new playSound(); reproductorSonido.execute(aux.getSoundAlternate()); } publishProgress(aux,ant); try { Thread.sleep((long)TSetup.getScanWaitTime()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); seguir=false; } ant=aux; } } }else{ if(metrics.heightPixels>metrics.widthPixels){ //portrait aux=(cell)(controlLayout.getChildAt(vistaActual+5)); } else{//esta en landscape aux=(cell)(controlLayoutLandscape.getChildAt(vistaActual+5)); } publishProgress(aux,ant); try { Thread.sleep((long)TSetup.getScanWaitTime()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); seguir=false; } ant=aux; } vistaActual++; } return null; } /** * @param values[0] cell new cell to scan (publishProgress) * @param values[1] cell last cell scanned (publishProgress) */ @Override protected void onProgressUpdate( final cell... values) { super.onProgressUpdate(values); if(isCancelled()){ for(int i=0;i<5;i++){ ((cell)controlLayout.getChildAt(i)).showMainCell(); } return; } if(values[1]!=null){ values[1].showMainCell(); } values[0].showAlternateCell(); } } /**************************************************************************************************************************************************/ /** * Defines the sizes of the different layouts in the main TICO Activity * in function of the screen size and the horientation * Defines size for boards panel, accumulated images panel and the control panel for the 2 horientations * The sizes are refreshed in the variables panelSize accumulatedSize controlSize * panelSizeLandscape accumulatedSizeLandscape controlSizeLandscape */ private void setLayoutSizes(){ displayActual = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); metrics=new DisplayMetrics(); displayActual.getMetrics(metrics); //Si esta en portrait if(metrics.heightPixels>metrics.widthPixels){ panelSize = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_panel_porcien_portrait)/100); accumulatedSize = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_barras_porcien_portrait)/100); controlSize = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_barras_porcien_portrait)/100); int auxOrientation=this.getRequestedOrientation(); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); displayActual.getMetrics(metrics); panelSizeLandscape = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_panel_porcien_landscape)/100); accumulatedSizeLandscape = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_barras_porcien_landscape)/100); controlSizeLandscape = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_barras_porcien_landscape)/100); setRequestedOrientation(auxOrientation); } //si esta en landscape else{ panelSizeLandscape = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_panel_porcien_landscape)/100); accumulatedSizeLandscape = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_barras_porcien_landscape)/100); controlSizeLandscape = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_barras_porcien_landscape)/100); int auxOrientation=this.getRequestedOrientation(); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); displayActual.getMetrics(metrics); panelSize = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_panel_porcien_portrait)/100); accumulatedSize = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_barras_porcien_portrait)/100); controlSize = new RelativeLayout.LayoutParams(metrics.widthPixels,metrics.heightPixels*res.getInteger(R.integer.tamanyo_barras_porcien_portrait)/100); setRequestedOrientation(auxOrientation); } displayActual.getMetrics(metrics); } /*********************************************************************************************************************************************/ //menus /** * Defines the options menu shown by clicking menu button */ //mostrar menu @Override public boolean onCreateOptionsMenu(Menu menu){ super.onCreateOptionsMenu(menu); SubMenu sm; menu.add(0,ABRIR,0,R.string.abrir); menu.add(0,CONFIGURACION,0,R.string.configuracion); sm=menu.addSubMenu(0,ACCIONES,0,R.string.acciones); sm.add(0,READ,0,R.string.read); sm.add(0,REMOVE_CELL,0,R.string.remove_cell); sm.add(0,REMOVE_ALL_CELLS,0,R.string.remove_all_cells); sm.add(0,BACK,0,R.string.back); sm.add(0,HOME,0,R.string.home); sm.add(0,RESOLUTIONS,0,R.string.get_resolutions); menu.add(0,AYUDA,0,R.string.ayuda); menu.add(0,EXIT,0,R.string.exit); return true; } /**********************************************************************************************************************************/ //acciones del menu /** * Defines the behavior when selected a MenuItem * @param item The selected MenuItem */ @Override public boolean onOptionsItemSelected(MenuItem item){ switch(item.getItemId()){ case ABRIR: //abrir if(barredor!=null){ barredor.cancel(true); barredor=null; for(int cont=0;cont<5;cont++){ ((cell)controlLayout.getChildAt(cont)).showMainCell(); ((cell)controlLayoutLandscape.getChildAt(cont)).showMainCell(); } } intent=new Intent(TICO.this,fileDialog.class); startActivityForResult(intent,1); return true; case CONFIGURACION: //configuracion if(barredor!=null){ barredor.cancel(true); barredor=null; for(int cont=0;cont<5;cont++){ ((cell)controlLayout.getChildAt(cont)).showMainCell(); ((cell)controlLayoutLandscape.getChildAt(cont)).showMainCell(); } } intent=new Intent(TICO.this,SetupScreen.class); startActivityForResult(intent,SETUP); return true; case READ: //leer frase if(accumulated!=null){ if(metrics.heightPixels>metrics.widthPixels){//portrait controlLayout.leer().performClick(); }else{//landscape controlLayoutLandscape.leer().performClick(); } } return true; case REMOVE_CELL: //borrar celda if(accumulated!=null) accumulated.deleteCell(); return true; case REMOVE_ALL_CELLS: //borrar todas las celdas if(accumulated!=null) accumulated.deleteAllCells(); return true; case AYUDA: //ayuda AlertDialog alert=new AlertDialog.Builder(this).create(); alert.setTitle(res.getString(R.string.about)); alert.setMessage(res.getString(R.string.info_help)); alert.setButton(res.getString(R.string.accept), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); alert.show(); return true; case EXIT: //salir finish(); case BACK: //volver if(accumulated!=null){ if(metrics.heightPixels>metrics.widthPixels){//portrait controlLayout.volver().performClick(); }else{//landscape controlLayoutLandscape.volver().performClick(); } } return true; case HOME: //Inicio if(accumulated!=null){//si hay cargado un proyecto if(metrics.heightPixels>metrics.widthPixels){//portrait controlLayout.inicio().performClick(); }else{//landscape controlLayoutLandscape.inicio().performClick(); } } return true; case RESOLUTIONS: //Resoluciones AlertDialog alert2=new AlertDialog.Builder(this).create(); alert2.setTitle(res.getString(R.string.resolutions)); alert2.setMessage(res.getString(R.string.current_resolution)+"\n "+res.getString(R.string.width)+":"+metrics.widthPixels+" "+res.getString(R.string.height)+ ":" + metrics.heightPixels +"\n"+res.getString(R.string.board_resolution)+" portrait\n "+res.getString(R.string.width)+":"+panelSize.width+" "+res.getString(R.string.height)+":"+panelSize.height +"\n"+res.getString(R.string.board_resolution)+" landscape\n "+res.getString(R.string.width)+":"+panelSizeLandscape.width+" "+res.getString(R.string.height)+":"+panelSizeLandscape.height); alert2.setButton(res.getString(R.string.accept), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); alert2.show(); return true; } return true; } /***********************************************************************************************************************************/ /** * Redefines the onDestroy behavior of the main activity * Removes the temp directory */ //cuando la activity es destruida borra la carpeta temporal @Override public void onDestroy(){ //paramos el barredor si esta en marcha if(barredor!=null){ barredor.cancel(true); barredor=null; } super.onDestroy(); //quitamos el bloqueo de brillo de pantall if(wakelock.isHeld()) wakelock.release(); if(playSound.mp!=null) playSound.mp.stop(); File root = Environment.getExternalStorageDirectory(); File tempDirectory=new File(root+"/TMPtico"); readProject.borrarTmp(tempDirectory); android.os.Process.killProcess(android.os.Process.myPid()); } /*******************************************************************************************************************************************/ /** * Refresh the current board */ private void refresh(){ if(accumulated!=null){ //si no no hay cargado ningun proyecto y no refrescamos try{ if(metrics.heightPixels>metrics.widthPixels){//portrait if(boards.getLength()>0) MostrarPanel(layPGeneral,boards,accumulated, LayoutVisible); else //solo se han definido paneles en landscape MostrarPanel(layPGeneral,boardsLandscape,accumulated,LayoutVisible); }else{ //landscape if(boardsLandscape.getLength()>0)MostrarPanel(layPLandscape,boardsLandscape,accumulated, LayoutVisible); else //solo se han definido tableros en portrait MostrarPanel(layPLandscape,boards,accumulated,LayoutVisible); } } catch (OutOfMemoryError e) { // TODO Auto-generated catch block outOfMemoryRecover(); e.printStackTrace(); //reactivamos los botones listenersOn(); }catch(NullPointerException e){ readErrorRecover(); //reactivamos los botones listenersOn(); } catch(Exception e){ readErrorRecover(); //reactivamos los botones listenersOn(); } } } /*********************************************************************************************************************************************/ /** * Recover the application of a outOfMemoryError and shows a message */ private void outOfMemoryRecover(){ layPGeneral.removeAllViews(); layPLandscape.removeAllViews(); AlertDialog alert=new AlertDialog.Builder(this).create(); alert.setTitle(res.getString(R.string.error)); alert.setMessage(res.getString(R.string.memory_problem_panel)); alert.setButton(res.getString(R.string.accept), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); alert.show(); System.gc();//garbage collector } /********************************************************************************************************************************/ /** * Recover the application of a Exception and shows a message with the defined * AlertDialog alertPrincipal */ private void readErrorRecover(){ alertPrincipal.setTitle(res.getString(R.string.error)); alertPrincipal.setMessage(res.getString(R.string.read_error)); alertPrincipal.setButton(res.getString(R.string.accept),new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub } }); alertPrincipal.show(); setContentView(R.layout.main); layPGeneral=null; layPLandscape=null; controlLayout=null; controlLayoutLandscape=null; accumulated=null; } /***********************************************************************************************************************************/ private void listenersOff(){ backEnabled=false; if(controlLayout!=null) controlLayout.listenersOff(); if(controlLayoutLandscape!=null) controlLayout.listenersOff(); } private void listenersOn(){ //backEnabled=true; if(controlLayout!=null) controlLayout.listenersOn(); if(controlLayoutLandscape!=null) controlLayout.listenersOn(); Handler handler = new Handler(); handler.postDelayed(new Runnable() { public void run() { backEnabled=true; } }, 100L);//tiempo minimo de espera al cargar un panel para la siguiente orden de control } }