Autore Topic: [facile] Comunicare con un server ftp  (Letto 19493 volte)

Offline dodopepper

  • Utente junior
  • **
  • Post: 124
  • Respect: +4
    • Mostra profilo
  • Dispositivo Android:
    HTC Magic 32a black
[facile] Comunicare con un server ftp
« il: 20 Aprile 2010, 18:52:58 CEST »
+4
Livello di difficoltà: facile
Versione SDK utilizzata: 2.1
Link al file compresso del progetto eclipse: file in allegato

In primis abbiate pietà, è il mio primo tutorial e programmo per Android da una settimana scarsa!

Il seguente tutorial ha come obiettivo di mostrare il modo per inviare un file ad un server FTP, il download di un file non è attualmente mostrato nel tutorial, provvederò forse più avanti ad aggiungerlo.
 

Prima di iniziare a illustrare il codice avrete bisogno di scaricare  le librerie necessarie all'implementazione di un client FTP da integrare nella vostra applicazione android (il file .jar necessario è allegato alla discussione).
Detto questo la prima cosa da fare è aggiungere le suddette librerie al nostro progetto: clicchiamo su Project, poi Proprietis, selezioniamo dunque Java Build Path e poi Libraries infine scegliamo Add External JARs e selezioniamo il file commons-net.jar dal path in cui l'abbiamo salvato.

Altra operazione preliminare è aggiungere le permission per INTERNET nell'Android Manifest.

L'applicazione non fa nulla di particolarmente speciale, semplicemente istanzia un oggetto di tipo FtpClient e sfrutta le relative primitive la cui documentazione potete trovare nel link indicato in bibliografia.

Il codice è abbastanza commentato, spero sia chiaro

(ricorda di allegare il file compresso contenente il progetto eclipse o di indicare un link dove poterlo scaricare)

Sorgenti:

Codice (Java): [Seleziona]
package it.dodopepper.tutorial.ftpclient;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;

public class FtpClient extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView risposta = (TextView) findViewById(R.id.RispostaServer);
        //Il seguente codice dovrebbe implementare l'upload del file verso il server ftp
        FTPClient client= new FTPClient();
        try {
                InetAddress indirizzo = InetAddress.getByName("indirizzo o url del server ftp");
                client.connect(indirizzo);
                risposta.setText(client.getReplyString());
                        //aperta la connessione al server procedo al login
                        boolean loggato=client.login("username", "password");
                        if(loggato==true) risposta.append(" ....login effettuato");
                        else risposta.append("...login fallito");
                        //apro il file contenuto nel path /sdcard come stream
                        client.setFileType(FTP.BINARY_FILE_TYPE); // imposto il tipo di dati, da modificare a seconda dell'utilità
                        File sdcardDir = Environment.getExternalStorageDirectory(); //dato che il mio file era sulla sd prendo il riferimento alla memoria       esterna
                        File file = new File(sdcardDir,"fotografia.jpeg"); //prendo il riferimento al file salvato sulla sd
                        FileInputStream fis = new FileInputStream(file);//creo uno stream in input a partire dal mio file
                       
                        //risposta.append("...path file: " + file.getPath()); //questa istruzione la usavo per test, la lascio casomai dovesse servire, stampa semplicemente il path del file che voglio uploadare
                       
                        boolean upload_ok=client.storeFile("fotografia.jpeg", fis);
                        fis.close();//procedo alla chiusura dello stream, infatti storeFile non chiude fis
                        if(upload_ok==true)risposta.append("  ..... upload ok");
                        else risposta.append("....upload fallito, errore: " + upload_ok);

                } catch (SocketException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
    }
}

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent">
<TextView  
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="...in attesa di risposta"
   android:id="@+id/RispostaServer"/>
</LinearLayout>

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="it.dodopepper.tutorial.ftpclient"
     android:versionCode="1"
     android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".FtpClient"
                 android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>

Bibliografia:

« Ultima modifica: 20 Aprile 2010, 19:13:05 CEST da JD, Reason: Sistemata la bibliografia »

