Приложение Android подключается к FTP-серверу на Java

Я пытаюсь создать приложение для Android с возможностью подключения к указанному FTP-серверу на Java. Операция подключения была выполнена в FTPconnection class, а сетевой вызов FTP был отделен от основного потока через FtpTask реализация класса.

Экспериментальная реализация

  • Название проекта: FTPConnectionTest

  • FTPconnection реализация класса

    package com.example.ftpconnectiontest;
    
    import android.util.Log;
    
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    import org.apache.commons.net.SocketClient;
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    public class FTPconnection {
    
        private static final String FTPHostName = "Hostname";
        private static final int FTPPort = 21;
        private static final String FTPUsername = "Username";
        private static final String FTPPassword = "Password";
    
        public FTPconnection()
        {
    
        }
    
        public FTPClient connectftp()
        {
            //  Reference: https://stackoverflow.com/a/8761268/6667035
            FTPClient ftp = new FTPClient();
            try {
                //  Reference: https://stackoverflow.com/a/55950845/6667035
                //  The argument of `FTPClient.connect` method is hostname, not URL.
                ftp.connect(FTPHostName, FTPPort);
                boolean status = ftp.login(FTPUsername, FTPPassword);
                if (status)
                {
                    ftp.enterLocalPassiveMode();
                    ftp.setFileType(FTP.BINARY_FILE_TYPE);
                    ftp.sendCommand("OPTS UTF8 ON");
                }
                System.out.println("status : " + ftp.getStatus());
            } catch (UnknownHostException ex) {
                ex.printStackTrace();
            } catch (SocketException en) {
                en.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return ftp;
        }
    }
    
  • FtpTask реализация класса

    //  AsyncTask must be subclassed to be used. The subclass will override at least one method
    //  `doInBackground(Params...)`, and most often will override a second one `onPostExecute(Result)`
    //  Reference: https://developer.android.com/reference/android/os/AsyncTask?authuser=4
    //  Reference: https://stackoverflow.com/a/12447497/6667035
    private class FtpTask extends AsyncTask<Void, Void, FTPClient> {
        //  `doInBackground` invoked on the background thread immediately after `onPreExecute()`
        //  finishes executing. This step is used to perform background computation
        //  that can take a long time. The parameters of the asynchronous task are
        //  passed to this step. The result of the computation must be returned by
        //  this step and will be passed back to the last step. This step can also use
        //  `publishProgress(Progress...)` to publish one or more units of progress.
        //  These values are published on the UI thread, in the `onProgressUpdate(Progress...)`
        //  step.
        protected FTPClient doInBackground(Void... args) {
            FTPconnection ftpConnect = new FTPconnection();
            FTPClient ftp = ftpConnect.connectftp();
            return ftp;
        }
    
        //  `onPostExecute` invoked on the UI thread after the background computation finishes.
        //  The result of the background computation is passed to this step as
        //  a parameter.
        protected void onPostExecute(FTPClient result) {
            Log.v("FTPTask","FTP connection complete");
            ftpClient = result;
            //Where ftpClient is a instance variable in the main activity
            Log.v("Boolean.toString(ftpClient.isConnected())", Boolean.toString(ftpClient.isConnected()));
            ShowToast(Boolean.toString(ftpClient.isConnected()), Toast.LENGTH_SHORT);
        }
    }
    
  • Настройка разрешений пользователя

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    
  • AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.ftpconnectiontest">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.FTPConnectionTest">
            <activity
                android:name=".MainActivity"
                android:exported="true">
                <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 android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    </manifest>
    
  • build.gradle

    plugins {
        id 'com.android.application'
    }
    
    android {
        compileSdk 30
    
        defaultConfig {
            applicationId "com.example.ftpconnectiontest"
            minSdk 26
            targetSdk 30
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }
    
    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        // https://mvnrepository.com/artifact/commons-net/commons-net
        implementation group: 'commons-net', name: 'commons-net', version: '20030805.205232'
        implementation 'androidx.appcompat:appcompat:1.2.0'
        implementation 'com.google.android.material:material:1.3.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.2'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    }
    

Полный код тестирования

MainActivity.java выполнение:

package com.example.ftpconnectiontest;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import org.apache.commons.net.ftp.FTPClient;

public class MainActivity extends AppCompatActivity {

    private FTPClient ftpClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new FtpTask().execute();
    }

    void ShowToast(String Text, int Duration)
    {
        Context context = getApplicationContext();
        CharSequence text = Text;
        int duration = Duration;

        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
    }

    //  AsyncTask must be subclassed to be used. The subclass will override at least one method
    //  `doInBackground(Params...)`, and most often will override a second one `onPostExecute(Result)`
    //  Reference: https://developer.android.com/reference/android/os/AsyncTask?authuser=4
    //  Reference: https://stackoverflow.com/a/12447497/6667035
    private class FtpTask extends AsyncTask<Void, Void, FTPClient> {
        //  `doInBackground` invoked on the background thread immediately after `onPreExecute()`
        //  finishes executing. This step is used to perform background computation
        //  that can take a long time. The parameters of the asynchronous task are
        //  passed to this step. The result of the computation must be returned by
        //  this step and will be passed back to the last step. This step can also use
        //  `publishProgress(Progress...)` to publish one or more units of progress.
        //  These values are published on the UI thread, in the `onProgressUpdate(Progress...)`
        //  step.
        protected FTPClient doInBackground(Void... args) {
            FTPconnection ftpConnect = new FTPconnection();
            FTPClient ftp = ftpConnect.connectftp();
            return ftp;
        }

        //  `onPostExecute` invoked on the UI thread after the background computation finishes.
        //  The result of the background computation is passed to this step as
        //  a parameter.
        protected void onPostExecute(FTPClient result) {
            Log.v("FTPTask","FTP connection complete");
            ftpClient = result;
            //Where ftpClient is a instance variable in the main activity
            Log.v("Boolean.toString(ftpClient.isConnected())", Boolean.toString(ftpClient.isConnected()));
            ShowToast(Boolean.toString(ftpClient.isConnected()), Toast.LENGTH_SHORT);
        }
    }
}

Если есть какие-то улучшения, пожалуйста, дайте мне знать.

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *