I am trying to download and save the file to sd card. The file url is as follows
http://test.com/net/Webexecute.aspx?fileId=120
This url provides a stream of data. I have the following option to read the input stream.
Use generic input and output stream (no handlers for connection fail
overs)
Download manager
Using HttpUrlConnection (possible timeout chances)
I have done the download using option a. But there are no handlers for connection fail overs. So I decided to go with option b
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Request request = new Request(Uri.parse("http://test.com/net/Webexecute.aspx?fileId="+ fileId));
request.setMimeType("application/pdf");
request.setDescription("fileDownload");
request.setTitle(fileName);
request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
dm.enqueue(request);
It is downloading the file. However, the file seems to be corrupted.
While doing the research, I never found DownloadManager being used to fetch an input stream and save that to a file. Is there anything I am lacking?
Please change your code to download a file.
protected Void downLoadFile(String fileURL) {
int count;
try {
URL url = new URL(fileURL);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
InputStream is = url.openStream();
File testDirectory = new File(Environment.getExternalStorageDirectory() + "/Download");
if (!testDirectory.exists()) {
testDirectory.mkdir();
}
FileOutputStream fos = new FileOutputStream(testDirectory + "/filename.txt");
byte data[] = new byte[1024];
long total = 0;
int progress = 0;
while ((count = is.read(data)) != -1) {
total += count;
int progress_temp = (int) total * 100 / lenghtOfFile;
fos.write(data, 0, count);
}
is.close();
fos.close();
readStringFromFile(testDirectory);
} catch (Exception e) {
Log.e("ERROR DOWNLOADING", "Unable to download" + e.getMessage());
e.printStackTrace();
}
return null;
}
The Below method is used to read string from file.
public String readStringFromFile(File file) {
String response = "";
try {
FileInputStream fileInputStream = new FileInputStream(file + "/filename.txt");
StringBuilder builder = new StringBuilder();
int ch;
while ((ch = fileInputStream.read()) != -1) {
builder.append((char) ch);
}
response = builder.toString();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
}
Related
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
In my Android project, programmatically I need to download a .mp3 file from google drive download url and store in the app sandbox. Then, App can have play option to play this audio locally.
How is this possible to achieve downloading .mp3 file from server and store it locally in the app? Later, it can be played from local storage. Any help on this is very much appreciated.
Thank you.
You can use this method:
static void downloadFile(String dwnload_file_path, String fileName,
String pathToSave) {
int downloadedSize = 0;
int totalSize = 0;
try {
URL url = new URL(dwnload_file_path);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
// connect
urlConnection.connect();
File myDir;
myDir = new File(pathToSave);
myDir.mkdirs();
// create a new file, to save the downloaded file
String mFileName = fileName;
File file = new File(myDir, mFileName);
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();
// runOnUiThread(new Runnable() {
// public void run() {
// pb.setMax(totalSize);
// }
// });
// create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
// update the progressbar //
// runOnUiThread(new Runnable() {
// public void run() {
// pb.setProgress(downloadedSize);
// float per = ((float)downloadedSize/totalSize) * 100;
// cur_val.setText("Downloaded " + downloadedSize + "KB / " +
// totalSize + "KB (" + (int)per + "%)" );
// }
// });
}
// close the output stream when complete //
fileOutput.close();
// runOnUiThread(new Runnable() {
// public void run() {
// // pb.dismiss(); // if you want close it..
// }
// });
} catch (final MalformedURLException e) {
// showError("Error : MalformedURLException " + e);
e.printStackTrace();
} catch (final IOException e) {
// showError("Error : IOException " + e);
e.printStackTrace();
} catch (final Exception e) {
// showError("Error : Please check your internet connection " + e);
}
}
Call this method like this:
String SDCardRoot = Environment.getExternalStorageDirectory()
.toString();
Utils.downloadFile("http://my_audio_url/my_file.mp3", "my_file.mp3",
SDCardRoot+"/MyAudioFolder");
for playback:
String SDCardRoot = Environment.getExternalStorageDirectory()
.toString();
String audioFilePath = SDCardRoot + "/MyAudioFolder/my_file.mp3";
MediaPlayer mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(audioFilePath);
mPlayer.prepare();
mPlayer.start();
} catch (IOException e) {
Log.e("AUDIO PLAYBACK", "prepare() failed");
}
a very simple solution is to use Android Download Manager Api
public void download(MediaRecords mediaRecords) {
try {
Toast.makeText(application, application.getString(R.string.download_started), Toast.LENGTH_SHORT).show();
MediaRecordsOffline mediaRecordsOffline = mediaRecords.toOfflineModel();
mediaRecordsOffline.setLocalFileUrl(Utils.getEmptyFile(mediaRecordsOffline.getId() + ".mp3").getAbsolutePath());
dao.insertOfflineMedia(mediaRecordsOffline);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(mediaRecordsOffline.getFileUrl()))
.setTitle(mediaRecordsOffline.getName())// Title of the Download Notification
.setDescription(mediaRecordsOffline.getDescription())// Description of the Download Notification
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)// Visibility of the download Notification
.setAllowedOverMetered(true)// Set if download is allowed on Mobile network
.setDestinationUri(Uri.fromFile(Utils.getEmptyFile(mediaRecordsOffline.getId() + ".mp3")))
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setAllowedOverRoaming(true);// Set if download is allowed on roaming network
DownloadManager downloadManager = (DownloadManager) application.getSystemService(Context.DOWNLOAD_SERVICE);
downloadManager.enqueue(request); // enqueue puts the download request in
} catch (Exception e) {
android.util.Log.i(TAG, "downloadManager: " + e.getMessage());
Toast.makeText(application, application.getString(R.string.error), Toast.LENGTH_SHORT).show();
}
}
Utils class which used to create the File :
public class Utils {
public static File getEmptyFile(String name) {
File folder = Utils.createFolders();
if (folder != null) {
if (folder.exists()) {
File file = new File(folder, name);
return file;
}
}
return null;
}
public static File createFolders() {
File baseDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
if (baseDir == null)
return Environment.getExternalStorageDirectory();
File aviaryFolder = new File(baseDir, ".playNow");
if (aviaryFolder.exists())
return aviaryFolder;
if (aviaryFolder.isFile())
aviaryFolder.delete();
if (aviaryFolder.mkdirs())
return aviaryFolder;
return Environment.getExternalStorageDirectory();
}
}
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);
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) {}
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);
}
}