Offline didodede

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung i5500
  • Sistema operativo:
    Windows 7
Re:[facile] Comunicare con un server ftp
« Risposta #1 il: 28 Aprile 2011, 23:45:21 CEST »
0
il tutorial è ottimo, ma non riesco a far funzionare l'applicazione per intero. Mi dice che è stato effettuato il login, però poi mi dà eccezione: FileNotFoundException (mnt/sdcard/fotografia.jpg ) Permission denied.

Eppure ho aggiunto i permessi al manifest. Cosa può essere? Please help..

Offline 7h38ugg3r

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1200
  • Respect: +133
    • riccardofischetti
    • th38ugg3r
    • @7h38ugg3r
    • Mostra profilo
  • Dispositivo Android:
    Galaxy-S GT I-9000/ ASUS Eee Pad Transformer
  • Play Store ID:
    Riccardo Fischetti
  • Sistema operativo:
    OS X Lion / Linux Mint 11 (Katya)
Re:[facile] Comunicare con un server ftp
« Risposta #2 il: 29 Aprile 2011, 09:53:49 CEST »
0
hai messo il permesso per accedere alla sd?
7h38ugg3r<=>thebugger
Non conosci Java? Allora sei nel posto sbagliato!

http://www.androidpatterns.com/

Offline didodede

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung i5500
  • Sistema operativo:
    Windows 7
Re:[facile] Comunicare con un server ftp
« Risposta #3 il: 29 Aprile 2011, 14:23:21 CEST »
0
I permessi aggiunti sono: INTERNET e WRITE_EXTERNAL_STORAGE. Devo aggiungerne altri?

Offline Nicola_D

  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:[facile] Comunicare con un server ftp
« Risposta #4 il: 29 Aprile 2011, 14:29:16 CEST »
0
prova con READ_EXTERNAL_STORAGE
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline didodede

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung i5500
  • Sistema operativo:
    Windows 7
Re:[facile] Comunicare con un server ftp
« Risposta #5 il: 30 Aprile 2011, 12:56:54 CEST »
0
ho provato ma non esiste quel permesso...ti posto il manifest...sperando di risolvere il problema!

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.ftp"
     android:versionCode="1"
     android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>


    <application android:icon="@drawable/icon" android:label="@string/app_name" android:permission="android.permission.INTERNET">
        <activity android:name=".FTPActivity"
                 android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

« Ultima modifica: 02 Maggio 2011, 09:21:23 CEST da 7h38ugg3r »

Offline nero84

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Motorola Defy
Re:[facile] Comunicare con un server ftp
« Risposta #6 il: 06 Giugno 2011, 00:36:26 CEST »
0
il tutorial è ottimo, ma non riesco a far funzionare l'applicazione per intero. Mi dice che è stato effettuato il login, però poi mi dà eccezione: FileNotFoundException (mnt/sdcard/fotografia.jpg ) Permission denied.

Eppure ho aggiunto i permessi al manifest. Cosa può essere? Please help..


Hai controllato che il file "fotografia.jpg" sia presente nella root directory della tua sdcard?



In ogni caso vorrei segnalare che se il server FTP lavora in modo passivo va eseguito il metodo

Codice (Java): [Seleziona]
client.enterLocalPassiveMode();
altrimenti non funziona e restituisce un errore, il più delle volte un

Codice: [Seleziona]
java.net.SocketException: Connection reset by peer
o si blocca indefinitamente sulla

Codice (Java): [Seleziona]
client.storeFile("fotografia.jpeg", fis);
Grazie del tutorial comunque, ben fatto! ;)
« Ultima modifica: 06 Giugno 2011, 02:35:23 CEST da nero84 »

Offline megauni

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    LG Optimus Black
  • Sistema operativo:
    Windows 7
Re:[facile] Comunicare con un server ftp
« Risposta #7 il: 12 Ottobre 2011, 16:01:15 CEST »
0

Ciao!


Ottima guida dodopepper! purtroppo però non riesco a connertmi al server, rimane sempre in attesa di risposta..


