Download files from android application - android

I have a strange issue in downloading files in my android application all the files without space can be downloaded but when I have a space in my filename the file will not be downloaded for example:
Will not be download but this link:
http:..../DIV/Bon de Commande.pdf
will be downloaded:
http:..../DIV/POLITIQUE_QUALITE_V6.doc
This how I download file:
protected String downloadfile(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();
SharedPreferences myPreference= PreferenceManager.getDefaultSharedPreferences(getContext());
String path=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/Document" ;
String Fichename=sUrl[0].replace(myPreference.getString("lientelecharge", ""), "");
String filePath=path+"/"+Fichename;
File file = new File(filePath);
if(file.exists()) {
}else{
// download the file
input = connection.getInputStream();
File folder = new File(path);
boolean success = true;
if (!folder.exists()) {
success = folder.mkdir();
}
output = new FileOutputStream(path+"/"+Fichename);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
if (fileLength > 0) // only if total length is known
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;
}
Any help would be appreciated

Petrus is right - you have to urlencode string like:
String addressToGo = URLEncoder.encode("www.123.com/55 U.doc", "utf-8");
More ways to encode the string can be found at (my favourite one is without extra libraries): URL encoding in Android

Related

how to install an app from internal storage files

I'm trying to download an apk file then install it.
I have done it with an external storage directory but when I download the file in a Local directory I can't parse it.
Here is the code on OnCreate method
final DownloadTask downloadTask = new DownloadTask(this);
downloadTask.execute("http://file.appsapk.com/wp-content/uploads/apps-2/Gmail.apk","Gmail.apk");
DownloadTask is a class that extends from AsyncTask.
Here is the background task:
#Override
protected String doInBackground(String... sUrl) {
file_name=sUrl[1];
Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
if (isSDPresent) {
directory = new File(Environment.getExternalStorageDirectory()+File.separator+"app_directory");
}
else
{
directory = getFilesDir();
}
if (!directory.exists())
directory.mkdirs();
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
int fileLength = connection.getContentLength();
input = connection.getInputStream();
output = new FileOutputStream(directory+"/"+file_name);
byte[] buffer = new byte[1024];
long total = 0;
int count;
while ((count = input.read(buffer)) != -1) {
if (isCancelled()) {
input.close();
return null;
}
total += count;
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(buffer, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (input != null)
input.close();
if (output != null)
output.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
And this is the post execution method that runs after the first one done downloading the file:
#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();
File file = new File(directory, file_name);
Intent promptInstall = new Intent(Intent.ACTION_VIEW)
.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
context.startActivity(promptInstall);
finish();
}
It runs perfectly with an external storage but it won't run with an external one. Why not?
Try to use openfileoutput() rather than OutputStream in saving your file in internal storage and allow it to be readable. http://developer.android.com/guide/topics/data/data-storage.html#filesInternal . The package error is mainly caused by the permission of internal storage.
It's because of android application can not read from another application file if it is written using PRIVATE mode.So you have to change the mode of the file. i have just modify else part of your onPostExecute() method below.
try {
String tempfile="xyzfile";
File file = new File(directory, file_name);
FileInputStream inStream = new FileInputStream(file);
FileOutputStream fos = context.openFileOutput(tempfile,
context.MODE_WORLD_WRITEABLE | context.MODE_WORLD_READABLE);
byte[] buffer = new byte[1024];
int length;
// copy the file content in bytes
while ((length = inStream.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
inStream.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
File file = new File(context.getFilesDir(), tempfile);
Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(
Uri.fromFile(file), "application/vnd.android.package-archive");
context.startActivity(promptInstall);

InputstreamReader not reading all bytes of data from URL: android?

when I am trying to download files from server, it misses some bytes! and shows as a corrupted file. below the code i tried to download from URL. It gives no exception while running. I am using this in a service.
these are the sample results from my tries:
file 1:
actual size = 73.2 kb
downloaded size = 68.7 kb
file 2:
actual size = 147 kb
downloaded size = 137 kb
file 3:
actual size = 125 kb
downloaded size = 116.8 kb
please help me to find the correction needed to my code.
thanks,
InputStream stream = null;
FileOutputStream fos = null;
try {
URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
InputStreamReader reader = new InputStreamReader(stream);
fos = new FileOutputStream(output.getPath());
int next = -1;
while ((next = reader.read()) != -1) {
fos.write(next);
}
// Successful finished
Log.d("reaching", "reaching : DOWNLOAD FINISHED SUCCESSFULLY");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
yes, the problem was with the use of InputstreamReader
I used InputStream instead of that as #EJP said. And I modified my code to download file from server
Here I am putting my code for someone who comes to this link. May helpful for them.
try {
URL url = new URL(urlPath);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("download", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory()+"/"+fileName);
byte data[] = new byte[1024];
int count= -1;
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}

Download resume not working in setRequestProperty method

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.

Download PDF file android

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);
}
}

Download takes just too much time

I'm trying to download a file in my app, but the download times are inconsistently too long.
Sometimes it just downloading it in normal time, but sometimes it just stuck for like 30 seconds or more until it will just fail due to time out error.
Why would that be?
private void Download(String url, String destFileName) throws IOException{
//TODO remove that
// File file = new File(destFileName);
// if(file.exists())
// return;
if(BuildConfig.DEBUG)
Log.d("DownloadFile", "Downloading url: " + url + ", dest: " + destFileName);
HttpGet httppost = null;
AndroidHttpClient client = AndroidHttpClient.newInstance("TvinciAndroid");
FileOutputStream fos = new FileOutputStream(destFileName);
try {
httppost = new HttpGet(url);
HttpResponse res = client.execute(httppost);
if (res.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
Header[] headers = res.getHeaders("Location");
if(headers != null && headers.length != 0) {
url = headers[headers.length - 1].getValue();
Download(url, destFileName);
}
}
HttpEntity responseEntity = res.getEntity();
if (responseEntity != null && responseEntity.getContentLength() > 0) {
InputStream is = AndroidHttpClient.getUngzippedContent(responseEntity);
BufferedReader reader = new BufferedReader(new InputStreamReader(is,Charset.forName("UTF-8")));
StringBuilder bld = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
line += "\n";
fos.write(line.getBytes());
bld.append(line);
}
reader.close();
if(BuildConfig.DEBUG)
Log.d("file content", bld.toString());
bld = null;
}
}
catch(IOException ex){
throw ex;
}
finally {
client.close();
fos.close();
}
}
Any help will be much appreciated
Try specifying the buffer to 8192.
//input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
I have a sample working code here that can download a file via URL It is different from your implementation, but this might help you.
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
// getting file length
int lengthOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream(filePath);
byte data[] = new byte[1024];
long total = 0;
pDialog.setMax(lengthOfFile);
NOTIFICATION_ID = 1+lengthOfFile;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
//publishProgress(""+(int)((total*100)/lenghtOfFile));
publishProgress(""+(int)(total));
notifBuilder.setProgress(lengthOfFile, (int)(total), false)
.setContentText("Download in progress... "+total+"/"+lengthOfFile);
nm.notify(NOTIFICATION_ID, notifBuilder.build());
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
Log.e("Error: ", e.getMessage());
return e.getMessage()+" download failed!";
}
I Hope this helps.

Categories

Resources