In my app I am using a webview to navigate through to a site, automatically fill in a web form using javascript then submit to obtain a link to a CSV export file.
The link looks like this: XYZ.com/TEST/index/getexport?id=130.
I'd like to download the file this URL points to, then when complete read it into a local database but I'm having trouble downloading the linked file.
If I simply try to open the URL in webview I get an error from the webpage telling me no such file exists.
If I use the Download Manager to download it myself, the source code is downloaded as an html file, not the associated .csv file.
I can open the url with an ACTION_VIEW intent and a browser (chrome) downloads the correct file, but this way I have no notification of when the download completes.
Any ideas of how to download my .CSV file?
To download a file from webview use this :
mWebView.setDownloadListener(new DownloadListener(){
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength){
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
Hope this helps.
You could resort to manually downloading the file from the url using an AsyncTask.
Here id the background part:
#Override
protected String doInBackground(Void... params) {
String filename = "inputAFileName";
HttpURLConnection c;
try {
URL url = new URL("http://someurl/" + 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();
}
if (file.exists()) {
return "File downloaded!";
} else {
Log.e(TAG, "file not found");
}
} else {
Log.e(TAG, "unable to create folder");
}
}
Perhaps it would make sense to refactor it so that the file is returned. Then you get the file as an argument in onPostExecute as soon as the download is complete.
Related
I'm downloading a PDF from my server.
The server send me a HttpResponse with the InputStream of file's body.
I'm able to write it into a file but, when I try to read it with a PDF reader, it tells me that the file might be corrupted.
I've also noticed that the size of the PDF downloaded directly from web service is twice the size of the PDF downloaded via my application.
The code I use to download and write the PDF file is this:
String fileName = //FILENAME + ".pdf";
fileName = fileName.replaceAll("/", "_");
String extPath = Environment.getExternalStorageDirectory().toString();
String folderName = //FOLDERNAME;
try {
File folder = new File(extPath, folderName);
folder.mkdir();
File pdfFile = new File(folder, fileName);
pdfFile.createNewFile();
URL url = new URL(downloadURL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(pdfFile);
byte[] buffer = new byte[MEGABYTE];
int bufferLength;
while((bufferLength = inputStream.read(buffer))>0 ){
fileOutputStream.write(buffer, 0, bufferLength);
}
fileOutputStream.close();
Uri path = Uri.fromFile(pdfFile);
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "No Application available to view PDF", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
//otherStuff
Where I go wrong?
I've also noticed that inside the Headers of HttpResponse contains Content-type:text/html. It shoudld be something like text/pdf?
Your Downloading code seems correct. Based on that and on your comment:
I've also noticed that the size of the PDF downloaded directly from web service is twice the size of the PDF downloaded via my application."
I would suggest checking your URL. It appears that you might be downloading an html page instead of the pdf. To verify you are downloading correctly, change the download directory as follows:
//Default download directory
String extPath = Environment.DIRECTORY_DOWNLOADS;
And check the directory (via the file system, e.g. mount the phone to your computer or a file manager app) for the downloaded content to verify it is a pdf.
I have one requirement in my Android application. I need to download and save file in specific folder of SD card programmatically. I have developed source code, which is
String DownloadUrl = "http://myexample.com/android/";
String fileName = "myclock_db.db";
DownloadDatabase(DownloadUrl,fileName);
// and the method is
public void DownloadDatabase(String DownloadUrl, String fileName) {
try {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + "/myclock/databases");
if(dir.exists() == false){
dir.mkdirs();
}
URL url = new URL("http://myexample.com/android/");
File file = new File(dir,fileName);
long startTime = System.currentTimeMillis();
Log.d("DownloadManager" , "download url:" +url);
Log.d("DownloadManager" , "download file name:" + fileName);
URLConnection uconn = url.openConnection();
uconn.setReadTimeout(TIMEOUT_CONNECTION);
uconn.setConnectTimeout(TIMEOUT_SOCKET);
InputStream is = uconn.getInputStream();
BufferedInputStream bufferinstream = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(5000);
int current = 0;
while((current = bufferinstream.read()) != -1){
baf.append((byte) current);
}
FileOutputStream fos = new FileOutputStream( file);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
Log.d("DownloadManager" , "download ready in" + ((System.currentTimeMillis() - startTime)/1000) + "sec");
int dotindex = fileName.lastIndexOf('.');
if(dotindex>=0){
fileName = fileName.substring(0,dotindex);
}
catch(IOException e) {
Log.d("DownloadManager" , "Error:" + e);
}
}
Now the issue is only empty file with filename myclock_db.db is saving in the path. but I need to download and save content of file in the specific folder. Tried several ways to get the file download, but I can't.
Your download URL is not a link to any file. It's a directory. Make sure its a file and exists. Also check your logcat window for error logs. One more suggestion, its always better to do a printStackTrace() in catch blocks instead of Logs. Its gives a more detailed view of the error.
Change this line:
URL url = new URL("http://myexample.com/android/");
to:
URL url = new URL("http://myexample.com/android/yourfilename.txt"); //some file url
Next, in catch block, add this line:
e.printStackTrace();
Also in the directory path, it should be something like this:
File dir = new File(root.getAbsolutePath() + "/mnt/sdcard/myclock/databases");
instead of
File dir = new File(root.getAbsolutePath() + "/myclock/databases");
Next, make sure you have acquired permission for writing to external storage in Android manifest.
I am using following code to download and read a PDF file from internal storage on device.
I am able to download the files successfully to the directory:
data/data/packagename/app_books/file.pdf
But I am unable to read the file using a PDF reader application like Adobe Reader.
Code to download file
//Creating an internal dir;
File mydir = getApplicationContext().getDir("books", Context.MODE_WORLD_READABLE);
try {
File file = new File(mydir, outputFileName);
URL downloadUrl = new URL(url);
URLConnection ucon = downloadUrl.openConnection();
ucon.connect();
InputStream is = ucon.getInputStream();
FileOutputStream fos = new FileOutputStream(file);
byte data[] = new byte[1024];
int current = 0;
while ((current = is.read(data)) != -1) {
fos.write(data, 0, current);
}
is.close();
fos.flush();
fos.close();
isFileDownloaded=true;
} catch (IOException e) {
e.printStackTrace();
isFileDownloaded = false;
System.out.println(outputFileName + " not downloaded");
}
if (isFileDownloaded)
System.out.println(outputFileName + " downloaded");
return isFileDownloaded;
Code to read the file
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent,
PackageManager.MATCH_DEFAULT_ONLY);
try {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
File fileToRead = new File(
"/data/data/com.example.filedownloader/app_books/Book.pdf");
Uri uri = Uri.fromFile(fileToRead.getAbsoluteFile());
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
} catch (Exception ex) {
Log.i(getClass().toString(), ex.toString());
Toast.makeText(MainActivity.this,
"Cannot open your selected file, try again later",
Toast.LENGTH_SHORT).show();
}
All works fine but the reader app says "File Path is not valid".
Your path is only valid for your app. Place the file in a place where other apps can 'see' it. Use GetExternalFilesDir() or getExternalStorageDirectory().
Note about files which are created inside the directory created by Context.getDir(String name, int mode) that they will only be accessible by your own application; you can only set the mode of the entire directory, not of individual files.
So you can use Context.openFileOutput(String name, int mode). I'm re-using your code for an example:
try {
// Now we use Context.MODE_WORLD_READABLE for this file
FileOutputStream fos = openFileOutput(outputFileName,
Context.MODE_WORLD_READABLE);
// Download data and store it to `fos`
// ...
You might want to take a look at this guide: Using the Internal Storage.
If you would like to keep the file app specific, you can use PdfRenderer available for Lollipop and above builds. There are great tutorials on google and youtube that work well. The method you are using is a secure way to store a PDF file that is only readable from inside the app ONLY. No outside application like Adobe PDF Reader will be able to even see the file.It took me a lot of seaching but I found a solution to my specific usage by using this site and especially youtube.
How to download PDF file from asset folder to storage by making folder
make sure you have storage permission are given like marshmallow device support etc then follow these steps
private void CopyReadAssets()
{
AssetManager assetManager = getContext().getAssets();
FileInputStream in = null;
FileOutputStream out = null;
File sdcard = Environment.getExternalStorageDirectory();
File dir = new File(Environment.getExternalStorageDirectory()+File.separator+ "A_level");
File dir2;
if (dir.exists() && dir.isDirectory()){
Log.e("tag out", ""+ dir);
}else {
dir.mkdir();
Log.e("tag out", "not exist");
}
File file = new File(dir, mTitle+".pdf");
try
{
Log.e("tag out", ""+ file);
out = new FileOutputStream(file);
in = new FileInputStream (new File(mPath));
Log.e("tag In", ""+ in);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e)
{
Log.e("tag out", ""+ out);
Log.e("tag In", ""+ in);
Log.e("tag", e.getMessage());
Log.e("tag", ""+file);
Log.i("tag",""+sdcard.getAbsolutePath() + "A_level");
}
}
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);
}
}
I made an android app for viewing Pdf file fetched from URL by integrating pdfViewer library in my code.Firstly app downloading the file from web to external sd card then from there the app is getting opened with PdfViewer library.It is working fine if the file size is small but if the pdf file contains images and size is more , the downloaded file size shown in sdcard is 0kb.
Can someone help me out why this is so?
Following is java code :
public class MainActivity extends Activity {
static Context applicationContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
applicationContext = getApplicationContext();
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, "pdfDownloads");
folder.mkdir();
File file = new File(folder, "android.pdf");
try {
if(!file.exists()) {
file.createNewFile();
}
} catch (IOException e1) {
e1.printStackTrace();
}
boolean downloadFile = downloadFile("http://www.irs.gov/pub/irs-pdf/fw4.pdf", file);
if (file!=null && file.exists() && file.length() > 0){
Intent intent = new Intent(this, com.example.soniapdf.Second.class);
intent.putExtra(PdfViewerActivity.EXTRA_PDFFILENAME,
file.getAbsolutePath());
startActivity(intent);
}
}
public static boolean downloadFile(String fileUrl, File directory) {
try {
FileOutputStream f = new FileOutputStream(directory);
URL u = new URL(fileUrl);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
//
int fileLength = c.getContentLength();
long total = 0;
//
Toast.makeText(applicationContext, "Downloading PDF...", 2000).show();
while ((len = in.read(buffer)) > 0) {
total += len;
//Toast.makeText(applicationContext, "Downloading PDF: remaining " + (fileLength / total )+ "%", 1).show();
f.write(buffer, 0, len);
}
f.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
This is a way for showing PDF in android app that is embedding the PDF document to android webview using support from http://docs.google.com/viewer
pseudo
String doc="<iframe src='http://docs.google.com/viewer?url=+location to your PDF File+'
width='100%' height='100%'
style='border: none;'></iframe>";
a sample is is shown below
String doc="<iframe src='http://docs.google.com/viewer?url=http://www.iasted.org/conferences/formatting/presentations-tips.ppt&embedded=true'
width='100%' height='100%'
style='border: none;'></iframe>";
Code
WebView wv = (WebView)findViewById(R.id.webView);
wv.getSettings().setJavaScriptEnabled(true);
wv.getSettings().setPluginsEnabled(true);
wv.getSettings().setAllowFileAccess(true);
wv.loadUrl(doc);
//wv.loadData( doc, "text/html", "UTF-8");
and in manifest provide
<uses-permission android:name="android.permission.INTERNET"/>
SEE THIS ANSWER
EDIT
If your PDF document is accessible online, use the Google Docs Viewer to open your PDF in a WebView
REFER
wv.loadUrl("https://docs.google.com/gview?embedded=true&url=http://www.irs.gov/pub/irs-pdf/fw4.pdf");
Don't Know how Stable These are
Here is the list of the other open sources PDF readers running on the top of the Android
Android PDF Viewer
APDFViewer
droidreader
android-pdf
Please note that these and any other project derived from MuPDF is bound by the terms of GPL and may not be suitable for the commerical use.
The following is a list of SDKs suitable for commerical use:
PDFTron
Adobe
Qoppa
Radaee
how can i download audio file from server by url and save it to sdcard.
i am using the code below:
public void uploadPithyFromServer(String imageURL, String fileName) {
try {
URL url = new URL(GlobalConfig.AppUrl + imageURL);
File file = new File(fileName);
Log.d("ImageManager", "download begining");
Log.d("ImageManager", "download url:" + url);
Log.d("ImageManager", "downloaded file name:" + fileName);
/* Open a connection to that URL. */
URLConnection con = url.openConnection();
InputStream is = con.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is, 1024 * 50);
FileOutputStream fos = new FileOutputStream("/sdcard/" + file);
byte[] buffer = new byte[1024 * 50];
int current = 0;
while ((current = bis.read(buffer)) != -1) {
fos.write(buffer, 0, current);
}
fos.flush();
fos.close();
bis.close();
} catch (IOException e) {
Log.d("ImageManager", "Error: " + e);
}
}
the above code is not downloading audio file.
if use any permission in menifest file plz tell me.. (i have used internet permission)
please help
thanks..
you must also add
android.permission.WRITE_EXTERNAL_STORAGE
permission if you wish to write data to sd card.
also post your logcat output , if you are getting any IOExceptions.
Your example does not specify a request method and some mimetypes and stuff.
Here you will find a list of mimetypes http://www.webmaster-toolkit.com/mime-types.shtml
Find the mimetypes relevant to you and add it to the mimetypes specified below in the code.
Oh and btw, the below is normal Java code. You'll have to replace the bit that stores the file on the sdcard. dont have an emulator or phone to test that part at the moment
Also see the docs for storage permissions on sd here: http://developer.android.com/reference/android/Manifest.permission_group.html#STORAGE
public static void downloadFile(String hostUrl, String filename)
{
try {
File file = new File(filename);
URL server = new URL(hostUrl + file.getName());
HttpURLConnection connection = (HttpURLConnection)server.openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.addRequestProperty("Accept","image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/x-shockwave-flash, */*");
connection.addRequestProperty("Accept-Language", "en-us,zh-cn;q=0.5");
connection.addRequestProperty("Accept-Encoding", "gzip, deflate");
connection.connect();
InputStream is = connection.getInputStream();
OutputStream os = new FileOutputStream("c:/temp/" + file.getName());
byte[] buffer = new byte[1024];
int byteReaded = is.read(buffer);
while(byteReaded != -1)
{
os.write(buffer,0,byteReaded);
byteReaded = is.read(buffer);
}
os.close();
} catch (IOException e) {
e.printStackTrace();
}
Then call,
downloadFile("http://localhost/images/bullets/", "bullet_green.gif" );
EDIT:
Bad coder me.
Wrap that input InputStream in a BufferedInputStream. No need to specify buffersizes ect.
Defaults are good.