I want to download PDF's and images into my app, essentially it will call a JSON web service that returns the link to the PDF, link to the image, and the title. It will download the image and PDF and save them. Then it will display the PDF's and images with the title. My only question is how do I deal with images? They cant be saved to APK since it is locked. The images are high enough resolution that they can scaled down to fit all the other densities, should I just use the large image, and let the activity scale it down when it uses it. Or should I implement an image scaler during the retrieval process?
Eventually the PDF's and images would be loaded into the APK. How would I check the assets folder to remove the images, would I just need to call a service that runs when the Application First starts to check for the files in the assets folder then remove them if they are present?
Sample code for your reference where u can download Images from the web.Its better to store Images in asset folder than Internal Memory and resize the images for good performance.U can delete the folder before making web service call and load new set images.
if (Utility.isWifiPresent()
|| Utility.isMobileConnectionPresent()) {
URL url = new URL(fileUrl);
InputStream iStream = url.openConnection().getInputStream();// .read(data)
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] tmpArray = new byte[1024];
int nRead;
while ((nRead = iStream.read(tmpArray, 0, tmpArray.length)) != -1) {
buffer.write(tmpArray, 0, nRead);
}
buffer.flush();
data = buffer.toByteArray();
FileOutputStream fOut = null;
//path to store
fOut = Utility.getFileOutputStreamForCloud(
sdcardFolderPath, fileUrl);
}
fOut.write(data);
fOut.flush();
fOut.close();
Related
I know a library called libaums and had implemented it, but I don't know how to open Images and Videos using their library.
According to https://github.com/magnusja/libaums, you can actually read a file from the storage using this:
// read from a file
InputStream is = new UsbFileInputStream(file);
byte[] buffer = new byte[currentFs.getChunkSize()];
is.read(buffer);
Then your buffer contains the image data, so you can convert it to e.g. a Bitmap, like this:
Bitmap bmp = BitmapFactory.decodeByteArray(buffer , 0, buffer .length);
After that you can set it to an ImageView or whatever to show it to your user.
To be short, find your File and implement this logic.
I'm using Android-Universal-Image-Loader for downloading image files from my server using .loadImageSync(imageURL) method.
And then I need to save that bitmap to user device external storage.
File file = new File(mContext.getExternalFilesDir(null) + directoryIntermediatePath, fileName);
FileOutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
My issue is .png file on my server holding size of approx 200KB, which will become approx 700KB after this process on android device storage.
You should not save the loaded image to disk. Instead you should use the file as it had been downloaded.
If I got it right the Android-Universal-Image-Loader library uses a disk cache.
If you set a specific DiskCache implementation while building the ImageLoaderConfiguration you should be able to access this DiskCache later and retrieve it later via:
File f = DiskCacheUtils.findInCache(imageURL, diskCache);
Then you only have to copy the file on byte[] level.
You can try reducing the quality parameter in bitmap.compress to some value less than 100. However, for PNG image, which is a lossless format, Bitmap will ignore the quality parameter. So, an option is to convert to JPEG for reduced size. For example, use this line:
bitmap.compress(Bitmap.CompressFormat.JPEG, 60, fileOutputStream);
For more information on bitmap.compress, check here.
If you want to reduce to a specific size using PNG, you'll have to re-scale your image; this SO link may prove useful.
I wrote an android application that part of it is to handle upload and download documents. Currently I am using the Microsoft Azure server to save the files on.
The way I am currently doing it is by turning the files to a string and saving it that way on the Azure server:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis;
try {
fis = new FileInputStream(new File(Uridata.getPath()));
byte[] buf = new byte[1024];
int n;
while (-1 != (n = fis.read(buf)))
baos.write(buf, 0, n);
} catch (Exception e) {
e.printStackTrace();
}
byte[] bbytes = baos.toByteArray();
item.setStringFile(Base64.encodeToString(bbytes, Base64.URL_SAFE));
item.setName(Uridata.getLastPathSegment());
where item is my class that saves the string representation and the name of the file and is being loaded to the Azure, Uridata is an Uri instance of the file chosen.
I have one main problem with this solution and it is the limit on the file size.
I am searching for a good server to use instead of the Azure (maybe a RESET one) and if there is a better way to save files of all kinds (pdf, word...).
I will also want in the future to use the same data in a web interface
Does anybody have any suggestions on how to do it?
Thanks in advance!
To start, you don't have to transform the file into a string, you can just save it as a file. You have the possibility of losing data by continuing to do that. See: How do I save a stream to a file in C#?
If you're looking for another service to save files, then you should look into Azure Blob Storage. It will allow you to upload as much data as you want to a storage service for arbitrary files. See for example:
https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs/
I have a lot of png images in assets folder. I need to use them in app in ImageView and Gallary. Android supports only Bitmaps images. So what is the right way to store files. For example while first run of application it decodes images from png to bmp and saves it somewhere on internal storage , is it possible ? And every start app checks if folder with bmp images exist or not , if exists it uses previously decoded bmp images.
Or there is another way to store a lot of images ?
Any help would be greatly appreciated. Thanks
-4 but 0 answers. Please help
I wan't to call decode method only once on first app start , and than use decoded bmps saved on internal storage .
I think it's not need to decode! Universal Image Loader is a powerful image loader library for android. it can load image from drawables folder, assets, url and ...... this library have cashing system. refer this tutorial.
https://github.com/nostra13/Android-Universal-Image-Loader
Start with:
Converting your largest images from png to jpeg. Jpeg has some disadvantages for a mobile env. but it does produce as smaller image.
Try using png 'reducer' tools like OptiPNG or PNGCrush to reduce png image size. You will usually not see a noticeable difference in image quality.
And, if that does not solve your problem consider zipping all (or at least the largest) of your images into a zip file to be stored in assets/ directory and, at first run, open it to an sdcard folder.
After you do that you will need to populate your ImageViews as follows:
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);
myImage.setImageBitmap(myBitmap);
Which is a pain but if you have no other choice..
Extraction of assets/zip file goes like this:
public void unzipFromAssets(String zipFileInAssets, String destFolder) {
FileInputStream fin = new FileInputStream(zipFileInAssets);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
if(ze.isDirectory()) {
File f = new File(_location + ze.getName());
if(!f.isDirectory()) {
f.mkdirs();
}
} else {
FileOutputStream fout = new FileOutputStream(destFolder + ze.getName());
for (int c = zin.read(); c != -1; c = zin.read()) {
fout.write(c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
}
You will need to work a bit on this method - try..catch, getting path for asserts/ files etc.
Good luck.
My application allows users to take a photo using the camera and save it as their profile picture. There can be only 1 image stored at a time?
Is it a bad idea to use SharedPrefertences for this purpose although I am only storing 1 image? (Converting image to Base64). What are the cons?
If storing the image using shared preferences is not a good idea, what are the alternatives?
I think storing binary data in SharedPreferences is not a good idea. Instead save it to the filesystem. Example for that, if the data is coming from an InputStream:
storeImage( new File(context.getFilesDir().getAbsolutePath() + fileDir),
is,
"profile.png" );
public static void storeImage(
File fileDir,
InputStream inputStream,
String fileName ) throws IOException {
File file = new File( fileDir,fileName );
FileOutputStream fos = new FileOutputStream( file );
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
inputStream.close();
fos.close();
bitmap.recycle();
bitmap = null;
}
Where context can be the Application/Activity context.
There is no reason why you can't use SharedPreferences to store a single image as a Base64 String, Of course this isn't really a scalable approach as when the SharedPreferences are loaded, every image would be loaded into memory at once, but that's not what your looking for.
The other possible approaches you can take is to store the images either using the internal or external storage APIs or to store them in a database
In general for this kind of thing you should be looking to use something other than shared preferences, however in this case, I can't see there been an actual issue to the approach your suggesting.