I'm trying to upload ZIP files of size 2MB to FTPServer from Android App. After authentication, I create the necessary folders in server if not exist, later I try to upload the zip file but ended up failing with following error.
ftpUpload: libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:588)
libcore.io.IoBridge.recvfrom(IoBridge.java:552)
java.net.PlainSocketImpl.read(PlainSocketImpl.java:481)
java.net.PlainSocketImpl.-wrap0(PlainSocketImpl.java)
java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
java.io.InputStreamReader.read(InputStreamReader.java:233)
java.io.BufferedReader.fillBuf(BufferedReader.java:145)
java.io.BufferedReader.readLine(BufferedReader.java:397)
org.apache.commons.net.ftp.FTP.__getReply(FTP.java:294)
org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:490)
org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:534)
org.apache.commons.net.ftp.FTP.port(FTP.java:862)
org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:463)
org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:374)
org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:1379)
com.inspection.servertransaction.CaseUploader.ftpUpload(CaseUploader.java:775)
com.inspection.servertransaction.CaseUploader.zipMedia(CaseUploader.java:591)
com.inspection.servertransaction.CaseUploader.uploadCase(CaseUploader.java:194)
com.inspection.services.UploadCasesThread$WorkerThread.processCommand(UploadCasesThread.java:103)
com.inspection.services.UploadCasesThread$WorkerThread.run(UploadCasesThread.java:51)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
java.lang.Thread.run(Thread.java:818)
FTPUpload function
private boolean ftpUpload(File localFilePath, String remoteFilePath) {
FTPClient ftpclient = new FTPClient();
FileInputStream fis;
boolean result;
try {
ftpclient.connect(InetAddress.getByName(context.getString(R.string.ftp_hostname)));
boolean isLoggedIn = ftpclient.login(context.getString(R.string.ftp_username), context.getString(R.string.ftp_password));
if (isLoggedIn) {
Log.i(this.getClass().getSimpleName(), "FTP authenticated");
// On Successful login
ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
// Ignore the actual file name from remote path, and get only directory path.
int index = remoteFilePath.lastIndexOf("/");
String remoteDir = null;
if (index != -1)
remoteDir = remoteFilePath.substring(0, index);
if (remoteDir != null)
/**
* changeWorkingDirectory returns whether the specified directory exist or not.
* If not exist in remote, create folders
*/
if (!ftpclient.changeWorkingDirectory(remoteDir)) {
if (makeDirectories(ftpclient, remoteDir))
ftpclient.changeWorkingDirectory(remoteFilePath);
else
Log.e(this.getClass().getSimpleName(), "remote path is not available");
} else
ftpclient.changeWorkingDirectory(remoteFilePath);
// Get the stream of the file
String testName = localFilePath.getName();
fis = new FileInputStream(localFilePath);
// Upload file to the ftp server
result = ftpclient.storeFile(testName, fis);
Log.i(this.getClass().getSimpleName(), "FTP Store Result " + result);
if (result) {
Log.i(this.getClass().getSimpleName(), "File is uploaded successfully");
result = true;
} else {
Log.e(this.getClass().getSimpleName(), "File uploading failed");
result = false;
}
} else {
Log.e(this.getClass().getSimpleName(), "Login Fail!");
result = false;
}
// logout from ftp server
ftpclient.logout();
} catch (Exception e) {
Log.e(this.getClass().getSimpleName(), "FTP Exception!");
EvApp.mErrorLogger.writeLog(ExceptionStackTrace.printStackTraceException(e),
this.getClass().getSimpleName() + ": ftpUpload", null, "Error");
result = false;
}
It was working fine, suddenly facing this issue. So I doubt that it's might be Server side issue. But what might be the problem? Any help will be appreciated.
Related
i want to create a comic reader project on android. In my database, i only save path to the chapter directory which was taken from folderID on google drive. When user request to read comic, i want to through google client api to browse folder and get all file inside it.
i've seen guilde on https://developers.google.com/drive/v2/reference/files/list
but i still do not understand how it works, specials parameter Drive, how can i get it?
Thanks for any supports.
private static List<File> retrieveAllFiles(Drive service) throws IOException {
List<File> result = new ArrayList<File>();
Files.List request = service.files().list();
do {
try {
FileList files = request.execute();
result.addAll(files.getItems());
request.setPageToken(files.getNextPageToken());
} catch (IOException e) {
System.out.println("An error occurred: " + e);
request.setPageToken(null);
}
} while (request.getPageToken() != null &&
request.getPageToken().length() > 0);
return result;
}
I've been working with Azure on the Android OS and I managed to upload my video file (.mp4) to a Container I had already prepared for it.
I did this by getting a Shared Access Signature (SAS) first, which provided me with:
a temporary key
the name of the container to where I want to send the files
the server URI
Then, I started an AsyncTask to send the file to the container using the "upload".
I checked the container, and the file gets uploaded perfectly, no problems on that end.
My question is regarding the progress of the upload. Is it possible to track it? I would like to have an upload bar to give a better UX.
P.S - I'm using the Azure Mobile SDK
Here's my code:
private void uploadFile(String filename){
mFileTransferInProgress = true;
try {
Log.d("Funky Stuff", "Blob Azure Config");
final String gFilename = filename;
File file = new File(filename); // File path
String blobUri = blobServerURL + sharedAccessSignature.replaceAll("\"", "");
StorageUri storage = new StorageUri(URI.create(blobUri));
CloudBlobClient blobCLient = new CloudBlobClient(storage);
//Container name here
CloudBlobContainer container = blobCLient.getContainerReference(blobContainer);
blob = container.getBlockBlobReference(file.getName());
//fileToByteConverter is a method to convert files to a byte[]
byte[] buffer = fileToByteConverter(file);
ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
if (blob != null) {
new UploadFileToAzure().execute(inputStream);
}
} catch (StorageException e) {
Log.d("Funky Stuff", "StorageException: " + e.toString());
e.printStackTrace();
} catch (IOException e) {
Log.d("Funky Stuff", "IOException: " + e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.d("Funky Stuff", "Exception: " + e.toString());
e.printStackTrace();
}
mFileTransferInProgress = false;
//TODO: Missing ProgressChanged method from AWS
}
private class UploadFileToAzure extends
AsyncTask <ByteArrayInputStream, Void, Void>
{
#Override
protected Void doInBackground(ByteArrayInputStream... params) {
try {
Log.d("Funky Stuff", "Entered UploadFileToAzure Async" + uploadEvent.mFilename);
//Method to upload, takes an InputStream and a size
blob.upload(params[0], params[0].available());
params[0].close();
} catch (StorageException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Thanks!
You can split your file and send its part using Block, there is a good example of your case in this link but it used C# so you should find the corresponding function in the android library reference.
Basically instead of sending you file as one big file, you split it to multiple files (bytes) and send it to azure so you can track the progress on how many bytes that already sent to azure
This is a follow-up of this question. I have written my data file on Drive application folder, now the same app that created these files needs to retrieve them.
This doesn't work (I get the listing of the file, but the request of file download return with a 401 error):
private ArrayList<File> listFilesInApplicationDataFolder(Drive service) throws IOException {
ArrayList<File> result = new ArrayList<File>();
Files.List request = service.files().list();
request.setQ("'appdata' in parents");
do {
try {
FileList files = request.execute();
result.addAll(files.getItems());
request.setPageToken(files.getNextPageToken());
} catch (IOException e) {
System.out.println("An error occurred: " + e);
request.setPageToken(null);
}
} while (request.getPageToken() != null &&
request.getPageToken().length() > 0);
for (File file:result){
System.out.println("##### "+file.getOriginalFilename()+ " "+file.toPrettyString());
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) {
try {
HttpResponse resp =
service.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl()))
.execute();
InputStream in= resp.getContent();
FileOutputStream fos = openFileOutput("pinmemo",
Context.MODE_PRIVATE);
while(in.available()>0)
fos.write(in.read());
fos.close();
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
return null;
} catch (IOException e) {
// An error occurred.
e.printStackTrace();
return null;
}
} else {
// The file doesn't have any content stored on Drive.
return null;
}
}
return result;
}
What should I do?
EDIT:
I get this error message:
04-17 11:19:30.614: W/System.err(2022): com.google.api.client.http.HttpResponseException: 401 Unauthorized
04-17 11:19:30.614: W/System.err(2022): at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1095)
EDIT: the new Google play games services basically covers my needs (the only problem is that my app isn't a game...), therefore this question is now partially obsolete. Of course, Google play games uses "Cloud save" instead of "drive", but for my needs that's sufficent. However, should I use Google play games for non-gaming app?
Make sure that your access token has permissions for the appdata scope:
https://www.googleapis.com/auth/drive.appdata
I was trying to download files in Google Drive on Android, and I was following the sample from https://developers.google.com/drive/manage-downloads#examples
if (entry.getDownloadUrl() != null && entry.getDownloadUrl().length() > 0)
{
try
{
LogUtils.xi(this, "start opening url:", entry.getDownloadUrl());
/* HttpRequestFactory: Thread-safe light-weight HTTP request factory layer on top of the HTTP */
HttpResponse resp = manager.getDrive().getRequestFactory()
.buildGetRequest(new GenericUrl(entry.getDownloadUrl()))
.execute();
return resp.getContent();
}
catch (IOException e)
{
LogUtils.xe(this, e.toString());
e.printStackTrace();
throw ExceptionUtils.getIOException("Can't open inputstream.", e);
}
}
else
{
LogUtils.xw(this, "The file doesn't have any content stored on Drive.");
return null;
}
But getting the error 302: Does anybody knows what's going on here?
03-29 14:56:07.316 E/XXGoogleDrive(25539): [25566][DriveDLFutureTask] [getInputStream]com.google.api.client.http.HttpResponseException: **302 Moved Temporarily**
03-29 14:56:07.326 W/System.err(25539): com.google.api.client.http.HttpResponseException: 302 Moved Temporarily
03-29 14:56:07.326 W/System.err(25539): at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1062)
'Moved temporarily' occurred because the page was trying for a re-direct to user authentication page or virus scanning in case file size exceeeds 25 MB
I got it working by using file get request with 'alt=media' query param and the working code is below
private static byte[] getBytes(Drive drive, String accessToken, String fileId, long position, long byteCount) {
byte[] receivedByteArray = null;
String downloadUrl = "https://www.googleapis.com/drive/v3/files/" + fileId + "?alt=media&access_token="
+ accessToken;
if (downloadUrl != null && downloadUrl.length() > 0) {
try {
com.google.api.client.http.HttpRequest httpRequestGet = drive.getRequestFactory().buildGetRequest(new GenericUrl(downloadUrl));
httpRequestGet.getHeaders().setRange("bytes=" + position + "-" + (position + byteCount - 1));
com.google.api.client.http.HttpResponse response = httpRequestGet.execute();
InputStream is = response.getContent();
receivedByteArray = IOUtils.toByteArray(is);
response.disconnect();
System.out.println("google-http-client-1.18.0-rc response: [" + position + ", " + (position + receivedByteArray.length - 1) + "]");
} catch (IOException e) {
e.printStackTrace();
}
}
return receivedByteArray;
}
I can't access "ftp server in PC" from "android app" to download file, I used wireless connection.
public void FTP_Download(){
String server = "192.168.1.135";
int port = 21;
String user = "pc1";
String pass = "1551";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
Toast.makeText(getBaseContext(), "download starting.",Toast.LENGTH_LONG).show();
// APPROACH #1: using retrieveFile(String, OutputStream)
String remoteFile1 = "i.xml";
File downloadFile1 = new File("sdcard/i.xml");
OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
outputStream1.close();
if (success) {
Toast.makeText(getBaseContext(), "File #1 has been downloaded successfully.",Toast.LENGTH_LONG).show();
}
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
I added internet permission :
<uses-permission android:name="android.permission.INTERNET"/>
Note: I tested app in emulator on PC and all things was OK.
When I tried to access FTP from default browser I can't, but I can from firefox.
any help please
I've had the same issue. If it worked on the emulator and not on the device, there's probably a firewall in your way, or your network isn't allowing the connection because for some reason it's not secure enough. Also make sure your FTP server allows connections from your username and password.