Download a large pdf with jsoup - java

I would like to download a large pdf file with jsoup. I have try to change timeout and maxBodySize but the largest file I could download was about 11MB. I think if there is any way to do something like buffering. Below is my code.
public class Download extends Activity {
static public String nextPage;
static public Response file;
static public Connection.Response res;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Bundle b = new Bundle();
b = getIntent().getExtras();
nextPage = b.getString("key");
new Login().execute();
finish();
}
private class Login extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
try {
res = Jsoup.connect("http://www.eclass.teikal.gr/eclass2/")
.ignoreContentType(true).userAgent("Mozilla/5.0")
.execute();
SharedPreferences pref = getSharedPreferences(
MainActivity.PREFS_NAME, MODE_PRIVATE);
String username1 = pref.getString(MainActivity.PREF_USERNAME,
null);
String password1 = pref.getString(MainActivity.PREF_PASSWORD,
null);
file = (Response) Jsoup
.connect("http://www.eclass.teikal.gr/eclass2/")
.ignoreContentType(true).userAgent("Mozilla/5.0")
.maxBodySize(1024*1024*10*2)
.timeout(70000*10)
.cookies(res.cookies()).data("uname", username1)
.data("pass", password1).data("next", nextPage)
.data("submit", "").method(Method.POST).execute();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
String PATH = Environment.getExternalStorageDirectory()
+ "/download/";
String name = "eclassTest.pdf";
FileOutputStream out;
try {
int len = file.bodyAsBytes().length;
out = new FileOutputStream(new File(PATH + name));
out.write(file.bodyAsBytes(),0,len);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I hope somebody could help me!

I think, it's better to download any binary file via HTTPConnection:
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL("http://example.com/file.pdf");
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/file_name.extension");
byte data[] = new byte[4096];
int count;
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
Jsoup is for parsing and loading HTML pages, not binary files.

Related

Failed to download pdf file

I want to download this pdf file
https://scholar.najah.edu/sites/default/files/book/dllt-lhwy-wlrmz-fy-lfwlklwr-lshby.pdf
I am using this code to download pdf files, it works fine with many files but it failed on pdf file like above
public void downloadFile(#NonNull String urlStr, #NonNull String fullFilePath,
#NonNull DownloadListener downloadListener) {
cancelStatus = false;
InputStream is = null;
File ffPath = null;
FileOutputStream fos = null;
try {
downloadListener.onProgress(0);
URL url = new URL(urlStr);
URLConnection conexion = url.openConnection();
conexion.setReadTimeout(2000000);
conexion.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5");
System.setProperty("http.agent", "");
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
if (lenghtOfFile <= 0) lenghtOfFile = 1;
is = url.openStream();
ffPath = new File(fullFilePath);
fos = new FileOutputStream(ffPath);
int count = 0;
long total = 0;
int progress = 0;
byte data[] = new byte[1024];
while ((count = is.read(data)) != -1) {
if (cancelStatus == true) {
break;
}
total += count;
int progress_temp = (int) total * 100 / lenghtOfFile;
if (progress != progress_temp) {
progress = progress_temp;
downloadListener.onProgress(progress >= 0 && progress <= 100 ? progress : 0);
}
fos.write(data, 0, count);
cancelStatus = downloadListener.onPacketDownloaded(total, lenghtOfFile);
}
if (is != null) is.close();
if (fos != null) fos.close();
if (lenghtOfFile <= 1) {
downloadListener.onComplete();
} else if (ffPath.length() < lenghtOfFile) {
if (cancelStatus) {
downloadListener.onCancel();
} else {
downloadListener.onError();
}
} else if (ffPath.length() >= lenghtOfFile) {
downloadListener.onComplete();
}
if (cancelStatus == true) {
if (ffPath != null) ffPath.delete();
}
} catch (MalformedURLException e) {
try {
if (is != null) is.close();
if (fos != null) fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
if (ffPath != null) ffPath.delete();
downloadListener.onError();
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
try {
if (is != null) is.close();
if (fos != null) fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
if (ffPath != null) ffPath.delete();
downloadListener.onError();
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
try {
if (is != null) is.close();
if (fos != null) fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
if (ffPath != null) ffPath.delete();
downloadListener.onError();
// TODO Auto-generated catch block
e.printStackTrace();
}
}
the problem is count = is.read(data) return -1 and break from while loop after one loop, the file about 345 kb
please help
/**
* download file used too download the file and save into phone
*
* #param fileURL contain file url
* #param fileName contain file name
*/
public void DownloadFile(String fileURL, String fileName) {
try {
String RootDir = Environment.getExternalStorageDirectory()
+ File.separator + "Cards List";
File RootFile = new File(RootDir);
RootFile.mkdir();
// File root = Environment.getExternalStorageDirectory();
java.net.URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File(RootFile,
fileName + " abc " + ".pdf"));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
Log.d("Error....", e.toString());
}
} // used to download the file from server
class ProgressBack extends AsyncTask<String, Void, Void> {
ProgressDialog PD;
#Override
protected void onPreExecute() {
super.onPreExecute();
PD = ProgressDialog.show(MainActivity.this, null, "Please Wait ...", true);
PD.setCancelable(true);
}
#Override
protected Void doInBackground(String... params) {
DownloadFile("https://scholar.najah.edu/sites/default/files/book/dllt-lhwy-wlrmz-fy-lfwlklwr-lshby.pdf",
"Cards List"); // calling DownloadFile
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
PD.dismiss();
Toast.makeText(MainActivity.this, "Download Completed", Toast.LENGTH_SHORT).show();
}
}

Download function with overwrite

I am doing a function to download files to android device, works fine but I want to do that if the downloaded file exists already in the device will overwrite it. Here is my code:
class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
mProgressDialog.dismiss();
if (result != null){
this.finish();
}
else
{
Descargar.this.finish();
}
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
HttpURLConnection connection = null;
for (i=0; i< sUrl.length; i++) {
try {
URL url = new URL(sUrl[i]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
fOut = openFileOutput(i+".json",MODE_PRIVATE);
//fOut = new FileOutputStream("/aste/tiempobilbao.json");
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
fOut.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (fOut != null)
fOut.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
}
return null;
}
}
If the file exist, delete it first.
you can delete file before starting download with below code :
File myFile = new File(fileName);
if(myFile.exists())
myFile.delete();

Download the video before play it on android VideoView

I need to program my apps to download the video first from server and save into sdcard before playing it. Where can i get this tutorial?
Current now, I stream the video, but i don't want this way.
final VideoView videoView = (VideoView)rootView.findViewById(R.id.styleVideo);
videoView.setVideoURI(Uri.parse(videoPath));
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
videoView.setBackground(mScarfBuffer.getDrawable(position));
}
});
videoView.setMediaController(new MediaController(rootView.getContext()));
videoView.requestFocus();
videoView.start();
Use the following to download the file:
void downloadFile(){
try {
URL url = new URL(dwnload_file_path);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//connect
urlConnection.connect();
//set the path where we want to save the file
String SDCardRoot= Environment.getExternalStorageDirectory() ;
//create a new file, to save the downloaded file
File file = new File(SDCardRoot,"mydownloadmovie.mp4");
FileOutputStream fileOutput = new FileOutputStream(file);
//Stream used for reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file which we are downloading
totalSize = urlConnection.getContentLength();
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
}
//close the output stream when complete //
fileOutput.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (Exception e) {
}
}
Don't forget to wrap inside an AsyncTask.
Then use MediaPlayer to play your downloaded file( now local file).
this the code download and play the video on completed
public class Testing extends AppCompatActivity {
VideoView videoView;
MediaController mediaController;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testing);
videoView = (VideoView) findViewById(R.id.vid258);
mediaController = new MediaController(this);
// Enter Your Server Link
final DownloadTask downloadTask = new DownloadTask(Testing.this);
downloadTask.execute("http://codechair.com/video/1496139752333.mp4");
});
}
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
private PowerManager.WakeLock mWakeLock;
public DownloadTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream("/sdcard/file_name.mp4");
byte data[] = new byte[4096];
Log.d("Orignalvalu1",String.valueOf(new byte[4096]));
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
Log.d("Orignalvalu1",String.valueOf(input.read(data)));
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
Log.d("Orignalvalu2",String.valueOf(total));
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// take CPU lock to prevent CPU from going off if the user
// presses the power button during download
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
mWakeLock.acquire();
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
// if we get here, length is known, now set indeterminate to false
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(String result) {
mWakeLock.release();
mProgressDialog.dismiss();
if (result != null)
Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
else
Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
videoView.setVideoPath("/storage/emulated/0/file_name.mp4");
videoView.setMediaController(mediaController);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
}
});
videoView.requestFocus();
videoView.start();
}
}

