Upload Xml file to internet via FTP - java

I'm developing a game in Android. The game has many levels and a Level Editor. So when a user make a level, the data are saving as Xml file. So I want to upload this Xml file to internet to share the other users. I searhed and tried these below codes. But It didn't work. The whole code like this:
String FTP_HOST= "185.27.134.11";
String FTP_USER = "fees0_14042425";
String FTP_PASS ="kadi1sd22";
File f = new File(Environment.getExternalStorageDirectory()+"/kadirGameLevels1/a.png");
FTPClient client = new FTPClient();
try {
client.connect(FTP_HOST,21);
client.login(FTP_USER, FTP_PASS);
client.setType(FTPClient.TYPE_BINARY);
client.changeDirectory("/levels/");
client.upload(f, new MyTransferListener());
} catch (Exception e) {
e.printStackTrace();
try {
client.disconnect(true);
} catch (Exception e2) {
e2.printStackTrace();
}
}
But even if I only use this single line, it still stop running. Did I something wrong with is integration or anything else?
FTPClient client = new FTPClient();

Make sure you have the INTERNET permission in your AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
This makes sure your app has the right permission to access the internet.
Also don't put any networking code in the main UI thread or you will likely get a NetworkOnMainThreadException.
Instead put all your FTP-connecting/accessing code into an AsyncTask: https://stackoverflow.com/a/6343299/833647

Related

Unable to copy a database on Android

