En este tutorial vamos a mostrar como crear una aplicación que nos permita subir archivos que se encuentran en la memoria externa a un servidor ftp.
Espero que le guste y no dude en comentar si tiene cualquier duda.
¡ Saludos !
Enlaces de interés:
Código Fuente
Puede descargar si lo desea el código fuente de este proyecto.
Androcode
Aquí se explica de una forma más detallada como subir ficheros a un servidor ftp a través de Apache Commons FTP, se lo recomiendo para que pueda ampliar conocimientos.
Pasos a seguir:
1. Primero tendremos que crear la interfaz gráfica de la aplicación, en este caso será bastante sencilla pues solamente necesitaremos un EditText que recoja el nombre del archivo que se quiere subir y que se encuentra en la memoria externa. Un ejemplo de interfaz sería el siguiente.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_marginTop="14dp" android:text="@string/informarcion_acerca_aplicacon" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/btnSubir" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView1" android:layout_centerHorizontal="true" android:layout_marginTop="136dp" android:text="@string/subir_archivo" /> <EditText android:id="@+id/edtxtNombreArchivo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView1" android:layout_centerHorizontal="true" android:layout_marginTop="67dp" android:ems="10" android:hint="@string/nombre_del_archivo" /> </RelativeLayout>
2. Antes de programas la actividad que acabamos de crear tendremos que crear la clase Ftp que se encargará de gestionar la subida de los archivos ftp. Declaramos antes de nada los campos que vamos a necesitar en esta clase.
/** * Gestiona la subida de ficheros a un servidor FTP * @author José Miguel * */ public class Ftp { //Campos----------------------------------------------------------- private String ip; //Almacena la dirección del servidor private String usuario; //Almacena el nombre de usuario private String contrasena; //Almacena la contraseña del usuario FTPClient ftpClient; //Crea la conexión con el servidor BufferedInputStream buffer; //Crea una buffer de lectura File rutaSd; //Almacena la ruta sd File rutaCompleta; //Almacena la ruta completa del archivo Context context; //Almacena el contexto de la aplicacion //util a la hora de mostrar mensajes //------------------------------------------------------------------
3. Generamos todos los constructores que vamos a necesitar para instanciar la clase.
//Constructores----------------------------------------------------- /** * Crea una instancia de FTP sin credenciales */ public Ftp(String ip, Context context) { //Inicialización de campos this.ip = ip; usuario = null; contrasena = null; ftpClient = null; buffer = null; rutaSd = null; rutaCompleta = null; this.context = context; } /** * Crea una instancia de FTP con credenciales * @param usuario El nombre de usuario * @param contrasena La contraseña de usuario */ public Ftp (String ip, String usuario, String contrasena, Context context){ //Inicialización de campos this.ip = ip; this.usuario = usuario; this.contrasena = contrasena; ftpClient = null; buffer = null; rutaSd = null; rutaCompleta = null; this.context = context; } //------------------------------------------------------------------
4. Seguidamente creamos todos los atributos que vamos a necesitar para acceder a los campos de la clase, los que vamos a necesitar son los siguientes:
//Propiedades------------------------------------------------------- /** * Obtiene el nombre de usuario * @return El nombre de usuario */ public String getUsuario() { return usuario; } /** * Establece el nombre de usuario * @param usuario El nombre de usuario */ public void setUsuario(String usuario) { this.usuario = usuario; } /** * Obtiene la contraseña de usuario * @return La contraseña de usuario */ public String getContrasena() { return contrasena; } /** * Establece la contraseña de usuario * @param contrasena La contraseña de usuario */ public void setContrasena(String contrasena) { this.contrasena = contrasena; } //------------------------------------------------------------------
5. Creamos el método que nos va a permitir hacer login en el servidor ftp antes de poder subir un archivo al servidor.
//------------------------------------------------------------------ /** * Realiza el login en el servidor * @param usuario El nombre de usuario * @param contrasena La contraseña de usuario * @return Verdad en caso de haber realizado login correctamente * @throws SocketException * @throws IOException */ public boolean Login (String usuario, String contrasena) throws SocketException, IOException{ //Almacena los valores en la clase this.usuario = usuario; this.contrasena = contrasena; //Establece conexión con el servidor Toast.makeText(context, "Conectando . . .", Toast.LENGTH_SHORT).show(); try{ ftpClient = new FTPClient(); ftpClient.connect(ip); } catch (Exception e){ //Informa al usuario Toast.makeText(context, "Imposible conectar . . .", Toast.LENGTH_SHORT).show(); return false; //En caso de que no sea posible la conexion } //Hace login en el servidor if (ftpClient.login(usuario, contrasena)){ //Informa al usuario Toast.makeText(context, "Login correcto . . .", Toast.LENGTH_SHORT).show(); return true; //En caso de login correcto } else{ //Informa al usuario Toast.makeText(context, "Login incorrecto . . .", Toast.LENGTH_SHORT).show(); return false; //En caso de login incorrecto } }
6. Creamos también el método que nos va a permitir subir un archivo al servidor en caso de que el usuario se haya logeado correctamente.
/** * Sube un archivo al servidor FTP si previamente se ha hecho login correctamente * @param nombreArchivo Nombre del archivo que se quiere subir * @return Verdad en caso de que se haya subido con éxito * @throws IOException */ public boolean SubirArchivo (String nombreArchivo) throws IOException{ ftpClient.enterLocalActiveMode(); ftpClient.setFileType(FTP.BINARY_FILE_TYPE); //Cambia la carpeta Ftp if (ftpClient.changeWorkingDirectory("ftp")){ //Informa al usuario Toast.makeText(context, "Carpeta ftp cambiada . . .", Toast.LENGTH_SHORT).show(); //Obtiene la dirección de la ruta sd Toast.makeText(context, "Ruta SD obtenida . . .", Toast.LENGTH_SHORT).show(); rutaSd = Environment.getExternalStorageDirectory(); //Obtiene la ruta completa donde se encuentra el archivo Toast.makeText(context, "Ruta completa archivo obtenida . . .", Toast.LENGTH_SHORT).show(); rutaCompleta = new File(rutaSd.getAbsolutePath(), nombreArchivo); //Crea un buffer hacia el servidor de subida buffer = new BufferedInputStream(new FileInputStream(rutaCompleta)); if (ftpClient.storeFile(nombreArchivo, buffer)){ //Informa al usuario Toast.makeText(context, "Archivo subido . . .", Toast.LENGTH_SHORT).show(); buffer.close(); //Cierra el bufer return true; //Se ha subido con éxito } else{ //Informa al usuario Toast.makeText(context, "Imposible subir archivo . . .", Toast.LENGTH_SHORT).show(); buffer.close(); //Cierra el bufer return false; //No se ha subido } } else{ //Informa al usuario Toast.makeText(context, "Carpeta ftp imposible cambiar . . .", Toast.LENGTH_SHORT).show(); return false; //Imposible cambiar de directo en servidor ftp } }
7. Tras terminar con la clase ftp nos vamos a la clase que maneja la actividad principal donde vamos a declarar los campos que vamos a necesitar.
public class SubirActivity extends Activity { //Campos---------------------------------------------------- EditText nombreArhivo; // Almacena el id del componente donde está localizado el nombre del archivo a subir Button subir; // Almacena el id del componente donde está localizado el botón para subir el archivo //Credenciales String ip; //Almacena la direción ip del servidor String usuario; //Almacena el usuario String contrasena; //Almacena la contraseña Ftp ftp; //Instancia manejador ftp //-----------------------------------------------------------
8. Y simplemente en el método onCreate() inicializamos lo campos, creamos el evento del botón y programamos el botón para que pueda usar la clase que hemos definido anteriormente para subir el fichero que el usuario ha indicado.
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_subir); //Inicializa las credenciales ip = "192.168.0.1"; usuario = "admin"; contrasena ="admin"; //Establece los ids de la vista nombreArhivo = (EditText) findViewById(R.id.edtxtNombreArchivo); subir = (Button) findViewById(R.id.btnSubir); //Evento OnClick (btnSubir) subir.setOnClickListener(new OnClickListener() { public void onClick(View v) { //Establece un servidor ftp = new Ftp(ip, usuario, contrasena, getApplicationContext()); //Realiza login en el servidor try { ftp.Login(usuario, contrasena); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //Sube el archivo al servidor try { ftp.SubirArchivo(nombreArhivo.getText().toString()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); }
FIN
memarca imposible conectar le agregue mis datos del servidor ftp y nada
ResponderEliminarHola José muchas gracias por tu ayuda
ResponderEliminarMe sale un problema al tratar de subir un archivo, me puedes ayudar con una aplicacion cliente ftp y ayudarme para lograr subir el archivo sin error
Mil gracias!!
Excelente justo lo que necesitaba
ResponderEliminarno funciona! da un error en el método ftp.Login()
ResponderEliminaranda perfecto, mi duda es si se puede cambiar el puerto en vez de ir al 21, no lo estoy logrando
ResponderEliminarSabes donde esta la linea que configura el puerto? no la encuentro...
EliminarAdemas tengo un error de android.os.NetworkOnMainThreadException
No responde ninguna consulta...es buenisimo el tipo, jajajaja
ResponderEliminar