Monitoring BufferedInputStream download progress

I'm trying to download a file using an AsyncTask on Android. I want to display a ProgressDialog which should have a progress bar to show the status of the download. I'm using the onProgressUpdate() function for that and implemented a call to publishProgress() in my doInBackground() function. However, the progress dialog only pops up after downloading the file. My code:
protected Long doInBackground(URL...urls) {
for (int i = 0; i < urls.length; i++) {
url = urls[i];
try {
URLConnection conn = url.openConnection();
conn.connect();
totalSize = conn.getContentLength();
BufferedInputStream bis = new BufferedInputStream(url.openStream());
FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/forvo_temp.mp3");
BufferedOutputStream bos = new BufferedOutputStream(fos,1024);
byte [] data = new byte[1024];
int x=0; int c=0;
while((x=bis.read(data,0,1024))>=0){
bos.write(data,0,x);
c += 1024;
publishProgress(c);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return 0L; // Don't know what to do with this
}
protected void onProgressUpdate(Integer...args) {
pd = ProgressDialog.show(context, "Downloading...", "Downloading...", true, false);
pd.setProgress(args[0] / totalSize);
}
I guess the whole file is downloaded when I call new BufferedInputStream(url.openStream()). How can I monitor the download progress?
Wrap URL input stream with you own InputStream that just reads bytes and "monitors" the status, e.g. sends notifications.
It is simple: InputStream is an abstract class with only one abstract method:
public abstract int read() throws IOException;
In your case it should read bytes from stream that it wraps.
public class NotifcationInputStream extends InputStream {
private InputStream in;
private int count;
private Collection<ByteListener> listeners = new ArrayList<ByteListener>();
NotificationInputStream(InputStream in) {
this.in = in;
}
public int read() throws IOException {
int b = in.read();
byteReceived(b);
return b;
}
public void addListener(ByteListener listener) {
listeners.add(listener);
}
private void byteReceived(int b) {
for (ByteListener l : listeners) {
l.byteReceived(b, ++count);
}
}
}
public interface ByteListener extends EventListener {
public void byteReceived(int b, int count);
}
The problem here is how to show the process bar: you have to know total number of bytes. You can get it from HTTP header content-length if your resource is static. Otherwise you need appropriate server support or heuristics.
This code is useful showing download items totol size and downloaded size.
private static final int DOWNLOAD_ONPROGRESS = 1;
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DOWNLOAD_ONPROGRESS:
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Downloading latest ...");
progressDialog.setCancelable(true);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
try {
progressDialog.show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return progressDialog;
default:
return null;
}
}
You can use AsyncTask for downloading the version in background.
private class DownLoad extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
logger.info("LoadDataAsync onPreExecute");
showDialog(DOWNLOAD_ONPROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count = 0;
try {
URL url = new URL(aurl[0]);
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
int contentlength = urlConnection.getContentLength();
progressDialog.setMax(contentlength);
String PATH = "";
File file = null;
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED)) {
PATH = Environment.getExternalStorageDirectory()
+ "/download/";
file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "telfaz.apk");
OutputStream fos = new FileOutputStream(outputFile);
InputStream is = new BufferedInputStream(url.openStream());
byte[] buffer = new byte[1024];
long len1 = 0;
while ((count = is.read(buffer)) != -1
&& !downLoad.isCancelled()) {
len1 += count;
publishProgress("" + len1);
fos.write(buffer, 0, count);
}
fos.flush();
fos.close();
is.close();
}
logger.info("Success -> file downloaded succesfully. returning 'success' code");
return Util.APK_DOWNLOAD_SUCCESS;
} catch (IOException e) {
logger.error("Exception in update process : "
+ Util.getStackTrace(e));
}
logger.info("Failed -> file download failed. returning 'error' code");
return Util.APK_DOWNLOAD_FAILED;
}
#Override
protected void onPostExecute(String result) {
logger.info("on DownLoad onPostExecute. result : " + result);
progressDialog.dismiss();
removeDialog(DOWNLOAD_ONPROGRESS);
if (result.equalsIgnoreCase(Util.APK_DOWNLOAD_SUCCESS)) {
Update();
} else {
Toast.makeText(DownloadAllContentsActivity.this,
getString(R.string.updateApplicationFailed),
Toast.LENGTH_LONG).show();
loadDataAsync.execute();
}
}
#Override
protected void onProgressUpdate(String... values) {
if (values != null && values.length > 0) {
progressDialog.setProgress(Integer.parseInt(values[0]));
}
}
}

