From 4f0fd95220bb2ee1da4f28d3596115155347a13e Mon Sep 17 00:00:00 2001 From: Gyubin Han Date: Mon, 5 Jan 2026 01:12:11 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9B=90=EA=B2=A9=20FTP=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=20=ED=8C=8C=EC=9D=BC=20=EB=8B=A4=EC=9A=B4=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++ .../file/explorer/FTPClientHelper.java | 16 ++++++++--- .../android/file/explorer/MainActivity.java | 28 +++++++++++++++++-- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 30fe0ca..e0e4f0a 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,6 @@ captures/ # Google Services (safety) /app/google-services.json + +# temp +/.temp diff --git a/app/src/main/java/be/gyu/android/file/explorer/FTPClientHelper.java b/app/src/main/java/be/gyu/android/file/explorer/FTPClientHelper.java index 663c544..44dfb32 100644 --- a/app/src/main/java/be/gyu/android/file/explorer/FTPClientHelper.java +++ b/app/src/main/java/be/gyu/android/file/explorer/FTPClientHelper.java @@ -5,6 +5,7 @@ import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; import java.io.IOException; +import java.io.OutputStream; public class FTPClientHelper { @@ -23,6 +24,7 @@ public class FTPClientHelper { return false; } ftpClient.enterLocalPassiveMode(); + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); return true; } catch (IOException e) { e.printStackTrace(); @@ -43,13 +45,9 @@ public class FTPClientHelper { public FTPFile[] listFiles(String path) { try { - // First, try to change the working directory. if (ftpClient.changeWorkingDirectory(path)) { - // If successful, list files in the new directory. return ftpClient.listFiles(); } else { - // If changing directory fails, it might be a file path, not a directory. - // Or the path is invalid. For now, we return null for simplicity. return null; } } catch (IOException e) { @@ -57,4 +55,14 @@ public class FTPClientHelper { return null; } } + + public boolean downloadFile(String remoteFileName, OutputStream out) { + try { + // retrieveFile works on the current working directory. + return ftpClient.retrieveFile(remoteFileName, out); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } } \ No newline at end of file diff --git a/app/src/main/java/be/gyu/android/file/explorer/MainActivity.java b/app/src/main/java/be/gyu/android/file/explorer/MainActivity.java index 668fccb..3d4b289 100644 --- a/app/src/main/java/be/gyu/android/file/explorer/MainActivity.java +++ b/app/src/main/java/be/gyu/android/file/explorer/MainActivity.java @@ -28,6 +28,9 @@ import androidx.recyclerview.widget.RecyclerView; import org.apache.commons.net.ftp.FTPFile; import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; @@ -118,6 +121,28 @@ public class MainActivity extends AppCompatActivity implements FileAdapter.OnIte }).start(); } + private void downloadAndOpenFile(FileItem item) { + runOnUiThread(() -> Toast.makeText(this, "Downloading " + item.getName(), Toast.LENGTH_SHORT).show()); + + new Thread(() -> { + File localFile = new File(getCacheDir(), item.getName()); + try (OutputStream out = new FileOutputStream(localFile)) { + boolean success = ftpHelper.downloadFile(item.getName(), out); + runOnUiThread(() -> { + if (success) { + Toast.makeText(this, "Download complete", Toast.LENGTH_SHORT).show(); + openFile(localFile); + } else { + Toast.makeText(this, "Download failed", Toast.LENGTH_SHORT).show(); + } + }); + } catch (IOException e) { + e.printStackTrace(); + runOnUiThread(() -> Toast.makeText(this, "Download failed: " + e.getMessage(), Toast.LENGTH_SHORT).show()); + } + }).start(); + } + // --- Local Storage Methods --- private void loadFiles(File directory) { this.currentDirectory = directory; @@ -143,8 +168,7 @@ public class MainActivity extends AppCompatActivity implements FileAdapter.OnIte if (item.isDirectory()) { loadFtpFiles(item.getPath()); } else { - // TODO: Implement file download/open for FTP - Toast.makeText(this, "Opening remote files is not implemented yet.", Toast.LENGTH_SHORT).show(); + downloadAndOpenFile(item); } } else { File file = new File(item.getPath());