I have permissions for read and writing on AndroidManifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
... because I want to copy one file. I'm performing this process in two steps:
1. Launching an Intent so the user creates the file where he wants:
This code is mostly the example of the Android developers site.
private void createFile() {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/vnd.sqlite3");
intent.putExtra(Intent.EXTRA_TITLE, "test.db");
startActivityForResult(intent, CREATE_FILE);
}
2. Copy the file.
The intent returns a Uri, so inside the onActivityResult:
try {
destinationOutputStream = getContentResolver().openOutputStream(data.getData());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
(where data is the Intent), I'm able to get the output stream.
Finally, and according to the documentation, I should be able to copy the file:
try {
Long totalBytes = Files.copy(originalPath, destinationOutputStream);
} catch (IOException e) {
e.printStackTrace();
}
(where originalPath is the path (of type Path) where the original file is stored).
But, on runtime, I'm getting the following error:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

Java Android FTP Upload Issue & "Async"

I am attempting to upload via ftp a file, named "advancedsettings.xml" located in path "/storage/emulated/0/advancedsettings.xml" from my Android device. It doesn't seem to be working; the file does not upload and the following exception is thrown:
01-06 17:56:17.498 28084-28084/com.name.example.appname E/SmsReceiverīš• android.os.NetworkOnMainThreadException
I discovered that basically, an application cannot attempt to perform a networking operation "on its main thread".
I am new at Java but I understand, following from this, I must implement "ASync"; I haven't understood how to implement it. Could somebody help describe this to me and how I might implement it in respect of the below code?
My code is as follows:
public class FtpUpload {
// use this method to upload the file using file path global var and ftp code,
//then return the link string.
//TO DO: UID file name to prevent file already exists overwrite on server?
public void total() {
FTPClient con = null;
String dest_fname = "advancedsettings.xml"; // Added to create a destination file with a dynamically created name (same as the file name in /sdcard/ftp/)
try
{
con = new FTPClient();
con.connect("ftp.domain.co.uk");
// Check your USERNAME e.g myuser#mywebspace.com and check your PASSWORD to ensure they are OK.
if (con.login("username", "password"))
{
con.enterLocalPassiveMode(); // important!
con.setFileType(FTP.BINARY_FILE_TYPE);
String data = "/storage/emulated/0/advancedsettings.xml";
FileInputStream in = new FileInputStream(data);
boolean result = con.storeFile(dest_fname, in);
in.close();
if (result) Log.v("upload result", "succeeded");
con.logout();
con.disconnect();
} else { // This Error Log was created
// Create error log as a file
File log_file = new File("/storage/emulated/0/error.txt");
try {
FileWriter lfw = new FileWriter(log_file);
BufferedWriter lout = new BufferedWriter(lfw);
// Continue
lout.write("Upload Connection Failed!");
lout.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
Log.e("SmsReceiver", e1.toString());
}
}
}
catch (Exception e)
{
Log.e("SmsReceiver", e.toString());
}
}
Thank you in advance.
K
Shamefully I didn't initially come across this documentation on Async Tasks, which has proven invaluable.
With a bit of improv though, I got it working. I just modified my class as such:
private class FtpUpload extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
//code here
}
And used the following to call the above Async method:
new FtpUpload().execute();
Of course, you won't get very far with FTP networking without declaring the following user permissions in your manifest file (outside of the "application" tags):
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Limit web service access to only one app

Right now I am working on a android app and I am totally new to this.
I want to make sure my web-service is only accessible via my app.
My background is PHP. In PHP I don't need to worry about anything like that, because everything runs on a server.
In case of Java and especially Android programming things are different. Even with encryption. Everybody can just open an APK and see how the web service gets accessed. So is there a way to hide or to obfuscate the access to a web service, so only my app will be able to use it?
For test purposes I didn't add any security or encryption. This is the basic call to a web server I am doing right now:
String url = "http://thisismyurl.com/a.php?action=get";
String result = Web.executeWeb(url);
public class Web {
public static String executeWeb(final String url) {
final StringBuilder sb = new StringBuilder();
Thread thread = new Thread(new Runnable() {
public void run()
{
try
{
InputStream is = (InputStream) new URL(url).getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String result, line = reader.readLine();
result = line;
while((line=reader.readLine())!=null){
result+=line;
}
sb.append(result);
//System.out.println(result);
//Log.i("My Response :: ", result);
} catch (Exception e)
{
// TODO: handle exception
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sb.toString();
}
}
How would I hide this from the prying eyes of hackers? ;-) Is that even possible?
Thanks in advance!
Deploy client authentication using (self signed) certificates within TLS.
This kind of configuration can be enabled on most web servers and Java application servers, and you can normally also configure the web or application server in such a way that you can retrieve the certificate of the private key that the client used to authenticate itself.
Note that HTTPS uses SSL (or now TLS) before any web trafic, so you cannot program this in your application, it does require server configuration.
Check this link on how to configure for Apache 2.
Use your Application's ID ( like IMEI ) as parameter in your webservice call. You need to make a table in database at server side which will store all registered device. Now only these registered device can access your webservice. This is my idea, there should be other idea as well.

open failed: EACCES (Permission denied) Reading PNG Even Though I Have Permission

In my app I am adding a Share button through the ShareActionProvider class. I am trying to share a PNG which I pull from the file system. The problem is I get the following error thrown at me when I try to share it with the stock messaging app
com.google.android.mms.MmsException: /data/data/com.frostbytedev.wifiqr/files/QRCode.png: open failed: EACCES (Permission denied)
At first I thought it was my permissions but I have the following permissions in my Manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
The place where I try to get it from the file system is here:
Uri uri = Uri.fromFile(new File(getFilesDir(), "/QRCode.png"));
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM,uri);
provider.setShareIntent(intent);
If you were wondering, he is the code where I save the image
String fileName = getFilesDir() + "/QRCode.png";
etSSID.setText(fileName);
OutputStream stream = null;
try {
stream = new FileOutputStream(fileName);
bmp.compress(Bitmap.CompressFormat.PNG, 80, stream);
stream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
How can I solve this issue?
if /data/data/com.frostbytedev.wifiqr is your app's private directory then yes, your app has permission to read that file. You don't even need the WRITE_EXTERNAL_STORAGE permission because it's "your" directory.
But once you share it with another app, that app needs permission to read the file as well. And that's per default not the case with files inside your app private directory. The error you get is from the MMS app having no access.
A simple way to fix the problem is to save the file to a place that can be read by every app. Essentially everything in Environment.getExternalStorageDirectory().
The next possibility is to make that file readable for other apps but keep it where you have it. File#setReadable(true, false) should do that.
Context also has nice methods to simplify creating files in readable mode.
String fileName = getFileStreamPath("QRCode.png").getPath();
etSSID.setText(fileName);
OutputStream stream = null;
try {
stream = openFileOutput("QRCode.png", Context.MODE_WORLD_READABLE);
bmp.compress(Bitmap.CompressFormat.PNG, 80, stream);
stream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
...
Uri uri = Uri.fromFile(getFileStreamPath("QRCode.png"));
.. share

Why uploaded file through Apache FTPClient is smaller then original file on the local?

I am uploading files(.cvs,.zip,.rar,.doc,.png,.jpg...) to ftp server. The strange is everything is successfully but I miss some data.
Does any body know why it happens and how to fix it?
public static void uploadWithCommonsFTP(File fileToBeUpload) {
FTPClient f = new FTPClient();
try {
f.connect(server.getServer());
f.login(server.getUsername(), server.getPassword());
f.changeWorkingDirectory("user");
f.setFileType(FTP.BINARY_FILE_TYPE);
f.setFileTransferMode(FTP.BINARY_FILE_TYPE);//this is part of Mohammad Adil's solutions
f.enterLocalPassiveMode();
ByteArrayInputStream in = new ByteArrayInputStream(FileUtils.readFileToByteArray(fileToBeUpload));
boolean reply = f.storeFile(fileToBeUpload.getName(), in);
if(!f.completePendingCommand()) {
f.logout();
f.disconnect();
System.err.println("File transfer failed.");
System.exit(1);
}
if(reply){
JOptionPane.showMessageDialog(null,"uploaded successfully.");
}else{
JOptionPane.showMessageDialog(null,"Upload failed.");
}
}
//Logout and disconnect from server
in.close();//this is part of Mohammad Adil's solutions
f.logout();
f.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
It's often forgotten that FTP has two modes of operation - one for text files and the other for binary(jpg,csv,pdf,zip) files.
Your code doesn't work because the default transfer mode for FTPClient is FTP.ASCII_FILE_TYPE. You just need to update the configuration to transfer in binary mode.
Add this in your code :
f.setFileTransferMode(FTP.BINARY_FILE_TYPE);
just put that line after f.setFileType(FTP.BINARY_FILE_TYPE);
and it should work then.
EDIT:
You are not closing inputStream in your code,Just call in.close() before calling logout()

Categories