Skip to main content
Update build.gradle
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
  • Project name: FTPDownloadFile

  • FTPconnection class implementation

    package com.example.ftpdownloadfile;
    
    import android.util.Log;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class FTPconnection {
    
        private native String getHostname();
        private native String getUsername();
        private native String getPassword();
    
        private static String FTPHostName = "";
        private static final int FTPPort = 21;
        private static String FTPUsername = "";
        private static String FTPPassword = "";
    
        public FTPconnection()
        {
            FTPHostName = getHostname();
            FTPUsername = getUsername();
            FTPPassword = getPassword();
        }
    
        //  Reference: https://stackoverflow.com/a/24605713/6667035
        public Boolean downloadAndSaveFile(String filename, File localFile)
                throws IOException {
            String LOG_TAG = "FTPconnection_download";
            FTPClient ftp = null;
            try {
                ftp = new FTPClient();
                ftp.connect(FTPHostName, FTPPort);
                Log.d(LOG_TAG, "Connected. Reply: " + ftp.getReplyString());
    
                ftp.login(FTPUsername, FTPPassword);
                Log.d(LOG_TAG, "Logged in");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                Log.d(LOG_TAG, "Downloading");
                ftp.enterLocalPassiveMode();
    
                OutputStream outputStream = null;
                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(
                            localFile));
                    success = ftp.retrieveFile(filename, outputStream);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
    
                return success;
            } finally {
                if (ftp != null) {
                    ftp.logout();
                    ftp.disconnect();
                }
            }
        }
    }
    
  • ftpdownloadfile.cpp

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getHostname(JNIEnv *env, jobject thiz) {
        std::string output = "Hostname";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getUsername(JNIEnv *env, jobject thiz) {
        std::string output = "Username";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getPassword(JNIEnv *env, jobject thiz) {
        std::string output = "Password";
        return env->NewStringUTF(output.c_str());
    }
    
  • ExecutorService for new thread

    ExecutorService executor = Executors.newSingleThreadExecutor();
          executor.submit(() -> {
              String threadName = Thread.currentThread().getName();
              showToast(threadName, Toast.LENGTH_SHORT);
              FTPconnection ftpConnect = new FTPconnection();
              final String LOG_TAG = "executor";
              try {
                  String filename = "test.txt";
                  Log.v(LOG_TAG,"Preparing to download " + filename);
                  var result  = ftpConnect.downloadAndSaveFile(filename, Paths.get(getApplicationInfo().dataDir + "/" + filename).toFile());
                  if (result == false) {
                      Log.v(LOG_TAG,"Fail to download " + filename + "!");
                  } else {
                      Log.v(LOG_TAG,"Download " + filename + " successfully!");
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          });
    
  • User permission setting

    <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.ftpdownloadfile">
    
        <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.FTPDownloadFile">
            <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 31
    
        defaultConfig {
            applicationId "com.example.ftpdownloadfile"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags ''
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
        externalNativeBuild {
            cmake {
                path file('src/main/cpp/CMakeLists.txt')
                version '3.18.1'
            }
        }
    }
    
    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.46.1'
        implementation 'com.google.android.material:material:1.511.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.3'4'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'5'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.45.0'1'
    }
    
  • Project name: FTPDownloadFile

  • FTPconnection class implementation

    package com.example.ftpdownloadfile;
    
    import android.util.Log;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class FTPconnection {
    
        private native String getHostname();
        private native String getUsername();
        private native String getPassword();
    
        private static String FTPHostName = "";
        private static final int FTPPort = 21;
        private static String FTPUsername = "";
        private static String FTPPassword = "";
    
        public FTPconnection()
        {
            FTPHostName = getHostname();
            FTPUsername = getUsername();
            FTPPassword = getPassword();
        }
    
        //  Reference: https://stackoverflow.com/a/24605713/6667035
        public Boolean downloadAndSaveFile(String filename, File localFile)
                throws IOException {
            String LOG_TAG = "FTPconnection_download";
            FTPClient ftp = null;
            try {
                ftp = new FTPClient();
                ftp.connect(FTPHostName, FTPPort);
                Log.d(LOG_TAG, "Connected. Reply: " + ftp.getReplyString());
    
                ftp.login(FTPUsername, FTPPassword);
                Log.d(LOG_TAG, "Logged in");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                Log.d(LOG_TAG, "Downloading");
                ftp.enterLocalPassiveMode();
    
                OutputStream outputStream = null;
                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(
                            localFile));
                    success = ftp.retrieveFile(filename, outputStream);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
    
                return success;
            } finally {
                if (ftp != null) {
                    ftp.logout();
                    ftp.disconnect();
                }
            }
        }
    }
    
  • ftpdownloadfile.cpp

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getHostname(JNIEnv *env, jobject thiz) {
        std::string output = "Hostname";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getUsername(JNIEnv *env, jobject thiz) {
        std::string output = "Username";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getPassword(JNIEnv *env, jobject thiz) {
        std::string output = "Password";
        return env->NewStringUTF(output.c_str());
    }
    
  • ExecutorService for new thread

    ExecutorService executor = Executors.newSingleThreadExecutor();
          executor.submit(() -> {
              String threadName = Thread.currentThread().getName();
              showToast(threadName, Toast.LENGTH_SHORT);
              FTPconnection ftpConnect = new FTPconnection();
              final String LOG_TAG = "executor";
              try {
                  String filename = "test.txt";
                  Log.v(LOG_TAG,"Preparing to download " + filename);
                  var result  = ftpConnect.downloadAndSaveFile(filename, Paths.get(getApplicationInfo().dataDir + "/" + filename).toFile());
                  if (result == false) {
                      Log.v(LOG_TAG,"Fail to download " + filename + "!");
                  } else {
                      Log.v(LOG_TAG,"Download " + filename + " successfully!");
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          });
    
  • User permission setting

    <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.ftpdownloadfile">
    
        <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.FTPDownloadFile">
            <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 31
    
        defaultConfig {
            applicationId "com.example.ftpdownloadfile"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags ''
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
        externalNativeBuild {
            cmake {
                path file('src/main/cpp/CMakeLists.txt')
                version '3.18.1'
            }
        }
    }
    
    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.4.1'
        implementation 'com.google.android.material:material:1.5.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
    
  • Project name: FTPDownloadFile

  • FTPconnection class implementation

    package com.example.ftpdownloadfile;
    
    import android.util.Log;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class FTPconnection {
    
        private native String getHostname();
        private native String getUsername();
        private native String getPassword();
    
        private static String FTPHostName = "";
        private static final int FTPPort = 21;
        private static String FTPUsername = "";
        private static String FTPPassword = "";
    
        public FTPconnection()
        {
            FTPHostName = getHostname();
            FTPUsername = getUsername();
            FTPPassword = getPassword();
        }
    
        //  Reference: https://stackoverflow.com/a/24605713/6667035
        public Boolean downloadAndSaveFile(String filename, File localFile)
                throws IOException {
            String LOG_TAG = "FTPconnection_download";
            FTPClient ftp = null;
            try {
                ftp = new FTPClient();
                ftp.connect(FTPHostName, FTPPort);
                Log.d(LOG_TAG, "Connected. Reply: " + ftp.getReplyString());
    
                ftp.login(FTPUsername, FTPPassword);
                Log.d(LOG_TAG, "Logged in");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                Log.d(LOG_TAG, "Downloading");
                ftp.enterLocalPassiveMode();
    
                OutputStream outputStream = null;
                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(
                            localFile));
                    success = ftp.retrieveFile(filename, outputStream);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
    
                return success;
            } finally {
                if (ftp != null) {
                    ftp.logout();
                    ftp.disconnect();
                }
            }
        }
    }
    
  • ftpdownloadfile.cpp

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getHostname(JNIEnv *env, jobject thiz) {
        std::string output = "Hostname";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getUsername(JNIEnv *env, jobject thiz) {
        std::string output = "Username";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getPassword(JNIEnv *env, jobject thiz) {
        std::string output = "Password";
        return env->NewStringUTF(output.c_str());
    }
    
  • ExecutorService for new thread

    ExecutorService executor = Executors.newSingleThreadExecutor();
          executor.submit(() -> {
              String threadName = Thread.currentThread().getName();
              showToast(threadName, Toast.LENGTH_SHORT);
              FTPconnection ftpConnect = new FTPconnection();
              final String LOG_TAG = "executor";
              try {
                  String filename = "test.txt";
                  Log.v(LOG_TAG,"Preparing to download " + filename);
                  var result  = ftpConnect.downloadAndSaveFile(filename, Paths.get(getApplicationInfo().dataDir + "/" + filename).toFile());
                  if (result == false) {
                      Log.v(LOG_TAG,"Fail to download " + filename + "!");
                  } else {
                      Log.v(LOG_TAG,"Download " + filename + " successfully!");
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          });
    
  • User permission setting

    <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.ftpdownloadfile">
    
        <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.FTPDownloadFile">
            <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 31
    
        defaultConfig {
            applicationId "com.example.ftpdownloadfile"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags ''
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
        externalNativeBuild {
            cmake {
                path file('src/main/cpp/CMakeLists.txt')
                version '3.18.1'
            }
        }
    }
    
    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.6.1'
        implementation 'com.google.android.material:material:1.11.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.5'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    }
    
Tweeted twitter.com/StackCodeReview/status/1518107469926604801
Update description
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
  • Project name: FTPDownloadFile

  • FTPconnection class implementation

    package com.example.ftpdownloadfile;
    
    import android.util.Log;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class FTPconnection {
    
        private native String getHostname();
        private native String getUsername();
        private native String getPassword();
    
        private static String FTPHostName = "";
        private static final int FTPPort = 21;
        private static String FTPUsername = "";
        private static String FTPPassword = "";
    
        public FTPconnection()
        {
            FTPHostName = getHostname();
            FTPUsername = getUsername();
            FTPPassword = getPassword();
        }
    
        //  Reference: https://stackoverflow.com/a/24605713/6667035
        public Boolean downloadAndSaveFile(String filename, File localFile)
                throws IOException {
            String LOG_TAG = "FTPconnection_download";
            FTPClient ftp = null;
            try {
                ftp = new FTPClient();
                ftp.connect(FTPHostName, FTPPort);
                Log.d(LOG_TAG, "Connected. Reply: " + ftp.getReplyString());
    
                ftp.login(FTPUsername, FTPPassword);
                Log.d(LOG_TAG, "Logged in");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                Log.d(LOG_TAG, "Downloading");
                ftp.enterLocalPassiveMode();
    
                OutputStream outputStream = null;
                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(
                            localFile));
                    success = ftp.retrieveFile(filename, outputStream);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
    
                return success;
            } finally {
                if (ftp != null) {
                    ftp.logout();
                    ftp.disconnect();
                }
            }
        }
    }
    
  • ftpdownloadfile.cpp

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getHostname(JNIEnv *env, jobject thiz) {
        std::string output = "Hostname";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getUsername(JNIEnv *env, jobject thiz) {
        std::string output = "Username";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getPassword(JNIEnv *env, jobject thiz) {
        std::string output = "Password";
        return env->NewStringUTF(output.c_str());
    }
    
  • ExecutorService for new thread

    ExecutorService executor = Executors.newSingleThreadExecutor();
          executor.submit(() -> {
              String threadName = Thread.currentThread().getName();
              showToast(threadName, Toast.LENGTH_SHORT);
              FTPconnection ftpConnect = new FTPconnection();
              final String LOG_TAG = "executor";
              try {
                  String filename = "test.txt";
                  Log.v(LOG_TAG,"Preparing to download " + filename);
                  var result  = ftpConnect.downloadAndSaveFile(filename, Paths.get(getApplicationInfo().dataDir + "/" + filename).toFile());
                  if (result == false) {
                      Log.v(LOG_TAG,"Fail to download " + filename + "!");
                  } else {
                      Log.v(LOG_TAG,"Download " + filename + " successfully!");
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          });
    
  • User permission setting

    <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.ftpdownloadfile">
    
        <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.FTPDownloadFile">
            <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 31
    
        defaultConfig {
            applicationId "com.example.ftpdownloadfile"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags ''
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
        externalNativeBuild {
            cmake {
                path file('src/main/cpp/CMakeLists.txt')
                version '3.18.1'
            }
        }
    }
    
    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.34.1'
        implementation 'com.google.android.material:material:1.45.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.1'3'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
    
  • Project name: FTPDownloadFile

  • FTPconnection class implementation

    package com.example.ftpdownloadfile;
    
    import android.util.Log;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class FTPconnection {
    
        private native String getHostname();
        private native String getUsername();
        private native String getPassword();
    
        private static String FTPHostName = "";
        private static final int FTPPort = 21;
        private static String FTPUsername = "";
        private static String FTPPassword = "";
    
        public FTPconnection()
        {
            FTPHostName = getHostname();
            FTPUsername = getUsername();
            FTPPassword = getPassword();
        }
    
        //  Reference: https://stackoverflow.com/a/24605713/6667035
        public Boolean downloadAndSaveFile(String filename, File localFile)
                throws IOException {
            String LOG_TAG = "FTPconnection_download";
            FTPClient ftp = null;
            try {
                ftp = new FTPClient();
                ftp.connect(FTPHostName, FTPPort);
                Log.d(LOG_TAG, "Connected. Reply: " + ftp.getReplyString());
    
                ftp.login(FTPUsername, FTPPassword);
                Log.d(LOG_TAG, "Logged in");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                Log.d(LOG_TAG, "Downloading");
                ftp.enterLocalPassiveMode();
    
                OutputStream outputStream = null;
                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(
                            localFile));
                    success = ftp.retrieveFile(filename, outputStream);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
    
                return success;
            } finally {
                if (ftp != null) {
                    ftp.logout();
                    ftp.disconnect();
                }
            }
        }
    }
    
  • ftpdownloadfile.cpp

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getHostname(JNIEnv *env, jobject thiz) {
        std::string output = "Hostname";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getUsername(JNIEnv *env, jobject thiz) {
        std::string output = "Username";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getPassword(JNIEnv *env, jobject thiz) {
        std::string output = "Password";
        return env->NewStringUTF(output.c_str());
    }
    
  • ExecutorService for new thread

    ExecutorService executor = Executors.newSingleThreadExecutor();
          executor.submit(() -> {
              String threadName = Thread.currentThread().getName();
              showToast(threadName, Toast.LENGTH_SHORT);
              FTPconnection ftpConnect = new FTPconnection();
              final String LOG_TAG = "executor";
              try {
                  String filename = "test.txt";
                  Log.v(LOG_TAG,"Preparing to download " + filename);
                  var result  = ftpConnect.downloadAndSaveFile(filename, Paths.get(getApplicationInfo().dataDir + "/" + filename).toFile());
                  if (result == false) {
                      Log.v(LOG_TAG,"Fail to download " + filename + "!");
                  } else {
                      Log.v(LOG_TAG,"Download " + filename + " successfully!");
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          });
    
  • User permission setting

    <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.ftpdownloadfile">
    
        <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.FTPDownloadFile">
            <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 31
    
        defaultConfig {
            applicationId "com.example.ftpdownloadfile"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags ''
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
        externalNativeBuild {
            cmake {
                path file('src/main/cpp/CMakeLists.txt')
                version '3.18.1'
            }
        }
    }
    
    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.3.1'
        implementation 'com.google.android.material:material:1.4.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
    
  • Project name: FTPDownloadFile

  • FTPconnection class implementation

    package com.example.ftpdownloadfile;
    
    import android.util.Log;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class FTPconnection {
    
        private native String getHostname();
        private native String getUsername();
        private native String getPassword();
    
        private static String FTPHostName = "";
        private static final int FTPPort = 21;
        private static String FTPUsername = "";
        private static String FTPPassword = "";
    
        public FTPconnection()
        {
            FTPHostName = getHostname();
            FTPUsername = getUsername();
            FTPPassword = getPassword();
        }
    
        //  Reference: https://stackoverflow.com/a/24605713/6667035
        public Boolean downloadAndSaveFile(String filename, File localFile)
                throws IOException {
            String LOG_TAG = "FTPconnection_download";
            FTPClient ftp = null;
            try {
                ftp = new FTPClient();
                ftp.connect(FTPHostName, FTPPort);
                Log.d(LOG_TAG, "Connected. Reply: " + ftp.getReplyString());
    
                ftp.login(FTPUsername, FTPPassword);
                Log.d(LOG_TAG, "Logged in");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                Log.d(LOG_TAG, "Downloading");
                ftp.enterLocalPassiveMode();
    
                OutputStream outputStream = null;
                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(
                            localFile));
                    success = ftp.retrieveFile(filename, outputStream);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
    
                return success;
            } finally {
                if (ftp != null) {
                    ftp.logout();
                    ftp.disconnect();
                }
            }
        }
    }
    
  • ftpdownloadfile.cpp

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getHostname(JNIEnv *env, jobject thiz) {
        std::string output = "Hostname";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getUsername(JNIEnv *env, jobject thiz) {
        std::string output = "Username";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getPassword(JNIEnv *env, jobject thiz) {
        std::string output = "Password";
        return env->NewStringUTF(output.c_str());
    }
    
  • ExecutorService for new thread

    ExecutorService executor = Executors.newSingleThreadExecutor();
          executor.submit(() -> {
              String threadName = Thread.currentThread().getName();
              showToast(threadName, Toast.LENGTH_SHORT);
              FTPconnection ftpConnect = new FTPconnection();
              final String LOG_TAG = "executor";
              try {
                  String filename = "test.txt";
                  Log.v(LOG_TAG,"Preparing to download " + filename);
                  var result  = ftpConnect.downloadAndSaveFile(filename, Paths.get(getApplicationInfo().dataDir + "/" + filename).toFile());
                  if (result == false) {
                      Log.v(LOG_TAG,"Fail to download " + filename + "!");
                  } else {
                      Log.v(LOG_TAG,"Download " + filename + " successfully!");
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          });
    
  • User permission setting

    <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.ftpdownloadfile">
    
        <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.FTPDownloadFile">
            <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 31
    
        defaultConfig {
            applicationId "com.example.ftpdownloadfile"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags ''
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
        externalNativeBuild {
            cmake {
                path file('src/main/cpp/CMakeLists.txt')
                version '3.18.1'
            }
        }
    }
    
    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.4.1'
        implementation 'com.google.android.material:material:1.5.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
    
Update description
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
  • Project name: FTPDownloadFile

  • FTPconnection class implementation

    package com.example.ftpdownloadfile;
    
    import android.util.Log;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class FTPconnection {
    
        private native String getHostname();
        private native String getUsername();
        private native String getPassword();
    
        private static String FTPHostName = "";
        private static final int FTPPort = 21;
        private static String FTPUsername = "";
        private static String FTPPassword = "";
    
        public FTPconnection()
        {
            FTPHostName = getHostname();
            FTPUsername = getUsername();
            FTPPassword = getPassword();
        }
    
        //  Reference: https://stackoverflow.com/a/24605713/6667035
        public Boolean downloadAndSaveFile(String filename, File localFile)
                throws IOException {
            String LOG_TAG = "FTPconnection_download";
            FTPClient ftp = null;
            try {
                ftp = new FTPClient();
                ftp.connect(FTPHostName, FTPPort);
                Log.d(LOG_TAG, "Connected. Reply: " + ftp.getReplyString());
    
                ftp.login(FTPUsername, FTPPassword);
                Log.d(LOG_TAG, "Logged in");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                Log.d(LOG_TAG, "Downloading");
                ftp.enterLocalPassiveMode();
    
                OutputStream outputStream = null;
                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(
                            localFile));
                    success = ftp.retrieveFile(filename, outputStream);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
    
                return success;
            } finally {
                if (ftp != null) {
                    ftp.logout();
                    ftp.disconnect();
                }
            }
        }
    }
    
  • ftpdownloadfile.cpp

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getHostname(JNIEnv *env, jobject thiz) {
        std::string output = "Hostname";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getUsername(JNIEnv *env, jobject thiz) {
        std::string output = "Username";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getPassword(JNIEnv *env, jobject thiz) {
        std::string output = "Password";
        return env->NewStringUTF(output.c_str());
    }
    
  • ExecutorService for new thread

    ExecutorService executor = Executors.newSingleThreadExecutor();
          executor.submit(() -> {
              String threadName = Thread.currentThread().getName();
              showToast(threadName, Toast.LENGTH_SHORT);
              FTPconnection ftpConnect = new FTPconnection();
              final String LOG_TAG = "executor";
              try {
                  String filename = "test.txt";
                  Log.v(LOG_TAG,"Preparing to download " + filename);
                  var result  = ftpConnect.downloadAndSaveFile(filename, Paths.get(getApplicationInfo().dataDir + "/" + filename).toFile());
                  if (result == false) {
                      Log.v(LOG_TAG,"Fail to download " + filename + "!");
                  } else {
                      Log.v(LOG_TAG,"Download " + filename + " successfully!");
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          });
    
  • User permission setting

    <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.ftpdownloadfile">
    
        <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.FTPDownloadFile">
            <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 31
    
        defaultConfig {
            applicationId "com.example.ftpdownloadfile"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags ''
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
        externalNativeBuild {
            cmake {
                path file('src/main/cpp/CMakeLists.txt')
                version '3.18.1'
            }
        }
    }
    
    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.3.1'
        implementation 'com.google.android.material:material:1.4.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.0'1'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
    
  • Project name: FTPDownloadFile

  • FTPconnection class implementation

    package com.example.ftpdownloadfile;
    
    import android.util.Log;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class FTPconnection {
    
        private native String getHostname();
        private native String getUsername();
        private native String getPassword();
    
        private static String FTPHostName = "";
        private static final int FTPPort = 21;
        private static String FTPUsername = "";
        private static String FTPPassword = "";
    
        public FTPconnection()
        {
            FTPHostName = getHostname();
            FTPUsername = getUsername();
            FTPPassword = getPassword();
        }
    
        //  Reference: https://stackoverflow.com/a/24605713/6667035
        public Boolean downloadAndSaveFile(String filename, File localFile)
                throws IOException {
            String LOG_TAG = "FTPconnection_download";
            FTPClient ftp = null;
            try {
                ftp = new FTPClient();
                ftp.connect(FTPHostName, FTPPort);
                Log.d(LOG_TAG, "Connected. Reply: " + ftp.getReplyString());
    
                ftp.login(FTPUsername, FTPPassword);
                Log.d(LOG_TAG, "Logged in");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                Log.d(LOG_TAG, "Downloading");
                ftp.enterLocalPassiveMode();
    
                OutputStream outputStream = null;
                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(
                            localFile));
                    success = ftp.retrieveFile(filename, outputStream);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
    
                return success;
            } finally {
                if (ftp != null) {
                    ftp.logout();
                    ftp.disconnect();
                }
            }
        }
    }
    
  • ftpdownloadfile.cpp

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getHostname(JNIEnv *env, jobject thiz) {
        std::string output = "Hostname";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getUsername(JNIEnv *env, jobject thiz) {
        std::string output = "Username";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getPassword(JNIEnv *env, jobject thiz) {
        std::string output = "Password";
        return env->NewStringUTF(output.c_str());
    }
    
  • ExecutorService for new thread

    ExecutorService executor = Executors.newSingleThreadExecutor();
          executor.submit(() -> {
              String threadName = Thread.currentThread().getName();
              showToast(threadName, Toast.LENGTH_SHORT);
              FTPconnection ftpConnect = new FTPconnection();
              final String LOG_TAG = "executor";
              try {
                  String filename = "test.txt";
                  Log.v(LOG_TAG,"Preparing to download " + filename);
                  var result  = ftpConnect.downloadAndSaveFile(filename, Paths.get(getApplicationInfo().dataDir + "/" + filename).toFile());
                  if (result == false) {
                      Log.v(LOG_TAG,"Fail to download " + filename + "!");
                  } else {
                      Log.v(LOG_TAG,"Download " + filename + " successfully!");
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          });
    
  • User permission setting

    <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.ftpdownloadfile">
    
        <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.FTPDownloadFile">
            <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 31
    
        defaultConfig {
            applicationId "com.example.ftpdownloadfile"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags ''
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
        externalNativeBuild {
            cmake {
                path file('src/main/cpp/CMakeLists.txt')
                version '3.18.1'
            }
        }
    }
    
    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.3.1'
        implementation 'com.google.android.material:material:1.4.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
    
  • Project name: FTPDownloadFile

  • FTPconnection class implementation

    package com.example.ftpdownloadfile;
    
    import android.util.Log;
    
    import org.apache.commons.net.ftp.FTP;
    import org.apache.commons.net.ftp.FTPClient;
    import org.apache.commons.net.ftp.FTPReply;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    
    public class FTPconnection {
    
        private native String getHostname();
        private native String getUsername();
        private native String getPassword();
    
        private static String FTPHostName = "";
        private static final int FTPPort = 21;
        private static String FTPUsername = "";
        private static String FTPPassword = "";
    
        public FTPconnection()
        {
            FTPHostName = getHostname();
            FTPUsername = getUsername();
            FTPPassword = getPassword();
        }
    
        //  Reference: https://stackoverflow.com/a/24605713/6667035
        public Boolean downloadAndSaveFile(String filename, File localFile)
                throws IOException {
            String LOG_TAG = "FTPconnection_download";
            FTPClient ftp = null;
            try {
                ftp = new FTPClient();
                ftp.connect(FTPHostName, FTPPort);
                Log.d(LOG_TAG, "Connected. Reply: " + ftp.getReplyString());
    
                ftp.login(FTPUsername, FTPPassword);
                Log.d(LOG_TAG, "Logged in");
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                Log.d(LOG_TAG, "Downloading");
                ftp.enterLocalPassiveMode();
    
                OutputStream outputStream = null;
                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(
                            localFile));
                    success = ftp.retrieveFile(filename, outputStream);
                } finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }
    
                return success;
            } finally {
                if (ftp != null) {
                    ftp.logout();
                    ftp.disconnect();
                }
            }
        }
    }
    
  • ftpdownloadfile.cpp

    #include <jni.h>
    #include <string>
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getHostname(JNIEnv *env, jobject thiz) {
        std::string output = "Hostname";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getUsername(JNIEnv *env, jobject thiz) {
        std::string output = "Username";
        return env->NewStringUTF(output.c_str());
    }
    
    extern "C"
    JNIEXPORT jstring JNICALL
    Java_com_example_ftpdownloadfile_FTPconnection_getPassword(JNIEnv *env, jobject thiz) {
        std::string output = "Password";
        return env->NewStringUTF(output.c_str());
    }
    
  • ExecutorService for new thread

    ExecutorService executor = Executors.newSingleThreadExecutor();
          executor.submit(() -> {
              String threadName = Thread.currentThread().getName();
              showToast(threadName, Toast.LENGTH_SHORT);
              FTPconnection ftpConnect = new FTPconnection();
              final String LOG_TAG = "executor";
              try {
                  String filename = "test.txt";
                  Log.v(LOG_TAG,"Preparing to download " + filename);
                  var result  = ftpConnect.downloadAndSaveFile(filename, Paths.get(getApplicationInfo().dataDir + "/" + filename).toFile());
                  if (result == false) {
                      Log.v(LOG_TAG,"Fail to download " + filename + "!");
                  } else {
                      Log.v(LOG_TAG,"Download " + filename + " successfully!");
                  }
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          });
    
  • User permission setting

    <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.ftpdownloadfile">
    
        <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.FTPDownloadFile">
            <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 31
    
        defaultConfig {
            applicationId "com.example.ftpdownloadfile"
            minSdk 26
            targetSdk 31
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags ''
                }
            }
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_11
            targetCompatibility JavaVersion.VERSION_11
        }
        externalNativeBuild {
            cmake {
                path file('src/main/cpp/CMakeLists.txt')
                version '3.18.1'
            }
        }
    }
    
    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.3.1'
        implementation 'com.google.android.material:material:1.4.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }
    
Update MainActivity.java content
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update MainActivity.java content
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update MainActivity.java content
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update question description
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update question description
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update question description
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update build.gradle content
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update question description
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update question description
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update question description
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Update question description
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading
Source Link
JimmyHu
  • 5.5k
  • 2
  • 10
  • 40
Loading