问题
I want to access files located in a folder on the FTP server by giving ftp's hostname and display it in my app which is developed using the android studio. It should be dynamic, that is it should reflect all the changes done inside the folder of which I have given a specific URL, that is if something is deleted or inserted, it should be reflected in the app. I am unable to connect to FTP server and my app crashes. Below is the code of my app. Please have a look at the code and help me out. Thanks.
This is my MainActivity.java:-
package com.example.nishant.ftp1;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import java.io.IOException;
import java.io.PrintWriter;
import org.apache.commons.net.ftp.FTPClient;
import java.io.InputStream;
import java.net.SocketException;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect("ftp.drivehq.com");
ftpClient.enterLocalPassiveMode();
Log.v("ttt", "connected");
ftpClient.setFileType(FTPClient.ASCII_FILE_TYPE);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "done", Toast.LENGTH_SHORT).show();
}
});
ftpClient.disconnect();
/*Workbook wb = Workbook.getWorkbook(inStream);
Sheet s = wb.getSheet(0);
int row = s.getRows();
int col = s.getColumns();
for (int i = 0; i < row; i++) {
for(int c = 0, c< col; c++){
Cell z = s.getCell(c, i);
String content = z.getContents();
}
}*/
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Error in logcat:
01-24 12:45:09.643 7023-7023/com.example.nishant.ftp1 E/Zygote: MountEmulatedStorage()
01-24 12:45:09.643 7023-7023/com.example.nishant.ftp1 E/Zygote: v2
01-24 12:45:09.643 7023-7023/com.example.nishant.ftp1 I/SELinux: Function: selinux_compare_spd_ram , priority [2] , priority version is VE=SEPF_SAMSUNG-SGH-I337_5.0.1-1_0039
01-24 12:45:09.643 7023-7023/com.example.nishant.ftp1 E/SELinux: [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
01-24 12:45:09.643 7023-7023/com.example.nishant.ftp1 I/art: Late-enabling -Xcheck:jni
01-24 12:45:09.643 7023-7023/com.example.nishant.ftp1 I/libpersona: KNOX_SDCARD checking this for 10240
01-24 12:45:09.643 7023-7023/com.example.nishant.ftp1 I/libpersona: KNOX_SDCARD not a persona
01-24 12:45:09.773 7023-7023/com.example.nishant.ftp1 D/ResourcesManager: creating new AssetManager and set to /data/app/com.example.nishant.ftp1-1/base.apk
01-24 12:45:10.013 7023-7023/com.example.nishant.ftp1 I/InstantRun: starting instant run server: is main process
01-24 12:45:10.253 7023-7023/com.example.nishant.ftp1 W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
01-24 12:45:10.664 7023-7023/com.example.nishant.ftp1 D/AndroidRuntime: Shutting down VM
01-24 12:45:10.674 7023-7023/com.example.nishant.ftp1 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.nishant.ftp1, PID: 7023
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.nishant.ftp1/com.example.nishant.ftp1.MainActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2702)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getByName(InetAddress.java:305)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:202)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:306)
at com.example.nishant.ftp1.MainActivity.onCreate(MainActivity.java:40)
at android.app.Activity.performCreate(Activity.java:6289)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2655)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
01-24 12:50:11.007 7023-7023/com.example.nishant.ftp1 I/Process: Sending signal. PID: 7023 SIG: 9
build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.nishant.ftp1"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation files('libs/commons-net-3.6.jar')
}
activity_main.xml
回答1:
you can solve the problem by using Asynctask class. You can find code here:
FTP connection java
回答2:
You should write a method getCurrentFileNames() that get filename and search inside mobile folder and returns a list of Current stored Files.You should also write another method DownloafFileFromServer(String fileName) that takes a file name and if file exist in server it should download it and if not exist it should delete it in mobile folder.
List<String> fileNames = getCurrentFileNames();
String inputfileName;
for(String fileName:fileNames){
if(!inputfileName.equals(fileName){
DownloadFileFromServer(inputfileName);
break;
}
}
public void DownloadFileFromServer(String fileName){
OkHttpClient client = new OkHttpClient();]
String url = "http://hostname.com/folder/fileName"
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws
IOException {
try {
DownloadFileFromUrl(response, fileName);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
DownloadFileFromUrl(Response res, String fileName){
InputStream is = null;
FileOutputStream fos = null;
File f = new File(Environment.getExternalStorageDirectory() +
"/folder/" + fileName);
if(res.code == 200){
try {
if (f.exists())
f.delete();
fos = new FileOutputStream(f);
is = res.body().byteStream();
byte[] buffer = new byte[1024];
int rd;
long count = 0;
while ((rd = is.read(buffer, 0, buffer.length)) > 0) {
fos.write(buffer, 0, rd);
count += rd;
}
is.close();
fos.flush();
fos.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
//deleted in server
else if(res.code == 404){
if (f.exists())
//delete in mobile folder as well
f.delete();
}
}
来源:https://stackoverflow.com/questions/48396023/i-want-to-access-files-located-on-a-ftp-server-and-display-it-in-my-app