I am trying to download a file from my server in Android and updating the progress..
On Async method in background I am calling a method that will download the file to my SD card now I would like update the progress hence trying publishProgress("" + progressvalue); which I am not able access from this method. How do I access the publishProgress?
Here is what I am trying:
private class FileDownloader extends AsyncTask<String, String, Void> {
#Override
protected Void doInBackground(String... param) {
downloadFileToSdCard(param[0], "File" + counter + ".mp4");
return null;
}
protected void onProgressUpdate(String... values)
{
Log.d("ANDRO_ASYNC", values[0]);
}
}
downloadFileToSdCard method looks like this:
private void downloadImagesToSdCard(String downloadUrl, String fileName)]
{
FileOutputStream fos;
InputStream inputStream = null;
try {
URL url = new URL(downloadUrl);
String sdCard = Environment.getExternalStorageDirectory().toString();
File myDir = new File(sdCard, "AppDownload");
if (!myDir.exists()) {
myDir.mkdir();
}
String fname = fileName;
File file = new File(myDir, fname);
if (file.exists())
file.delete();
URLConnection ucon = url.openConnection();
final String contentLengthStr=ucon.getHeaderField("content-length");
int lenghtOfFile = Integer.valueOf(contentLengthStr);
HttpURLConnection httpConn = (HttpURLConnection) ucon;
httpConn.setRequestMethod("GET");
httpConn.connect();
inputStream = httpConn.getInputStream();
fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int bufferLength = 0;
long total = 0;
int progress = 0;
while ((bufferLength = inputStream.read(buffer)) > 0)
{
total += bufferLength;
int progress_temp = (int) total * 100 / lenghtOfFile;
publishProgress("" + progress_temp);
if (progress_temp % 10 == 0 && progress != progress_temp)
{
progress = progress_temp;
}
fos.write(buffer, 0, bufferLength);
int downloadedSize = Integer.valueOf(contentLengthStr);
}
inputStream.close();
fos.close();
Log.e("Value", "File Saved in sdcard..");
} catch (IOException io) {
inputStream = null;
fos = null;
io.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
Can somebody help me fix this? Thanks!
Triy this:
keep you function inside into AsyncTask Class
private class FileDownloader extends AsyncTask<String, String, Void> {
#Override
protected Void doInBackground(String... param) {
downloadFileToSdCard(param[0], "File" + counter + ".mp4");
return null;
}
protected void onProgressUpdate(String... values)
{
Log.d("ANDRO_ASYNC", values[0]);
}
private void downloadImagesToSdCard(String downloadUrl, String fileName)
{
//Publish Progress calling code
}
}
The first thing that hits me is to simply pass your AsyncTask to your sdcard method. AsyncTask.publishProgress is protected, so as long as your two classes are in the same package, you should be able to call publishProgress from the sdcard downloaded method.
A cleaner/prettier approach would be to define a callback interface such as ProgressUpdater, let the AsyncTask implement it, and have the sdcard method take a ProgressUpdater as a parameter. This interface would typically have a similar or even equal publishProgress method. This however decouples the AsyncTask itself from the rest of your program.
Related
I am creating an app in which I have to play audio from a number of URL links. At the first ever run of the app I am providing user the option of either downloading all of the audio files at once. Right now I am downloading each URL individually using Async Task. The problem with this approach is that since I have some 6000 url links for audio files it takes very long.
My questions is that is there any way I can quickly download audio files from these 6000 urls.
Below I am also providing the code that I am using for downloading each url.
public class DownloadAudio extends AsyncTask<Void, Void, String> {
public static final String TAG = DownloadAudio.class.getSimpleName();
ProgressDialog mProgressDialog;
Context context;
String stringUrl;
int index;
public DownloadAudio(Context context,String url, int randomNumber) {
this.context = context;
stringUrl=url;
index = randomNumber;
}
protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(context, "Please wait", "Download …");
}
#Override
protected String doInBackground(Void... voids) {
try {
URL url = new URL(stringUrl);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String[] path = url.getPath().split("/");
int temp = path.length - 1;
String mp3 = path[temp];
int lengthOfFile = c.getContentLength();
String PATH = Environment.getExternalStorageDirectory()+ "/MyAudioApp/" ;
Log.v(TAG, "PATH: " + PATH);
File file = new File(PATH);
file.mkdirs();
String fileName = mp3;
File outputFile = new File(file , fileName);
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();
} catch (IOException e) {
e.printStackTrace();
}
return "done";
}
protected void onPostExecute(String result) {
if (result.equals("done")) {
mProgressDialog.dismiss();
}
}
}
Please any suggestions would be very helpful.
I have downloaded an audio file from Url thanks to Giridharan's answer in the link below:
Android - Save image from URL onto SD card
The problem is that I cannot play it, the error is as follows:
java.io.IOException: setDataSourceFD failed.: status=0x80000000
I'm sure that the audio url on the Internet is working fine, because I can play audio directly from that Url without downloading, but after download it then cannot play anymore, maybe the data source was changed incorrectly while downloading.
So how to solve this problem? Any help will be appreciated! Thanks for reading.
Download Audio from web using below code.
private void startDownload() {
String url = "http://farm1.static.flickr.com/114/298125983_0e4bf66782_b.jpg";
// Smaple url String url = "http://farm1.static.flickr.com/114/298125983_0e4bf66782_b.jpg";
new DownloadFileAsync().execute(url);
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// create dialog if you want
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/myAudio.mp3");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
#Override
protected void onPostExecute(String unused) {
// hide/dismiss dialog if you have any
}
}
then play it using /sdcard/myAudio.mp3 path in your media player.
if have any issue see this thread.
Finally I found the solution to my question, and now I post here to help everyone else faces the same problem can overcome it.
public String downloadAudioFromUrl(String url) {
int count;
File file = null;
try {
URL urls = new URL(url);
URLConnection connection = urls.openConnection();
connection.connect();
// this will be useful to show the percentage 0-100% in progress bar
int lengthOfFile = connection.getContentLength();
File storageDir = new File(Environment.getExternalStorageDirectory().toString() + "/Photo_Quiz/Audio");
if (!storageDir.exists()) {
storageDir.mkdirs();
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmssSSS").format(new Date());
String filename = "audio_" + timeStamp + ".3gp";
file = new File(storageDir, filename);
InputStream input = new BufferedInputStream(urls.openStream());
OutputStream output = new FileOutputStream(file.getAbsolutePath());
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress...
// publishProgress((int) (total * 100 / lengthOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
notifyNewMediaFile(file);
} catch (Exception e) {
e.printStackTrace();
}
return file.getAbsolutePath();
}
I am using string array to hold images, i am fetching the imaes from the URLs. I have one imageview which when swipped changes the images in it. Now i want to download and save any image i want on the SD card and want it to appear in the phone gallery in a new folder.
I am using the following code but it is not working, it is showing no error at all.
private class ImageDownloadAndSave extends AsyncTask<String, Void, Bitmap> {
#Override
protected Bitmap doInBackground(String... arg0) {
downloadImagesToSdCard("", "");
return null;
}
private void downloadImagesToSdCard(String downloadUrl, String imageName) {
try {
URL url = new URL(thumb[j]);
/* making a directory in sdcard */
String sdCard = Environment.getExternalStorageDirectory()
.toString();
File myDir = new File(sdCard, "test.jpg");
/* if specified not exist create new */
if (!myDir.exists()) {
myDir.mkdir();
Log.v("", "inside mkdir");
}
/* checks the file and if it already exist delete */
String fname = imageName;
File file = new File(myDir, fname);
if (file.exists())
file.delete();
/* Open a connection */
URLConnection ucon = url.openConnection();
InputStream inputStream = null;
HttpURLConnection httpConn = (HttpURLConnection) ucon;
httpConn.setRequestMethod("GET");
httpConn.connect();
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
inputStream = httpConn.getInputStream();
}
FileOutputStream fos = new FileOutputStream(file);
int totalSize = httpConn.getContentLength();
int downloadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = inputStream.read(buffer)) > 0) {
fos.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
Log.i("Progress:", "downloadedSize:" + downloadedSize
+ "totalSize:" + totalSize);
}
fos.close();
Log.d("test", "Image Saved in sdcard..");
} catch (IOException io) {
io.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
And i am executing it by
new ImageDownloadAndSave().execute("");
the name of my string array is "thumb" which is holding all the URLs. What am i doing wrong?
You should add image to gallery after save and then scan it. Please check the following topics:
Image, saved to sdcard, doesn't appear in Android's Gallery app
MediaScannerConnection
The file needs to be added to the Android MediaStore. This can be done easily by using below function.
public void scanFile(final File file) {
try {
new MediaScannerConnectionClient() {
private MediaScannerConnection mMs;
public void init() {
mMs = new MediaScannerConnection(myContext, this);
mMs.connect();
}
#Override
public void onMediaScannerConnected() {
mMs.scanFile(file.getAbsolutePath(), null);
mMs.disconnect();
}
#Override
public void onScanCompleted(String path, Uri uri) {
}
}.init();
} catch(Exception e) {
// Device does not support adding files manually.
// Sending Broadcast to start MediaScanner (slower than adding manually)
try {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
} catch(Exception ee) {
// Something went terribly wrong.
// Can't add file to MediaStore and can't send Broadcast to start MediaScanner.
}
}
}
You just need to add one line to your code:
// .....
fos.close();
Log.d("test", "Image Saved in sdcard..");
scanFile(file); // <------------- add this
I have a list view. When user selects an item of my list view, I open DetailActivity that user can download a file in that activity and I show the user download percentage using ProgressWheel.
My problem is when user closes the activity and then returns back to activity, the ProgressWheel doesn't update anymore.
Here is my code:(I download the file using AsynchTask)
/**
* Background Async Task to download file
* */
class DownloadTask extends AsyncTask<String, String, Boolean> {
/**
* Downloading file in background thread
* */
#Override
protected Boolean doInBackground(String... params) {
try {
URL url = null;
try {
String link = params[0];
fileExtention = getFileExtention(link);
url = new URL(link);
} catch (Exception e) {
e.printStackTrace();
return false;
}
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
// set some parameters for httpUrlConnection
connection.setConnectTimeout(JSONConstants.CONNECTION_TIMEOUT);
connection.setReadTimeout(JSONConstants.READ_TIMEOUT);
connection.connect(); // Connection Complete here.!
// Get from Server and Catch In Input Stream Object.
InputStream inputStream = connection.getInputStream();
int lenghtOfFile = connection.getContentLength();
String PATH = Environment.getExternalStorageDirectory()
+ "/download/";
File file = new File(PATH);
if (!file.exists()) {
file.mkdirs();
}
File outputFile = new File(file, "fileTitle"
+ ".mp3" );
FileOutputStream fileOutputStream = new FileOutputStream(
outputFile);
byte[] buffer = new byte[4096];
int length = 0;
long total = 0;
while ((length = inputStream.read(buffer)) != -1) {
total += length;
// publishing the progress....
// After this onProgressUpdate will be called
if (lenghtOfFile > 0)
publishProgress(""
+ (int) ((total * 100) / lenghtOfFile));
// Write In FileOutputStream.
fileOutputStream.write(buffer, 0, length);
}
fileOutputStream.flush();
fileOutputStream.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
private void publishProgress(String percent) {
// Sets the progress indicator to a max value, the
// current completion percentage, and "determinate"
// state
downloadProgressWheel.setProgress(Integer.valueOf(percent));
}
How can I set my ProgressWheel still updated when user returns back to it's associated activity.
I have read this topic
and I have a problem about downloading large files, because progress dialog does not upload progress or upload only once after downloading and show 100% suddenly. But all works perfectly when I'm downloading small files.
I think problem may be here:
publishProgress((int)(total*100/fileLength));
My code:
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
try {
URL url = new URL(sUrl[0]);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a typical 0-100% progress bar
int fileLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream());
String sdpath = Environment.getExternalStorageDirectory().getAbsolutePat();
File dir = new File(sdpath + "/Myfolder");
dir.mkdir();
OutputStream output = new FileOutputStream(dir.toString() + "/" + "myfilename");
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int)(total/fileLength)*100);
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
}
catch (Exception e) {
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
mProgressDialog.setProgress(progress[0]);
}
}
My file is about 80 mb.
You should try to divide first :
publishProgress((int)(total/fileLength)*100);
as you can get an out of range division.