dovrei connettermi all'host altervista, se riusciste a darmi una mano a risolvere questo piccolo problemino :)


PS: ho messo i permessi nel manifest.xml e ho usato sia l'emulatore che il dispositivo fisico.


Grazie a tutti

Offline Nicola_D

  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:[facile] Comunicare con un server ftp
« Risposta #8 il: 12 Ottobre 2011, 16:11:52 CEST »
0
altervista  mi pare vada solo in mod passiva
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline megauni

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    LG Optimus Black
  • Sistema operativo:
    Windows 7
Re:[facile] Comunicare con un server ftp
« Risposta #9 il: 12 Ottobre 2011, 16:14:56 CEST »
0
si ho provato a inserire anche la stringa proposta nel messeggio qua sopra anche se provando da 2 gg a programmare android non so esattamente qual'è il punto giusto dove inserirla.

sai per caso come dovrei inserire l'indirizzo per l'ftp di altervista? del tipo tuonome@altervista.org come in filezilla o con ftp://tuonome@altervista.org:21

grazie

Offline khyn

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
Re:[facile] Comunicare con un server ftp
« Risposta #10 il: 14 Novembre 2011, 15:29:27 CET »
0
Salve a tutti, è il mio primo post sul forum per cui... Clemenza!  ;-)

Dunque, ho implementato il codice qui riportato e funziona alle perfezione in modalità passiva su un account Altervista.
Però, per il progetto di app che ho in mente (un tester della velocità di download/upload), mi occorre un "listener" che - a quanto pare - le librerie Apache non prevedono per le connessioni FTP (correggetemi se non vi risulta). Inoltre, il codice ha un effetto di lock sul file sino al completo trasferimento. Di librerie ne ho visionate altre ma il problema resta...
Come posso fare per rilevare la velocità ed anche la percentuale di file trasferita a intervalli di qualche millisecondo? Ciò mi tornerebbe utile anche per dare un'evidenza grafica tramite una barra di avanzamento.

Grazie in anticipo!  :-)

Offline megauni

  • Nuovo arrivato
  • *
  • Post: 16
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    LG Optimus Black
  • Sistema operativo:
    Windows 7
Re:[facile] Comunicare con un server ftp
« Risposta #11 il: 14 Novembre 2011, 17:49:29 CET »
0
ciao khyn,

io purtroppo non so come aiutarti in questo tuo problema ma leggendo che sei riuscito a fare il collegamento con l'account altervista...che io non sono riuscito a fare...mi diresti a grandi linee cosa hai inserito nei dati necessari?
Off-Topic:

Grazie e scusa se ti ho dato una falsa speranza di una risposta alla tua domanda :)

Offline khyn

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
Re:[facile] Comunicare con un server ftp
« Risposta #12 il: 21 Novembre 2011, 01:42:07 CET »
0
Ciao Megauni, scusa il ritardo e non preoccuparti per la "falsa speranza"... Prima o poi qualche anima pia mi verrà in aiuto!   O:-)
Quanto al tuo problema, questa è la parte di codice utile al login:
               
Codice (Java): [Seleziona]
FTPClient client = new FTPClient();
                try {
                        InetAddress indirizzo = InetAddress
                                        .getByName("www.tuonome.altervista.org");
                        client.connect(indirizzo);
                        Log.v(",", client.getReplyString());
                        boolean loggato = client.login("tuoid", "password");
                       //ecc.ecc....

Poi ricordati di inserire:       
Codice (Java): [Seleziona]
 client.enterLocalPassiveMode();
Spero di esserti stato utile.  ;-)