APK file gets corrupted while writing to SD Card

I hit to a URL where my apk file is hosted and then write the bytes received to a file.
class DownloadAPKFile extends AsyncTask<String, Void, Boolean>{
private byte[] fileBytes;
#Override
protected Boolean doInBackground(String... params) {
Log.d("begin", "begun");
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet("http://www.website/Path/my.apk");
try {
HttpResponse response = client.execute(get);
Log.d("Login", "Response " + response.getEntity());
Log.d("Login", "contentLength " + response.getEntity().getContentLength());
String responseBody = EntityUtils.toString(response.getEntity());
fileBytes = responseBody.getBytes();
Log.d("fileBytes", "fileBytes");
String filePath = Environment.getExternalStorageDirectory() + "/myappdir/" + "my" + ".apk";
File file = new File(filePath);
file.getParentFile().mkdirs();
file.createNewFile();
BufferedOutputStream objectOut = new BufferedOutputStream(new FileOutputStream(file));
Log.d("objectOut", "objectOut");
objectOut.write(fileBytes);
Log.d("write", "write");
objectOut.close();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
This works like a charm, the problem i am having is that the content length from the entitiy is 582504 but when i look into the file manager the size goes upto 863145. I think that some data is being added while writing file to SD Card. Is there any solution to this?
This is my code which works fine, please check if this works for you
public class downloadApk extends AsyncTask<Integer, Integer, Integer>
{
#Override
protected Integer doInBackground(Integer... params) {
// TODO Auto-generated method stub
try {
URL url = new URL("http://www.tagsinfosoft.com/android/shelf/Shelf_Cam.apk");
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "Shelf_Cam.apk");
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();//till here, it works fine - .apk is download to my sdcard in download file
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Context context=shelf.this;
pd.dismiss();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "Shelf_Cam.apk")), "application/vnd.android.package-archive");
startActivity(intent);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd=ProgressDialog.show(shelf.this,"Updating","Please wait....." );
}
}

Categories

Resources