I'm trying to create an image file on sd-card, building it from the bytes that a server is sending towards me after calling a web-service (basically: download file).
I managed to get "something" on the client-side, and try to write those bytes to a file, using:
FileOutputStream fOut = null;
BufferedOutputStream bOs = null;
try {
fOut = new FileOutputStream(returnedFile);
bOs = new BufferedOutputStream(fOut);
bOs.write(bytesToWrite);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if (bOs != null) {
bOs.close();
fOut.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
but the image file is broken (its size is > 0kb, but broken).
I ended up opening that file on my computer with a text editor, and I saw that some of the initial file data (before being sent), differs from the final one. So I'm guessing that there is some kind of encoding misstakening or something like that.
I would appreciate an idea of how to make this work ( download image file from a web server, and open in on my phone).
PS. I can also change or get info about the server configuration, as it was configured by a friend of mine.
PS2. I should be able not to download only images, but any kind of file.
I think It's better you encode the image to Base64 in your server, for example in PHP you can do it like this :
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
And then in android you decode the Base64 string into your image file:
FileOutputStream fos = null;
try {
if (base64ImageData != null) {
fos = context.openFileOutput("imageName.png", Context.MODE_PRIVATE);
byte[] decodedString = android.util.Base64.decode(base64ImageData, android.util.Base64.DEFAULT);
fos.write(decodedString);
fos.flush();
fos.close();
}
} catch (Exception e) {
} finally {
if (fos != null) {
fos = null;
}
}
First of all make sure you have this permissions on your android manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
File stream is designed to work on local file storage rather than network connection. Use URLConnection class instead.
URL uri = new URL("Your Image URL");
URLConnection connection = uri.openConnection();
InputStream stream = connection.getInputStream();
//DO other stuff....
Related
I'm trying to send PNG file from my android server to my python client.
The PNG image I try to send is a screenshot, around 4mb tops, usually under 2mb.
android code (sending):
File myFile = new File(imagePath);
FileInputStream fis = null;
try {
fis = new FileInputStream(myFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedInputStream bis = new BufferedInputStream(fis);
Log.i("service", "sending file len");
try {
out.write("" +myFile.length());
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
Log.i("service:", "waiteing for ok");
try {
msg = in.readLine();
} catch (Exception e) {
e.printStackTrace();
}
Log.i("service", "sending file");
byte[] outBuffer = new byte[(int) myFile.length()];
try {
bis.read(outBuffer, 0, outBuffer.length);
os = client.getOutputStream();
os.write(outBuffer, 0, outBuffer.length);
} catch (IOException e) {
e.printStackTrace();
}
python code (receiving):
print "waiting for responce's length"
MSGLEN = int(sock.recv(bufferLen))
print MSGLEN
sock.sendall("ok" +"\n")
chunks = []
bytes_recd = 0
while bytes_recd < MSGLEN:
chunk = sock.recv(min(MSGLEN - bytes_recd, bufferLen))
chunks.append(chunk)
bytes_recd = bytes_recd + len(chunk)
dataRecived = ''.join(chunks)
print 'data receieved'
print 'writing data to file'
fileout = open("D:\shots.png", 'w')
fileout.write(dataRecived)
fileout.close()
The file transfers from the android to my PC, but the file is corrupted.
When I compare it with the original image, almost everything is identical
except some empty lines here and there (not missing information, just empty line like someone added \n) and 1 or 2 big chunks of lines (15 lines or so) are missing.
Here you can see comparison between the tho files (left-original, right-file after sending).
I don't know why the file transfers corrupted, please help me.
Try coding it as Base64 and sending a simple string. Those missing lines are also part of image data - remember that those are binary.
Base64 or Bytestream is what u need
I can pass sdcard location to my adb command using
file:///sdcard/Android/screen.bmp
What is the equivalent string, if my file is saved in phone memory instead of sdcard, will it be
file:///phone/Android/screen.bmp
That isn't necessarily how you access things saved internally on your phone.
Keep in mind how you save an image to internal storage:
Bitmap bitmap = ______; //get your bitmap however
try {
FileOutputStream fos = context.openFileOutput("desiredFilename.png", Context.MODE_PRIVATE);
image.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (Exception e) {
Log.e("saveToInternalStorage()", e.getMessage());
Log.e("Saving the bitmap",e.getMessage());
}
Now, to go read it, we just get the context, and call getFileStreamPath(filename) on it.
Bitmap retrievedImage;
String filename = "desiredFilename.png";
try {
File filePath = context.getFileStreamPath(filename);
FileInputStream fi = new FileInputStream(filePath);
retrievedImage = BitmapFactory.decodeStream(fi);
} catch (Exception e) {
Log.e("Retrieving the image", e.getMessage());
}
You can read more about this here.
I am downloading image via a URL using loopj library https://github.com/loopj/android-async-http. In response I get image as File object. I want to store this image as .jpg to my internal storage and get the path of that image. Can anyone please help me regarding this? Or suggest me any other library or the code through which I can achieve this functionality?
Try :
try {
File imgFile = null; //File you received from loopj
FileInputStream fis = new FileInputStream(imgFile);
FileOutputStream fos = new FileOutputStream(
new File("yourPath.jpg"));
byte fileContent[] = new byte[(int) imgFile.length()];
fis.read(fileContent);
fos.write(fileContent);
fis.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
I am trying to retrieve a file via FTP but I am getting the following error in LogCat:
java.io.FileNotFoundException :/config.txt (read-only file system)
I have verified that the file exists on the server, and I can read it by double clicking it in a web browser.
Can anyone help please? Here is the code I am using:
FTPClient client = new FTPClient();
FileOutputStream fos = null;
try {
client.connect("xxx.xxx.xxx.xxx");
client.enterLocalPassiveMode();
client.login("user", "pass");
//
// The remote file to be downloaded.
//
String filename = "config.txt";
fos = new FileOutputStream(filename);
//
// Download file from FTP server
//
client.retrieveFile("/" + filename, fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
You cannot save files on the root of the phone. Use Environment.getExternalStorageDirectory()to get an file object of the SD card's directory and save the file there. Maybe create a directory for it. To do that you need the permission android.permission.WRITE_EXTERNAL_STORAGE.
Sample code:
try {
File external = Environment.getExternalStorageDirectory();
String pathTofile = external.getAbsolutePath() + "/config.txt";
FileOutputStream file = new FileOutputStream(pathTofile);
} catch (Exception e) {
e.printStackTrace();
}
You are trying to read the file in, but you have created an OutputStream, you need to create an inputStream and then read the file from that input stream.
Here is a great article, with come code that is very helpful. This should get you headed in the right direction.
http://www.roseindia.net/java/beginners/java-read-file-line-by-line.shtml
I hope this helps!
Best of luck
I've designed quickly a piece of code which loads from an specified URL and then saves it to the SD card, however it is not saving to the SD.
URL myFileUrl = new URL( Image_HTML);
String filepath = Environment.getExternalStorageDirectory().getAbsolutePath();
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bm = BitmapFactory.decodeStream(is);
FileOutputStream fos = new FileOutputStream(filepath+image_name);
bm.compress(CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
bm = BitmapFactory.decodeFile(filepath+image_name);
image_loader_view.setImageBitmap(bm);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.i("Hub", "FileNotFoundException: "+ e.toString());
} catch (IOException e) {
e.printStackTrace();
Log.i("Hub", "IOException: "+ e.toString());
}
I have tried to make this code as lightweight as possible, and I have also activated the EXTERNAL.STORAGE.WRITE in the android manifest.
Couple things.
When you use a FileOutputStream you have to make sure the directory you are trying to write to is created before you try to write a file to it. If not you have to create it. This can be done via mkdirs() method of the File class.
Next I'm not sure the call to getAbsolutePath is required, due to the type of file system Android uses. I've never had to use it to save to SD before.
I'd try these and see if one of them will solve it for you.