Quanto a me, sono riuscito a rilevare la velocità di connessione ma ho qualche difficoltà con l'implementazione della barra di avanzamento e nell'inserire dei timeout relativi a:
- connessione con il server (onde evitare che in caso di mancata login il processo rimanga in attesa perenne);
- operazione di upload (per impedire che venga caricato sino all'ultimo byte in caso di connessione lenta; cosa ininfluente ai fini della misura).
« Ultima modifica: 21 Novembre 2011, 01:59:20 CET da khyn »

Offline alexAndroid

  • Utente normale
  • ***
  • Post: 185
  • Respect: +27
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy Giò
  • Sistema operativo:
    Ubuntu 11.10; Windows XP
Re:[facile] Comunicare con un server ftp
« Risposta #13 il: 25 Novembre 2011, 12:07:23 CET »
0
Salve a tutti,
sono interessato anch'io a tali argomenti, perciò vorrei rimanerne aggiornato e, nel caso in cui io avanzassi, aggiornare anche voi sugli sviluppi.
Sei stato aiutato oppure il tuo problema è stato risolto? Allora premi il tasto THANKS E' un modo utile e carino per ringraziare chi ti è stato di aiuto.

Offline alexAndroid

  • Utente normale
  • ***
  • Post: 185
  • Respect: +27
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy Giò
  • Sistema operativo:
    Ubuntu 11.10; Windows XP
Re:[facile] Comunicare con un server ftp
« Risposta #14 il: 04 Dicembre 2011, 14:51:49 CET »
0
Sono passati più di dieci giorni dall'ultimo post.
Intanto vengo a dirvi che al momento sono riuscito a collegare ed a far comunicare la mia applicazione Android con un Server FTP. [Se a qualcuno servisse una mano a riguardo, gliela darei volentieri]
Però ho un altro problema. Mi serve passare l'oggetto ClientFTP da l'Activity1 a l'Activity2. Questo è possibile passando tale oggetto attraverso gli Intent, ma implementando la classe ClientFTP come Serializable.
Il problema è che non basta aggiungere implements Serializable ma bisogna fare qualcos'altro. Non saprei cosa. Intanto posto un pò di codice e il LOGCAT. Se qualcuno sapesse darmi una mano è ampiamente ringraziato.
Codice: [Seleziona]
12-04 14:49:08.324: E/AndroidRuntime(8617): FATAL EXCEPTION: main
12-04 14:49:08.324: E/AndroidRuntime(8617): java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = prova.ftp.ClientFTP)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.os.Parcel.writeSerializable(Parcel.java:1160)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.os.Parcel.writeValue(Parcel.java:1114)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.os.Parcel.writeMapInternal(Parcel.java:479)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.os.Bundle.writeToParcel(Bundle.java:1552)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.os.Parcel.writeBundle(Parcel.java:493)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.content.Intent.writeToParcel(Intent.java:5549)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:1290)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.app.Instrumentation.execStartActivity(Instrumentation.java:1373)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.app.Activity.startActivityForResult(Activity.java:2817)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.app.Activity.startActivity(Activity.java:2923)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at prova.ftp.AndroidFTPClientActivity.startFtpManageActivity(AndroidFTPClientActivity.java:67)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at prova.ftp.AndroidFTPClientActivity.access$5(AndroidFTPClientActivity.java:60)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at prova.ftp.AndroidFTPClientActivity$1.onClick(AndroidFTPClientActivity.java:44)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.view.View.performClick(View.java:2408)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.view.View$PerformClick.run(View.java:8816)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.os.Handler.handleCallback(Handler.java:587)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.os.Handler.dispatchMessage(Handler.java:92)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.os.Looper.loop(Looper.java:123)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.app.ActivityThread.main(ActivityThread.java:4633)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.lang.reflect.Method.invokeNative(Native Method)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.lang.reflect.Method.invoke(Method.java:521)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at dalvik.system.NativeStart.main(Native Method)
12-04 14:49:08.324: E/AndroidRuntime(8617): Caused by: java.io.NotSerializableException: org.apache.commons.net.ftp.FTPClient
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1547)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1859)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1701)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1665)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:1153)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:420)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1251)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1587)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1859)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1701)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1665)
12-04 14:49:08.324: E/AndroidRuntime(8617):         at android.os.Parcel.writeSerializable(Parcel.java:1155)
12-04 14:49:08.324: E/AndroidRuntime(8617):         ... 23 more

Sei stato aiutato oppure il tuo problema è stato risolto? Allora premi il tasto THANKS E' un modo utile e carino per ringraziare chi ti è stato di aiuto.