my app downloaded file with this :
public class DownloadService extends IntentService {
public static final int UPDATE_PROGRESS = 8344;
public DownloadService() {
super("DownloadService");
}
#Override
protected void onHandleIntent(Intent intent) {
String urlToDownload = intent.getStringExtra("url");
String fileToStore= intent.getStringExtra("file");
ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
try {
URL url = new URL(urlToDownload);
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(connection.getInputStream());
OutputStream output = new FileOutputStream("/sdcard/SingingStudio/"+fileToStore+".zip");
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
Bundle resultData = new Bundle();
resultData.putInt("progress" ,(int) (total * 100 / fileLength));
receiver.send(UPDATE_PROGRESS, resultData);
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
Bundle resultData = new Bundle();
resultData.putInt("progress" ,100);
receiver.send(UPDATE_PROGRESS, resultData);
}
}
my app work in any device properly . but in all kitkat version of android for example xperia z4 and too galaxy grande 4.2.2
when file downloaded . if i go to any activity app is crash .
but if it download file with DownloadManager app is not crash .
why ?
Related
What I want to do now is loop download pdf from URL that has about 875 Files.
I have already done this by using Asynctask and update the progress in progress dialog also everything is working fine, but what I had a problem is when the user clicks on my DOWNLOAD IN BACKGROUND button, the download is still going on and then I want to re-open the activity again. but the progress and name of the file that displays to the user is not showing anymore.
I know that when we start new activity it will ignore the background running process of our last Asynctask, so how could we solve this problem? (sorry for my English, it's my first time through on StackOverflow)
my code is similar to this
Here sample of my code:
class DownloadFileFromURL extends AsyncTask<ArrayList<LawDocument>,Integer, String> {
private boolean running = true;
Exception error;
#Override
protected void onPreExecute() {
super.onPreExecute();
if(haveNetworkConnection()){
showDialog(progress_bar_type);
}else {
running = false;
showdailog();
}
}
#Override
protected void onCancelled() {
super.onCancelled();
running = false;
}
#Override
protected String doInBackground(ArrayList<LawDocument>[] f_url) {
ArrayList<LawDocument> passed = f_url[0]; //get passed arraylist
System.out.println("Data::" + passed.size());
int count;
InputStream input = null;
OutputStream output = null;
while(!isCancelled()) {
try {
for (int i = 0; i < passed.size(); i++) {
File file = getBaseContext().getFileStreamPath(passed.get(i).getActualFilename());
if (file.exists()){
countfile+=1;
pDialog.setMessage(" Exist / "+ConstantClass.filecount);
}else{
Log.d("checkFilecount" + i, "fileName: " + passed.get(i).getFileName());
String filename = passed.get(i).getFileName().substring(passed.get(i).getFileName().lastIndexOf("/") + 1);
Log.d("checkFile", "name: " + filename);
URL url = new URL(passed.get(i).getFileName());
System.out.println("Data::" + passed.get(i).getFileName());
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
input = new BufferedInputStream(url.openStream(), 8192);
//input = new BufferedInputStream(url.openStream(), 20000);
System.out.println("Data::" + passed.get(i).getFileName());
System.out.println("Data::" + filename);
// Output stream to write file
output = new FileOutputStream(getApplicationContext().getFilesDir() + "/" + filename);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress((int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
countfile+=1;
runOnUiThread(new Runnable() {
#Override
public void run() {
pDialog.setMessage(countfile+" / "+ConstantClass.filecount);
}
});
}
}
} catch (Throwable t) {
Log.e("AsyncTask", "OMGCrash", t);
// maybe throw it again
Toast.makeText(DownloadLoading.this,"There is a problem",Toast.LENGTH_SHORT).show();
throw new RuntimeException(t);
} finally {
if (output != null) {
try {
output.flush();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return null;
}
/**
* Updating progress bar
*/
protected void onProgressUpdate(Integer... progress) {
// setting progress percentage
pDialog.setProgress(progress[0]);
}
/**
* After completing background task Dismiss the progress dialog
**/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
//dismissDialog(progress_bar_type);
if (error !=null){
Toast.makeText(DownloadLoading.this, error.getMessage(),
Toast.LENGTH_SHORT).show();
}else if(!running){
Log.d("Faild","Download fail connection");
}else{
Toast.makeText(DownloadLoading.this, "Success", Toast.LENGTH_SHORT).show();
}
}
}
}
}
I guess the Best solution to you is using Service with BroadCast
which Mean but all your download In Service
lets say
public class DowloadService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle extras = intent.getExtras();
your_data = extras.get() // just example
for (int i = 0; i < passed.size(); i++) {
File file = getBaseContext().getFileStreamPath(passed.get(i).getActualFilename());
if (file.exists()){
countfile+=1;
pDialog.setMessage(" Exist / "+ConstantClass.filecount);
}else{
Log.d("checkFilecount" + i, "fileName: " + passed.get(i).getFileName());
String filename = passed.get(i).getFileName().substring(passed.get(i).getFileName().lastIndexOf("/") + 1);
Log.d("checkFile", "name: " + filename);
URL url = new URL(passed.get(i).getFileName());
System.out.println("Data::" + passed.get(i).getFileName());
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
input = new BufferedInputStream(url.openStream(), 8192);
//input = new BufferedInputStream(url.openStream(), 20000);
System.out.println("Data::" + passed.get(i).getFileName());
System.out.println("Data::" + filename);
// Output stream to write file
output = new FileOutputStream(getApplicationContext().getFilesDir() + "/" + filename);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress((int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
countfile+=1;
// send broadcast with data you want
ntent.putExtra("dataType",dataType);
intent.putExtra("getAccuracy",gpsSignal);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
});
return START_NOT_STICKY;
}
}
and then in your activiy Setup Local BroadCast To get Data send
private class BroadCastLocal extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
if (Constrains.PEDOMETERBROADCAST.equalsIgnoreCase(intent.getAction()))
{
int dataType = intent.getIntExtra("dataType",-1);
}
}
Now whenever the user start/end your activity .. the process will not be effected
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 want to download all mp3 files from server one by one and save into sd card folder. I have no any errors or exception but mp3 does not downloaded and does not show in SD card. Can someone help how to solve this issue.Here is my code.
if (imageName.endsWith(mp3_Pattern))
{
str_DownLoadUrl = namespace + "/DownloadFile/FileName/" + imageName;
Log.e("######### ", "str_DownLoadUrl = " + str_DownLoadUrl);
download_Mp3File(str_DownLoadUrl);
strDownLoadStatus = "1";
dbhelper.update_DownLoadStatus(imageName, strDownLoadStatus);
}
void download_Mp3File(final String fileUrl) {
new AsyncTask<String, Integer, String>()
{
#Override
protected String doInBackground(String... arg0)
{
int count;
File file = new File(newFolder, System.currentTimeMillis() + imageName);
try
{
URL url = new URL(fileUrl);
URLConnection conexion = url.openConnection();
conexion.connect();
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// downlod the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int) (total * 100 / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
}
return null;
}
}.execute();
}
place a breakpoint in inputstream object to see is there any stream. then debug output stream to see the results.
I want my app to download a video from an url.
For now I want to write download the file to my sd card.
I tried some different scripts, I don't receive an android.os.NetworkOnMainThreadException exception. But my application crashes.
Download a file programatically on Android
What is best way to download files from net programatically in android?
Does anyone know how to create a working method?
To solve this exception it has to be an async task.
public static void downloadFile(String url, File outputFile) {
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(outputFile));
fos.write(buffer);
fos.flush();
fos.close();
} catch(Exception e) {
Log.e("theple", "" + e);
}
}
Logs:
03-14 12:09:46.535: E/theple(6987): android.os.NetworkOnMainThreadException
I made it working, thx for the help anyway.
My code:
public class FileDownloader extends AsyncTask<String, Integer, String>
{
#Override
protected String doInBackground(String... params)
{
try {
URL u = new URL(params[0]);
URLConnection conn = u.openConnection();
int contentLength = conn.getContentLength();
DataInputStream stream = new DataInputStream(u.openStream());
byte[] buffer = new byte[contentLength];
stream.readFully(buffer);
stream.close();
DataOutputStream fos = new DataOutputStream(new FileOutputStream(new File(params[1])));
fos.write(buffer);
fos.flush();
fos.close();
} catch(Exception e) {
Log.e("theple", "" + e);
}
return null;
}
}
There are many ways you can perform downloading,in-spite of creating a method for it you should use "thread,Async class or service",That error "Network on Main thread comes due to the process is taking time".
I am showing example of Using Async Task and with Service
*
*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());
OutputStream output = new FileOutputStream("/sdcard/file_name.extension");
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
}
return null;
}**
And With Service
you can use :
class DownloadService extends IntentService {
public static final int UPDATE_PROGRESS = 8344;
public DownloadService() {
super("DownloadService");
}
#Override
protected void onHandleIntent(Intent intent) {
String urlToDownload = intent.getStringExtra("url");
ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
try {
URL url = new URL(urlToDownload);
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());
OutputStream output = new FileOutputStream("/sdcard/BarcodeScanner-debug.apk");
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
Bundle resultData = new Bundle();
resultData.putInt("progress" ,(int) (total * 100 / fileLength));
receiver.send(UPDATE_PROGRESS, resultData);
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
}
Bundle resultData = new Bundle();
resultData.putInt("progress" ,100);
receiver.send(UPDATE_PROGRESS, resultData);
}
}
Hope this will be helpful for you.
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.