I am an amateur in android coding.
I am trying to setup an android app with the ability to download a file from an ftp server. While running the code on the android 2.2 emulator, i am able to connect to the ftp server but the downloading part is showing an error. LogCat gives "download failed".
package com.ftconnect.down;
import java.io.FileOutputStream;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import org.apache.commons.net.ftp.*;
public class FTPConnectActivity extends Activity {
/** Called when the activity is first created. */
public FTPClient mFTPClient = null;
public boolean mConnect;
public boolean mDownload;
public boolean mDisconnected;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mConnect = ftpConnect("xxx.xxx.xxx.xxx", "admin",
"123456", 21);
mDownload = ftpDownload("xxx.xxx.xxx.xxx/ftp.mp3", "/sdcard");
mDisconnected = ftpDisconnect();
}
public boolean ftpConnect(String host, String username, String password,
int port) {
try {
mFTPClient = new FTPClient();
// connecting to the host
mFTPClient.connect(host, port);
Log.d("ftpConnectApp", "Connecting to " + host);
// now check the reply code, if positive mean connection success
if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
// login using username & password
boolean status = mFTPClient.login(username, password);
return status;
}
} catch (Exception e) {
Log.d("ftpConnectApp", "Error: could not connect to host " + host);
}
return false;
}
public boolean ftpDownload(String srcFilePath, String desFilePath) {
boolean status = false;
try {
FileOutputStream desFileStream = new FileOutputStream(desFilePath);
;
status = mFTPClient.retrieveFile(srcFilePath, desFileStream);
desFileStream.close();
return status;
} catch (Exception e) {
Log.d("ftpConnectApp", "download failed");
}
return status;
}
public boolean ftpDisconnect() {
try {
mFTPClient.logout();
mFTPClient.disconnect();
return true;
} catch (Exception e) {
Log.d("ftpConnectApp",
"Error occurred while disconnecting from ftp server.");
}
return false;
}
}
I have setup the internet and write external permission in the android manifest file. Should i include any other permissions?
Also, let me know if there is any changes to be made to the code above. Is the destination address as '/sdcard' correct?
Thanks in advance.
You need to add Exception variable in your log message. You may also want to print full stack trace of the problem using:
e.printStackTrace();
Generally /sdcard should work, however it is more reliable to request SD card location using Environment object. See more details about file storage on android in
link
Also, let me know if there is any changes to be made to the code above. Is the destination address as '/sdcard' correct?
At the very least you should use /sdcard/filename.ext although this would only be OK for testing purposes if you are sure that /sdcard is a valid root directory.
To do things correctly, use getExternalFilesDir to find the correct path to the external storage 'files' directory that can be used for 'private' files for your own app. See the example code in that link for how to use it. You'll need to provide a filename for the output stream not just a path to a directory.
This may not be the answer to your problem but simply using...
FileOutputStream desFileStream = new FileOutputStream(desFilePath);
...when desFilePath is a directory, i.e., /sdcard, and not a file is guaranteed to fail.
Use
mFTPClient.enterLocalActiveMode();
after login
Related
I'm trying to connect my Android application to my company local network (Windows) using smb protocol. The problem is I'm kinda newbie on this matter and something is missing me.
The goal is download the file AREQA.txt from the network to the device. However I don't even can verify if the code can trace the file location because the application crashes when I compile it to the device (it loads fine but crashes when I call the DownLoadF001 procedure). Here's the code:
public void DownLoadF001(View v) {
jcifs.Config.registerSmbURLHandler();
String user;
String password;
String filename;
File localFile;
SmbFile path = null;
try {
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(null,"######", "********");
path = new SmbFile("smb:\\192.168.1.11/.../AREQA.txt", auth);
try {
if(path.exists()){
Toast.makeText(getApplicationContext(), "Sucesso!", Toast.LENGTH_LONG).show();
}
} catch (Exception e1) {
Toast.makeText(getApplicationContext(), e1.toString(), Toast.LENGTH_LONG).show();
}
} catch (MalformedURLException e2) {
Toast.makeText(getApplicationContext(), e2.toString(), Toast.LENGTH_LONG).show();
}
}
I already tried to remove the inside try from the main one (with all its associated code), and the application stops crashing. However, without it, I can't see if the connection is working.
EDIT: I managed to catch the error (Exception e1):
java.lang.NullPointerException: Attempt to invoke virtual method int java.lang.String.length()' on a null object reference. Any ideas to solve it?
Also, as pointed by #greenapps, I'm calling this procedure from a .xml button by onClick method.
I am writing because I created a computer base application that simple store data in a sqlite database, I used java through eclipse, the problem is that the application works fine on the pc that it was built on as a jar file, but when I distribute the application to my people I get this message on their computer
java.sql.SQLException path to c:user//usuario/documents/school.sqlite does not exist
The question is . How to change the code tomake the application also work in other computers as well and not only on the pc that it was built on?
here is the code I used
import java.sql.*;
import javax.swing.*;
public class sqlConnection {
Connection conn=null;
public static Connection dbConnector()
{
try{
Class.forName("org.sqlite.JDBC");
Connection conn=DriverManager.getConnection("jdbc:sqlite:C:\\Users\\USUARIO\\Documents\\workspace\\School2015.sqlite");
JOptionPane.showMessageDialog(null, "BIENVENIDO! Estás Conectado");
return conn;
}catch (Exception e)
{
JOptionPane.showMessageDialog(null, e);
return null;
}
}
}
Do not use 'C:\Users\USUARIO\Documents\workspace\School2015.sqlite'
Use relative path instead like ..\..\..\workspace\
or if you need to set up path on runtime use it as String which should be given as input parameter to your program
You can use this code.
import java.sql.*;
import javax.swing.*;
public class sqlConnection {
Connection conn=null;
public static Connection dbConnector()
{
try{
Class.forName("org.sqlite.JDBC");
Connection conn=DriverManager.getConnection("jdbc:sqlite:C:\\Users\\USUARIO\\Documents\\workspace\\School2015.sqlite");
JOptionPane.showMessageDialog(null, "BIENVENIDO! Estás Conectado");
return conn;
}catch (Exception e)
{
JOptionPane.showMessageDialog(null, e);
return null;
}}}
I'm using the library Jamod and I have trouble reading the record, what I want is to read only the record number 300 PLC I'm connected, but I get read error (enters the catch). Thanks for your help
package com.JR.scada;
import java.net.InetAddress;
import net.wimpi.modbus.Modbus;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.ReadInputDiscretesRequest;
import net.wimpi.modbus.msg.ReadInputDiscretesResponse;
import net.wimpi.modbus.msg.ReadMultipleRegistersResponse;
import net.wimpi.modbus.net.TCPMasterConnection;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Main extends Activity{
TextView text, depurar;
EditText IP;
Button boton;
int i=0;
TCPMasterConnection con = null; //the TCP connection
ModbusTCPTransaction trans = null; //the Modbus transaction
InetAddress addr = null; //direccion del esclavo
int port = Modbus.DEFAULT_PORT;//puerto por defecto 502
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.lblRegistro);
IP = (EditText) findViewById(R.id.txtIp);
depurar = (TextView) findViewById(R.id.txtdepurar);
boton = (Button)findViewById(R.id.btnVerRegistro);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
protected void onStop() {
super.onStop();
//Close the TCP connection
con.close();
}
public class conectar extends AsyncTask<String,String,Integer>{
ReadInputDiscretesRequest req = null; //the request
ReadInputDiscretesResponse res = null; //the response
int startReg;
protected void onPreExecute() {
try {
//IP address;
addr = InetAddress.getByName("212.170.50.238");
} catch (Exception e) {
Log.d("MODBUS","IP error", e);
}
}
protected Integer doInBackground(String... urls) {
try {
// Open the connection
con = new TCPMasterConnection(addr);
con.setPort(port);
con.connect ();
try {
startReg = 300;
// Prepare the request
req = new ReadInputDiscretesRequest (startReg, 1);
// Prepare the transaction
trans = new ModbusTCPTransaction(con);
trans.setRequest(req);
// execute the transaction
trans.execute();
// get the response
res = (ReadInputDiscretesResponse) trans.getResponse ();
} catch (Exception e) {
Log.d("MODBUS", "Error in reading/writing");
return 1;
}
} catch (Exception e) {
Log.d("MODBUS","connection error", e);
return 1;
}
return 0;
}
protected void onPostExecute(Integer bytes) {
if(con.isConnected()){
depurar.setText("conecta");
}
text.setText("Digital Inputs Status=" + res.getDiscretes ().toString () );
}
}
public void onClick(View v) {
// int startReg;
conectar conectamos = new conectar();
conectamos.execute("hola");
}
error:
08-21 10:01:57.554: D/MODBUS(3322): Error in reading/writing
Without knowing more about the modbus configuration on your slave PLC, my first suggestion is to try a different value for startReg, and see if the error persists. This will rule out problems with your Java.
Some test numbers that should work: 0,1,7,8
They may not all work, but at least one of them should return successfully.
If none of them return successfully, there may be a problem on the PLC configuration, or a problem with your request code.
If one of the test numbers is successful, you should post your results. If so, this means that you are attempting to access a memory location that does not exist on the PLC. If you access undefined PLC memory locations, often the PLC will abort the request (it does not just send back '0').
Followup remarks:
If you find that your code works when using different values for startReg, but not for 300, the reason has to do with memory mapping on the PLC, and this can be different for each brand/model of PLC (post your PLC brand/model if available).
You say in your question 'record 300'. When working with PLC, you usually don't refer to memory as a record. Are you trying to access Bit 300, Byte 300, Word 300, DoubleWord 300?
The real question you need to be asking, is 300 the actual modbus address you want to read, or is 300 how the PLC address is mapped (such as the 300th I/O slot, not necessarily the 300th WORD). It may be required to convert between octal, decimal, and hexidecimal addresses. Or, you may need to re-index an address (some PLCs like to start counting at 1, but generally modbus starts counting at 0).
Perhaps you meant to read BIT 300 (not record 300), which would then be 12th BIT in the 18th WORD, so it would look like this:
//
startReg = 17;
// Prepare the request
// Your 300th bit should be the last value returned.
req = new ReadInputDiscretesRequest (startReg, 12);
The different values I suggested for startReg are meant to help you discover how your PLC Inputs are mapped into modbus addresses by your Java library. This might help with number conversions.
If you keep getting exceptions in your catch block, you might want to find out more about the error.
Try changing this line from your original code:
try {
//...
} catch (Exception e) {
Log.d("MODBUS", "Error in reading/writing");
return 1;
}
into this:
try {
//...
} catch (Exception e) {
Log.d("MODBUS", e.getMessage() );
return 1;
}
Hopefully the exception will tell you more about exactly why its failing. Post those results.
If you are getting a NULL message, you might try using a debugger to manually inspect your connection instance.
In my application I want to upload video using ftp. I included apache.commons.net library in my application. When I am running the code it shows 04-28 14:56:05.229: ERROR/dalvikvm(739): Could not find class 'org.apache.commons.net.ftp.FTPClient', referenced from method net.jeema.hwdvideoshare.NewVideoActivity$loadVideo.doInBackground.
How to solve this problem? I am using the below code:
protected Void doInBackground(Void... arg0) {
String hostName = "ftp.host.net";
String username = "test";
String password = "test";
String location = selectedPath;
InputStream in = null;
try {
FTPClient ftp = new FTPClient();
ftp.connect(hostName);
ftp.login(username, password);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.changeWorkingDirectory("/uploads");
int reply = ftp.getReplyCode();
System.out.println("Received Reply from FTP Connection:" + reply);
if (FTPReply.isPositiveCompletion(reply)) {
System.out.println("Connected Success");
}
File f1 = new File(location);
in = new FileInputStream(f1);
ftp.storeFile(fname, in);
System.out.println("SUCCESS");
ftp.logout();
ftp.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
When you link de lib do you have to reference it, and mark as a usable one.
maybe you forgot one of the two steps?
Open your app’s Properties dialog, navigate to “Java Build Path”->”Libraries” and add the reference.
Navigate to “Java Build Path”->”Order and Export” and select to export the two jars.
I would like to implement an application to receive a file from a Bluetooth device.
Before receiving, a notification will be raised to accept an incoming file request.
From there, i would like to activate "accept" and download the file automatically without raising an accept dialog when the user receive a second file from another Bluetooth paired device, without notification disturbance when the user launchs an application.
I developed an app that include this kind of task, and you can use BluetoothChat example.
You must set the secure flag to false:
`
boolean secure = false;
try {
if (secure) {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
MY_UUID_SECURE);
} else {
tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
mmServerSocket = tmp;
}`
And then read the buffer from the InputStream that you can find in ConnectedThread:
while (true) {
try {
bytes = mmInStream.read(buffer);
/*write bytes in a file*/
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
BluetoothChatService.this.start();
break;
}
}
You can try using the Bluetooth socket connection to set a client server TCP like connection.
ON ROOTED DEVICES, You can just install only two apps on your phone to achieve your goal.
XPosed Installer
Auto-Accept
This way you hook System service.
import android.util.*;
import de.robv.android.xposed.*;
import de.robv.android.xposed.callbacks.XC_LoadPackage.*;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
public class Tutorial implements IXposedHookLoadPackage
{
private String TAG="TUTORIAL";
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("com.android.bluetooth"))
{
Log.i(TAG,"Not: "+lpparam.packageName);
return;
}
Log.i(TAG,"Yes "+lpparam.packageName);
findAndHookMethod("com.android.bluetooth.opp.BluetoothOppManager", lpparam.classLoader, "isWhitelisted", String.class,new XC_MethodHook() {
#Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.v(TAG,"HOOK DONE");
param.setResult(true); /* you can compare the sender address(String) with your computer and determine if you return true or just allow the original method to be called after this returns.*/
}
});
}
}
For more information, please visit my answer in SO.
I'll post some direct links here.
Links
Dropbox link of the auto accepting app
Dropbox link of the project files (zip)
Xposed apk site
Towelroot site to root your phone
Auto-Accept github repository