0

So I have run into a bit of an issue, I wanted to use an FTP transfer for my android app using java, sounded simple enough, so I got it working fine in normal java using the Apache-commons library, but when I attempted to use the same method in android java I ran into an error that log cat traces back to, I need to be able to connect to a pre-existing FTP server and be able to upload and download files, from it. I have read several things saying that "You need Internet permissions" so I added

 <uses-permission android:name="android.permission.INTERNET"/>
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

to my "AndroidManifest.xml" and I still run into the same issue, I then read another thing where it said you need to use an a-sync method because you can't do internet operations in the main visual thread, so I tried that, and that absolutely didn't work, and android-studio just screamed at me that the "A-sync method" was deprecated, I have asked on several discord communities got no response except for some guy who wanted to proclaim that "FTP is insecure" I do not care about that, I have my reasons and needs for FTP transfers and I just want to know how to get this working. Any help will be immensely appreciated and I am still relatively new to java and android development so a more dumbed down easier to comprehend answer would be very nice of you to my smooth brain, but I will take almost anything that will work at this point. And yes I have

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

added to my "androidmanifest.xml" aswell

Snippet of my code in a different method from the onCreate method that gets called by the clicking a button

  String server = "exampleserver.com";
            int port = 21;
            String user = "username";
            String pass = "password";
            FTPClient ftpClient = new FTPClient();
            try{
                ftpClient.connect(server, port);
                ftpClient.login(user, pass);
                ftpClient.enterLocalPassiveMode();
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                File firstLocalFile = new File("/test/test.txt");
                String firstRemoteFile = "test.txt";
                InputStream inputStream = new FileInputStream(firstLocalFile);
                ftpClient.storeFile(firstRemoteFile, inputStream);
    
            }catch(IOException e) {
                e.printStackTrace();
            }

List of My imports

package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

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

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

I also have the pop up to get read and write permissions

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE
                , Manifest.permission.READ_EXTERNAL_STORAGE}, PackageManager.PERMISSION_GRANTED);
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.INTERNET
                , Manifest.permission.INTERNET}, PackageManager.PERMISSION_GRANTED);
    }

and I have tried it with and without the INTERNET Grant line or whatever it makes no difference, and of course I do put in the real file names and username and password and domain in my actual code just not showing it here Log cat errors:

2021-08-17 18:28:57.501 6978-6978/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplication, PID: 6978
    java.lang.IllegalStateException: Could not execute method for android:onClick
        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414)
        at android.view.View.performClick(View.java:6930)
        at android.widget.TextView.performClick(TextView.java:12773)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
        at android.view.View$PerformClick.run(View.java:26211)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:7000)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
        at android.view.View.performClick(View.java:6930) 
        at android.widget.TextView.performClick(TextView.java:12773) 
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119) 
        at android.view.View$PerformClick.run(View.java:26211) 
        at android.os.Handler.handleCallback(Handler.java:790) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:7000) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408) 
     Caused by: android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1450)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:102)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90)
        at java.net.InetAddress.getByName(InetAddress.java:743)
        at org.apache.commons.net.SocketClient.connect(SocketClient.java:212)
        at com.example.myapplication.MainActivity.click(MainActivity.java:57)
        at java.lang.reflect.Method.invoke(Native Method) 
        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409) 
        at android.view.View.performClick(View.java:6930) 
        at android.widget.TextView.performClick(TextView.java:12773) 
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119) 
        at android.view.View$PerformClick.run(View.java:26211) 
        at android.os.Handler.handleCallback(Handler.java:790) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:7000) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408) 

line 57 is this piece of code that can be seen above: (click function is the method that gets called to do the FTP transfer when you hit a button)

ftpClient.connect(server, port);
TOGFB9
  • 1
  • 1
    If you look at your stack trace, the very last `Caused by:` cites the problem as being `android.os.NetworkOnMainThreadException`. When you encounter an error like that, use a search engine to try to find resources related to the error. You should have come up with the duplicate question, which lists several solutions among its 64 answers. "I do not care about that" -- *you* may not, but *the rest of the world* does, which is why you will find few libraries and dedicated examples for using FTP libraries in Android. – CommonsWare Aug 17 '21 at 23:37

0 Answers0