I have a simple FTP upload App that normally works fine.
Sometimes in the middle of a Upload I might lose INTERNET (moving between wifi spots or something).
When this happens the Upload keeps trying to upload but makes no progress, doesn't timeout or cause any errors and since the service never finishes I can't restart it unless I force stop the App.
How can I set timeout options and any other useful tool prevent my App from doing this?
How do I implement and to what effect the following or any other:
client.setConnectTimeout(60); //Are this milliseconds, seconds or what?
client.setDefaultTimeout(300); //Are this milliseconds, seconds or what?
client.setControlKeepAliveTimeout(120); //Are this milliseconds, seconds or what?
Here is a shoetened version of my code for you to see.
myFTP.class
public class myFTP{
String ip;
String user;
String pass;
FTPClient client = new FTPClient();
public myFTP() {
ip = "someip";
user = "´someuser";
pass = "somepass";
client = new FTPClient();
}
public boolean connect() {
//Define vars
try{
//Connect and login
client.setConnectTimeout(60);
client.setDefaultTimeout(300);
client.setControlKeepAliveTimeout(120);
client.connect(ip);
client.login(user,pass);
if(FTPReply.isPositiveCompletion(client.getReplyCode())){
client.setFileType(FTP.BINARY_FILE_TYPE);
}else{
Log.e ("Coneccion FTP", "Fallo");
}
} catch (UnknownHostException e) {
e.printStackTrace();
return false;
} catch (SocketException e){
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
public boolean upload (String fileName, File file, String dir){
//Cargo el archivo
try{
FileInputStream fis = new FileInputStream(file);
client.enterLocalPassiveMode();
Log.e("Subiendo", fileName);
boolean status = client.storeFile(dir+fileName,fis);
if (!status){
fis.close();
return false;
}
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
try {
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
I made some changes.
Had the FTP server connect and stay connected for all files instead of connecting and disconnecting for every file.
Added timeouts after a lot of trying and failing that seem to work.
In the alarm I stopped the service and then started a new one. If the service is hangged up it will start again.
Related
While trying to create a simple Android app that allows me to send a simple string to an IoT device, I used code which initialised a new socket everytime it would send a string. I thought it would be better to have a socket send multiple strings before it would get closed again, but this turned out to be very slow. I am not experienced enough to realise what is going on here.
public class sendString extends AsyncTask<String, String, Socket> {
int brightness;
private int oldbrightness;
void changeBrightness(int newbright){
oldbrightness = brightness;
brightness = newbright;
}
#Override
protected Socket doInBackground(String... strings) {
try {
Socket socket = new Socket(strings[0], 80);
socket.setTcpNoDelay(true);
DataOutputStream DOS = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
while (!isCancelled()) {
if (oldbrightness != brightness) {
DOS.writeUTF("\"sr1\":" + brightness + " ");
DOS.flush();
}
}
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onCancelled(){
return;
}
protected void onProgressUpdate(String... progress){
}
#Override
protected void onPostExecute(Socket socket){
return;
}
}
This is my code which sends multiple strings over one socket. The function is called when a seekbar is clicked, brightness is changed everytime the seekbar moves and cancel(true) is called when the seekbar is released. Is my code wrong or is there a different reason as to why this method would be so slow?
The old code:
public class sendString extends AsyncTask<String, Void, Socket> {
#Override
protected Socket doInBackground(String... strings) {
try {
Socket socket = new Socket(strings[0], 80);
DataOutputStream DOS = new DataOutputStream(socket.getOutputStream());
DOS.writeUTF(strings[1]);
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
This would get called everytime the seekbar moved.
The difference is that the first version executes in a CPU-smoking loop sending messages infinitely, while the second version executes exactly once per seek bar move, which should always be quicker.
You are comparing apples and oranges.
You should open the socket outside this method, prior to installing the seekbar listener, and only send one message per invocation.
I am planning to create an application for downloading a file from FTP server, Below code has working fine with the functionality, But I need to show current speed and transfer rate while downloading a file, Please help me to solve this problem,
private boolean downloadSingleFile(String remoteFilePath, File downloadFile) {
boolean status = false;
try {
con = new FTPClient();
con.setConnectTimeout(5000);
con.connect(host);
if (con.login(username, password)) {
con.enterLocalPassiveMode(); // important!
con.setFileType(FTP.BINARY_FILE_TYPE);
File parentDir = downloadFile.getParentFile();
if (!parentDir.exists())
parentDir.mkdir();
OutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(
new FileOutputStream(downloadFile));
con.setFileType(FTP.BINARY_FILE_TYPE);
status = con.retrieveFile(remoteFilePath, outputStream);
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
con.logout();
con.disconnect();
}
} else {
con.logout();
con.disconnect();
// delayWait(duration);
}
}
catch (UnknownHostException e) {
Log.e(TAG, e.getMessage());
} catch (Exception e) {
}
return status;
}
If i would like to download a more than 5Mb or 50 Mb file this requirement will be useful for the user to know about the current speed of the device , Please help me to finish this issues.
Regards
Priya
here is m code for creating and uploading a csv file to ftp for acceleration data and time :
case R.id.button_csv:
start.setEnabled(true);
pause.setEnabled(false);
csv.setEnabled(false);
try {
String s;
FileWriter datei = new FileWriter("Fahrt1.csv");
BufferedWriter dateiFahrt = new BufferedWriter (datei);
dateiFahrt.write("Time"+","+"ax"+","+"ay"+","+"az"+"\n");
for (int i=0; i<sensorDataTime.size(); i++)
{
s=sensorDataTime.get(i)+","+sensorDataAx.get(i).toString()+","+sensorDataAy.get(i).toString()+","+sensorDataAz.get(i).toString()+"\n";
dateiFahrt.write(s);
}
dateiFahrt.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
goforIt(); //write to given ftp client
break;
}
}
//method for uploading a file to ftp client
public void goforIt(){
FTPClient con = null;
try
{
con = new FTPClient();
con.connect("server");
if (con.login("userName", "password"))
{
con.enterLocalPassiveMode(); // important!
con.setFileType(FTP.BINARY_FILE_TYPE);
String data = "Fahrt1.csv";
FileInputStream in = new FileInputStream(new File(data));
boolean result = con.storeFile("/Fahrt1.csv", in);
in.close();
if (result) Log.v("upload result", "succeeded");
con.logout();
con.disconnect();
}
}
catch (Exception e)
{
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
when i run my app on device evertyhin works fine but when i press the csv button then it throw me an excetption :
android.os.NetworkOnMainThreadExcetption. but eclipse says that my code is just fine. so what to do ?
In Android like in most mobile environments it isn't permited to run network code on the Main thread since the main Thread is in charge of drawing UI and other taks relevant to the user experience, that's what that exception is telling you you'll need to use wrap the network code (tour goForit() in an AsyncTask or in a Thread
I have a FileInputStream that reads data from arduino. On my java code reading function in an infinite while loop. read function works just once in the beginning and stop doing its work and jumps to catch block continuously.
Why does it do that ONCE? It should read data continuously. Any suggestions?
while(true)
{
try
{ byte[] inputmessage =new byte[1];
ret=mInputStream.read(inputmessage);
SystemClock.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
SystemClock.sleep(2000);
}
finally{
try {
if(mInputStream!=null){
mInputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
veri = Arrays.toString(inputmessage);
veri = veri.replace("[","");
veri = veri.replace("]","");
publishProgress(Integer.parseInt(veri));
SystemClock.sleep(2000);
}
}
An inputstream will go through data only once, you can check with "markSupported()" if you can set a mark in your stream, if you can, you can set it and use "reset" when you want to restart from scratch.
I'm currently working on a tcp client in Android.
I want to connect my android device to a tcp server on my computer and receive the data once every 2 seconds. The problem is that I'm getting force close on my application because of the while loop that I've implemented in the tcp client.
I've tried writing in different ways the loop that will make the tcp client checking the server socket, but with no success. How can make a loop that will check the server socket without getting the force close?
Here's my code that I'm currently using:
public class Connection implements Runnable {
#Override
public void run() {
try {
sk=new Socket(server,port);
viewsurface.setText("connected");
flag = true;
} catch (UnknownHostException e) {
viewsurface.setText("failed 1 socket");
flag = false;
} catch (IOException e) {
viewsurface.setText("failed 2 socket");
flag = false;
}
while (flag == true){
try {
checkin = sk.getInputStream();
checkint = checkin.available();
if (checkint > 0){
try {
BufferedReader in = new BufferedReader(new InputStreamReader(sk.getInputStream()));
received = in.readLine();
viewsurface.setText(received);
} catch (IOException e) {
viewsurface.setText("failed to receive");
}
}
Thread.sleep(2000);
} catch (IOException e) {
viewsurface.setText("checkin failed");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
You need to paste the exception that you are getting to cause the force close, before anyone can provide decent help.
But some suggestions that might solve the problem.
Most likely to be the problem, viewText.setText can only be called from the UI thread. There's quite a few ways to handle this. You can use AsyncTask or if you have an Activity reference you can use runOnUIThread and pass in a runnable that calls setText.
Move checkin = sk.getInputStream(); to before the loop. There's no reason to get the strem every cycle through the loop.
Do not create the BufferedReader every cycle through the loop. Move it before the loop
.sleep(2000) does not guarantee exactly 2 seconds.
I'm having some code formatting issues so I apologize.
private class DownloadFilesTask extends AsyncTask<Void, String, Void> {
protected Long doInBackground(Void... nothing) {
try {
sk=new Socket(server,port);
publishProgress("connected");
flag = true;
} catch (UnknownHostException e) {
publishProgress("failed 1 socket");
flag = false;
} catch (IOException e) {
publishProgress("failed 2 socket");
flag = false;
}
while (flag == true){
try {
checkin = sk.getInputStream();
checkint = checkin.available();
if (checkint > 0){
try {
BufferedReader in = new BufferedReader(new InputStreamReader(sk.getInputStream()));
received = in.readLine();
publishProgress(received);
} catch (IOException e) {
publishProgress("failed to receive");
}
}
Thread.sleep(2000);
} catch (IOException e) {
updateProgress(
} catch (InterruptedException e) {
e.printStackTrace();
}
return;
}
protected void onProgressUpdate(String... progress) {
viewsurface.setText(progress[0]);
}
protected void onPostExecute(Void result) {
//nothing
}
}