In an app I am making people can download a PDF file. On my Nexus 5 there is on problem when downloading the PDF but on an HTC One X I get an Out of Memory error. How can I avoid this? The code I am using is:
#Override
protected Boolean doInBackground(String... params) {
String fileUrl = params[0];
mFileName = params[1];
mFolder = new File(mContext.getFilesDir(), "pdfs");
mFolder.mkdir();
Random r = new Random();
int i1 = r.nextInt(99 - 10) + 99;
mFile = new File(mFolder, mFileName + "." + i1);
try {
mFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
try {
System.gc();
URL url = new URL(fileUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(mFile);
int totalSize = urlConnection.getContentLength();
byte[] buffer = new byte[MEGABYTE];
int bufferLength = 0;
long total = 0;
while((bufferLength = inputStream.read(buffer))>0 ){
total += bufferLength;
int progress = (int)((total * 100) / totalSize);
publishProgress(progress, (int)total, totalSize);
fileOutputStream.write(buffer, 0, bufferLength);
}
fileOutputStream.close();
return true;
} catch (FileNotFoundException e) {
mFile.delete();
e.printStackTrace();
} catch (MalformedURLException e) {
mFile.delete();
e.printStackTrace();
} catch (IOException e) {
mFile.delete();
e.printStackTrace();
}
return false;
}
#Override
protected void onPostExecute(Boolean success) {
if(mOnDownloadListener != null) {
File to = new File(mFolder, mFileName);
mFile.renameTo(to);
mOnDownloadListener.onDownloaded(success);
}
super.onPostExecute(success);
}
Related
I want to render a pdf which in the raw folder with ParcelFileDescriptor tried too many methods from the other posts but none of them worked for me. Below is the code
I copied the code from the post you suggested and modified my code but still pdf is not opening even its showing no error.
public void render()
{
try
{
imgv = (ImageView) findViewById(R.id.img);
int w = imgv.getWidth();
int h = imgv.getHeight();
Bitmap bm = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_4444);
File fileBrochure = new File(Environment.getExternalStorageDirectory() + "/" + "abcd.pdf");
if (!fileBrochure.exists())
{
CopyAssetsbrochure();
}
/** PDF reader code */
File file = new File(Environment.getExternalStorageDirectory() + "/" + "abcd.pdf");
// File file = new File("android.resource://com.nyt.ilm.mytestpdfreader/raw/abcd.pdf");
PdfRenderer render = new PdfRenderer(ParcelFileDescriptor.open(file,ParcelFileDescriptor.MODE_READ_ONLY));
if (CurrentPage < 0)
{ CurrentPage =0;
}
else if (CurrentPage > render.getPageCount()){
CurrentPage = render.getPageCount() - 1;
}
Matrix m = imgv.getImageMatrix();
Rect rect = new Rect(0,0,w,h);
render.openPage(CurrentPage).render(bm,rect,m,PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
imgv.setImageMatrix(m);
imgv.setImageBitmap(bm);
imgv.invalidate();
}
catch (Exception e)
{
e.printStackTrace();
}
}
//method to write the PDFs file to sd card
private void CopyAssetsbrochure() {
AssetManager assetManager = getAssets();
String[] files = null;
try
{
files = assetManager.list("");
}
catch (IOException e)
{
Log.e("tag", e.getMessage());
}
for(int i=0; i<files.length; i++)
{
String fStr = files[i];
if(fStr.equalsIgnoreCase("abcd.pdf"))
{
InputStream in = null;
OutputStream out = null;
try
{
in = assetManager.open(files[i]);
out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/" + files[i]);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
break;
}
catch(Exception e)
{
Log.e("tag", e.getMessage());
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
This is my doInBackground method:
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
HttpURLConnection conection = null;
BufferedOutputStream bout = null;
FileOutputStream fos = null;
int downloaded = 0;
try {
URL url = new URL(sUrl[0]);
conection = (HttpURLConnection)url.openConnection();
int lenghtOfFile = conection.getContentLength();
if(STATUS) {
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/myapp.apk");
if (file.exists()) {
downloaded = (int) file.length();
conection.setRequestProperty("Range", "bytes=" + (file.length()) + "-");
}
}
else {
conection.setRequestProperty("Range", "bytes=" + downloaded + "-");
}
conection.setDoInput(true);
conection.setDoOutput(true);
conection.connect();
input = new BufferedInputStream(url.openStream(), 8192);
fos=(downloaded==0)? new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/myapp.apk"): new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/myapp.apk",true);
bout = new BufferedOutputStream(fos, 1024);
byte data[] = new byte[1024];
long total = 0;
int count = 0;
while ((count = input.read(data, 0, 1024)) >= 0) {
if (isCancelled()) {
input.close();
return null;
}
bout.write(data, 0, count);
downloaded += count;
publishProgress((int)(downloaded * 100/ lenghtOfFile) );
total += count;
}
bout.flush();
input.close();
fos.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
if (fos != null)
fos.close();
if (bout != null)
bout.close();
} catch (IOException ignored) {
}
if (conection != null)
conection = null;
}
return null;
}
I start download task with this code (resume flag is false -> STATUS = FALSE):
dt = new DownloadTask(DownloadsActivity.this, false);
dt.execute("myurl.something.apk");
then when downloaded completely I launch apk file and all thing work correctly and apk installed correctly. But when pause my download with this code:
dt.cancel(true);
and then resume it with this code (resume flag is true-> STATUS = TRUE):
dt = new DownloadTask(DownloadsActivity.this, true);
dt.execute("myurl.something.apk");
This time apk size is equal to last downloaded before pause + apk total size, therefore my apk file is corrupted. Which means connection.setRequestProperty() not working for me. What is my code problem? Thanks in advance.
i have An Error while download PDF file From Server and save it on SD
i have permission To Access internet and external storage ..
It`s working fine on android 2.3.6
But on Tab 4.1.1 its create the file with 0 byte
URL url = new URL("https://docs.google.com/"+direct);
//create the new connection
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Content-Type", "application/xml");
urlConnection.setDoOutput(true);
//and connect!
urlConnection.connect();
//set the path where we want to save the file
//in this case, going to save it on the root directory of the
//sd card.
File SDCardRoot = new File(Environment.getExternalStorageDirectory().getAbsoluteFile()+"/folder/");
//create a new file, specifying the path, and the filename
//which we want to save the file as.
File file = new File(SDCardRoot,book.getBook_name()+".pdf");
//this will be used to write the downloaded data into the file we created
FileOutputStream fileOutput = new FileOutputStream(file);
//this will be used in reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file
totalSize = urlConnection.getContentLength();
//variable to store total downloaded bytes
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0; //used to store a temporary size of the buffer
//now, read through the input buffer and write the contents to the file
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
//add the data in the buffer to the file in the file output stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
//add up the size so we know how much is downloaded
downloadedSize += bufferLength;
//this is where you would do something to report the prgress, like this maybe
publishProgress((downloadedSize*100)/totalSize);
}
//close the output stream when done
fileOutput.close();
//catch some possible errors...
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Try this:
private String getExternalSDPath() {
File file = new File("/system/etc/vold.fstab");
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(file);
} catch (FileNotFoundException e) {
// handle
}
String path = null;
try {
if (fr != null) {
br = new BufferedReader(fr);
String s = br.readLine();
while (s != null) {
if (s.startsWith("dev_mount")) {
String[] tokens = s.split("\\s");
path = tokens[2]; // mount_point
if (Environment.getExternalStorageDirectory()
.getAbsolutePath().equals(path)) {
break;
}
}
s = br.readLine();
}
}
} catch (IOException e) {
// handle
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
} catch (IOException e) {
// handle
}
}
return path;
}
The code is made specifically for Samsung Devices with both internal, an internal that acts as external, and SD.
I needed to access the SD and came up with the above code, so you can try it and possibly modify it to work on all devices.
Edit: My download AsyncTask
private class DownloadFile extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String filename = "somefile.pdf";
HttpURLConnection c;
try {
URL url = new URL("http://someurl.com/" + filename);
c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
} catch (IOException e1) {
return e1.getMessage();
}
File myFilesDir = new File(Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/Download");
File file= new File(myFilesDir, filename);
if (file.exists()) {
file.delete();
}
if ((myFilesDir.mkdirs() || myFilesDir.isDirectory())) {
try {
InputStream is = c.getInputStream();
FileOutputStream fos = new FileOutputStream(myFilesDir
+ "/" + filename);
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
} catch (Exception e) {
return e.getMessage();
}
} else {
return "Unable to create folder";
}
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG)
.show();
super.onPostExecute(result);
}
}
Here's the code to download a 3pg video file. Maybe one can give me an idea about what's wrong with it. I really need help. Can't get it to download the file:
Blockquote
protected String doInBackground(String... sUrl) {
byte[] data = new byte[1024];
int count = 0;
FileOutputStream fos = null;
BufferedOutputStream output = null;
try {
URL url= new URL(sUrl[0]);
URLConnection connection = url.openConnection();
connection.connect();
Log.v("URL"," " + connection.getURL());
Log.v("File ", "length = " + connection.getContentLength());
// download the file
BufferedInputStream input = new BufferedInputStream(connection.getInputStream());
File f = new File(Environment.getExternalStorageDirectory().getPath() + "/twokids.3gp");
f.setWritable(true,true);
try {
fos = new FileOutputStream(f);
} catch (FileNotFoundException fnfe) {
fnfe.getStackTrace();
} catch (SecurityException se) {
se.getStackTrace();
}
output = new BufferedOutputStream(fos);
while ((count = input.read(data)) != -1) {
Log.v("Count="," " + count);
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
Log.v("Download","Finished");
} catch (IndexOutOfBoundsException iobe) {
iobe.getStackTrace();
} catch (IOException ioe) {
ioe.getStackTrace();
} catch (NullPointerException npe) {
npe.getStackTrace();
}
catch (Exception e) {
e.getStackTrace();
}
return null;
}
And strangely enough, sometimes the method connection.getContentLength() returns -1 instead of the file length.
Im reading image url from a Array list in doInBackground using for loop , but loop is not incrementing only 1st url is loading and saving image . here is code :
class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
// This class definition states that DownloadImageTask will take String
// parameters, publish Integer progress updates, and return a Bitmap
#SuppressWarnings("unused")
protected Bitmap doInBackground(Void... paths) {
//URL url;
try {
for(int j=0; j<List.size();j++)
{
reviewImageLink =List.get(j).get(TAG_Image);
URL url = new URL(reviewImageLink);
// URL reviewImageURL;
String name = reviewImageLink.substring(reviewImageLink .lastIndexOf("/") + 1,reviewImageLink.length());
//try {
if (!hasExternalStoragePublicPicture(name)) {
isImage = false;
//new DownloadImageTask().execute();
Log.v("log_tag", "if");
isImage = true;
File sdImageMainDirectory = new File(Environment.getExternalStorageDirectory(), getResources().getString(R.string.directory));
//if(!sdImageMainDirectory.exists()){
sdImageMainDirectory.mkdirs();
File file = new File(sdImageMainDirectory, name);
Log.v("log_tag", "Directory created");}
//}
// catch (MalformedURLException e) {
// Log.v(TAG, e.toString()); }
// }
// }//try
// catch (Exception e) {
// e.printStackTrace();}
//url = new URL(List.get(j).get(TAG_Image));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
int length = connection.getContentLength();
InputStream is = (InputStream) url.getContent();
byte[] imageData = new byte[length];
int buffersize = (int) Math.ceil(length / (double) 100);
int downloaded = 0;
int read;
while (downloaded < length) {
if (length < buffersize) {
read = is.read(imageData, downloaded, length);
} else if ((length - downloaded) <= buffersize) {
read = is.read(imageData, downloaded, length- downloaded);
} else {
read = is.read(imageData, downloaded, buffersize);
}
downloaded += read;
setProgress((downloaded * 100) / length);
}
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0,length);
if (bitmap != null) {
Log.i(TAG, "Bitmap created");
} else {
Log.i(TAG, "Bitmap not created");
}
is.close();
return bitmap;
}
}catch (MalformedURLException e) {
Log.e(TAG, "Malformed exception: " + e.toString());
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.toString());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.toString());
}
return null;
}
protected void onPostExecute(Bitmap result) {
String name = reviewImageLink.substring(reviewImageLink.lastIndexOf("/") + 1,reviewImageLink.length());
if (result != null) {
hasExternalStoragePublicPicture(name);
saveToSDCard(result, name);
isImage = true;
} else {
isImage = false;
}
}
}
List is an interface, you can't use like List.size().Define one List subtype like ArrayList or something.There is no wrong with for loop.For ex:
List<Integer> li = new ArrayList<Integer>();
li.add(10);
li.add(20)';
for(int i = 0; i <= li.size(); ++i) {
//your stuff
}