LectorRss:actualización 1.7.0

Nueva actualización, de la que lo más importante es la opción de exportar a la tarjeta externa la base de datos con todos los canales y sus entradas, así como las opciones de idioma, tiempo entre actualizaciones de los canales y demás.
También se arreglan un par de errores, uno de los cuales creía haber arreglado en la anterior versión.

Uno de los errores, el que debía estar arreglado, es, de nuevo, no marcar como leídas las entradas que lo están. En realidad sí se marcan, ha sido un trabalenguas lo siento, pero sólo aparece modificado el estado al salir del canal y volver a entrar en él. Ahora, por fín, funciona de manera adecuada.
El otro error era un ANR, la aplicación tarda mucho tiempo en responder. Esto creo, y recalco el creo pues se supone que manejando los hilos con handlers y tal funciona, pero no ha sido así. En realidad sólo me ocurrió una vez al entrar en un canal al tiempo que lo actualizaba, pero me ha servido para pasar de tratar los hilos y su comunicación con la GUI a través de los handlers que decia a hacerlo mediante AsyncTask, cosa que explicaré en el muy mencionado y nunca, por ahora, desvelado tutorial sobre como está hecho LectorRss.
Por último queda la novedad que ha hecho saltar de 1.6.0 a 1.7.0 y esta es el poder exportar o importar la base de datos y las opciones a la o desde la tarjeta externa del móvil.
Esta opción viene sobre todo por la posibilidad de efectuar backups de cara a cambiar de teléfono. Una vez está en su directorio, llamado LectorRss en la raiz de la tarjeta, puedes o poner esta en tu nuevo teléfono para importarla de nuevo desde el programa o guardarla donde quieras y luego grabarla en la nueva tarjeta, en la ruta que he dicho antes (raiz de la sd, directorio LectorRss), ten en cuenta que hay tres ficheros en ese directorio: el fichero sqlite, que es la base de datos, y dos xml que son las opciones generales del programa y el que indica que canales están ligados a nuevas y/o se autoactualizan.
En cuanto a como está esto hecho, bueno he de reconocer que, una vez más he buscado por internet y he adaptado algo el código que he encontrado (apunte mental:conserva los enlaces de los que te sirves). Tanto para exportar como para importar he creado un par de métodos, uno para cada caso, que me sirven para controlar si la cosa ha ido bien o no. Empezamos con exportar:

	public boolean exportarBaseDeDatos(){
		if(!crearFicherosExportar("databases", "ServiciosRSS", ".sqlite")
		|| !crearFicherosExportar("shared_prefs", "opGenerales.xml", null)
        || !crearFicherosExportar("shared_prefs", "opciones.xml", null)){
			return false;
		}else return true;
	}//Fin exportarBaseDeDatos();

	boolean crearFicherosExportar(String directorio, String fichero, String terminacion){
		File serviciosRssPath = new File(Environment.getDataDirectory()+"/data/org.jmtu.lectorrss/"+directorio+"/"+fichero) ;
		File dirExp = null;
		if(android.os.Build.VERSION.SDK_INT 			dirExp = new File(Environment.getExternalStorageDirectory()+"/LectorRss", "");
		}else{
			dirExp = new File(Environment.getExternalStorageDirectory()+"/LectorRss", "");
		}
		if (!dirExp.exists()) {
            dirExp.mkdirs();
         }
		File file = null;
		if(terminacion != null){
			file = new File(dirExp, serviciosRssPath.getName()+terminacion);
		}else{
			file = new File(dirExp, serviciosRssPath.getName());
		}

        try {
           file.createNewFile();
           this.copyFile(serviciosRssPath, file);

        } catch (IOException e) {
        	return false;
        }
        return true;
	}//Fin crearFicherosExportar();

	void copyFile(File src, File dst) throws IOException {
        FileChannel inChannel = new FileInputStream(src).getChannel();
        FileChannel outChannel = new FileOutputStream(dst).getChannel();
        try {
           inChannel.transferTo(0, inChannel.size(), outChannel);
        } finally {
           if (inChannel != null)
              inChannel.close();
           if (outChannel != null)
              outChannel.close();
        }
     }//Fin copyFile();

Como se puede ver el método de control es algo más que eso. Se encarga de pasar los parámetros adecuados al que ha de hacer la copia de los tres ficheros que he mencionado anteriormente.
Aquí llamamos a crearFicherosExportar() y los parámetros son directorio, que hace referencia al directorio donde se encuentra el fichero a leer, fichero el propio fichero y terminación vale en este caso de manera exclusiva para el nombre de la base de datos, pues como se ve los ficheros de opciones ya llevan esta por sí mismos.
Con estos parámetros, excluyendo el de terminación, creamos un objeto de tipo File con el que apuntaremos al fichero a leer y, por otra parte, creamos el directorio donde lo vamos a crear. Si este existe no lo creamos, lo usamos y ya.
Para crear este directorio de destino al principio miraba la versión de Android que se estaba usando, y dependiendo de esta usaba una ruta u otra, finalmente, como se puede ver, acabé usando la misma sea el caso que sea, así que esa comprobación ya sobra, pero como en otros casos puede ir bien la dejo de ejemplo.
Más tarde creamos otro objeto tipo File con el directorio que habíamos creado más el nombre del fichero y la terminación, si es que corresponde usarla. Este será el fichero destino finalmente.
Por último llamamos al método copyFile() (este sí está sin ningún tipo de modificación por mi parte) donde se efectúa la copia y así tenemos salvados los datos en nuestra tarjeta…
Por cierto, cada vez que se encuentra con un problema devuelve false y, aunque haya podido grabar alguno de los ficheros,
Para importar tenemos un primer método idéntico al exportarBaseDeDatos(), pero llamando al siguiente método:

	boolean crearFicherosImportar(String directorio, String fichero, String terminacion){
		File bdDir = null;
		byte[] buffer;
		int length;
			if(terminacion != null){
				bdDir = new File(Environment.getExternalStorageDirectory()+"/LectorRss/"+fichero+terminacion);
			}else{
				bdDir = new File(Environment.getExternalStorageDirectory()+"/LectorRss/"+fichero);
			}
		
		if(!bdDir.exists()){
			return false;
		}else{
			InputStream origen = null;
			OutputStream destino = null;
			try{
				origen = new BufferedInputStream(new FileInputStream(bdDir));
				destino = new FileOutputStream(Environment.getDataDirectory()+"/data/org.jmtu.lectorrss/"+directorio+'/'+fichero);
				buffer = new byte[1024];
		    	try {
					while ((length = origen.read(buffer))>0){
						try {
							destino.write(buffer, 0, length);
						} catch (IOException e) {
							return false;
						}
					}
					canales = apoyo.getCanales(serviciosRSS);
				} catch (IOException e) {
					return false;
				}
			}catch(FileNotFoundException fnfe){
				return false;
			}finally{
				if(origen != null){
					try {
						destino.flush();
						destino.close();
						origen.close();
					} catch (IOException e) {
						return false;
					}
				}
			}
		}
		return true;
	}

Y esta parte que es exactamente lo mismo, pero distinto. Ahora es cuando me toca depurar el código y quitar duplicidades, intentar ponerlo más sencillo y esas cositas que irán explicadas en…¿no sabeis donde? En el tutorial sobre LectorRss… y puedo prometer y prometo (es que uno ya tiene cierta edad y se notan en las bromas) que va en serio.
También creo que si el programa sigue creciéndo tendré que acabar haciendo un manual de usuario aquí, en la web, ya veremos.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s