Is it possible to incorporate a horizontal progress bar in the following code? I was thinking os AsyncTask but then I realized, I can't pass an integer value to ProgressUpdate() method inside doInBackground(). Please help!
public void sendFileDOS() throws FileNotFoundException {
runOnUiThread( new Runnable() {
#Override
public void run() {
registerLog("Sending. . . Please wait. . .");
}
});
final long startTime = System.currentTimeMillis();
final File myFile= new File(filePath); //sdcard/DCIM.JPG
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
try {
dis.readFully(mybytearray, 0, mybytearray.length);
OutputStream os = socket.getOutputStream();
//Sending file name and file size to the server
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(myFile.getName());
dos.writeLong(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread( new Runnable() {
#Override
public void run() {
long estimatedTime = (System.currentTimeMillis() - startTime)/1000;
registerLog("File successfully sent");
registerLog("File size: "+myFile.length()/1000+" KBytes");
registerLog("Elapsed time: "+estimatedTime+" sec. (approx)");
registerLog("Server stopped. Please restart for another session.");
final Button startServerButton=(Button)findViewById(R.id.button1);
startServerButton.setText("Restart file server");
}
});
}
For those facing similar issues, here is the working method for file transfer using Data Output Stream. The main idea was to break file into multiple chunks (i have divided into 100 chunks) and write to DOS in a while loop. Use your loop counter to update progress bar. Make sure to update progress bar in the main UI thread or else the application would crash. Here goes the code:
public void sendFileDOS() throws FileNotFoundException {
runOnUiThread( new Runnable() {
#Override
public void run() {
registerLog("Sending. . . Please wait. . .");
}
});
final long startTime = System.currentTimeMillis();
final File myFile= new File(filePath); //sdcard/DCIM.JPG
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
try {
dis.readFully(mybytearray, 0, mybytearray.length);
OutputStream os = socket.getOutputStream();
//Sending file name and file size to the server
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(myFile.getName());
dos.writeLong(mybytearray.length);
int i = 0;
final ProgressBar myProgBar=(ProgressBar)findViewById(R.id.progress_bar);
while (i<100) {
dos.write(mybytearray, i*(mybytearray.length/100), mybytearray.length/100);
final int c=i;
runOnUiThread( new Runnable() {
#Override
public void run() {
registerLog("Completed: "+c+"%");
myProgBar.setProgress(c);
}
});
i++;
}
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread( new Runnable() {
#Override
public void run() {
long estimatedTime = (System.currentTimeMillis() - startTime)/1000;
registerLog("File successfully sent");
registerLog("File size: "+myFile.length()/1000+" KBytes");
registerLog("Elapsed time: "+estimatedTime+" sec. (approx)");
registerLog("Server stopped. Please restart for another session.");
final Button startServerButton=(Button)findViewById(R.id.button1);
startServerButton.setText("Restart file server");
}
});
}
Cheers! :)
You can use AsyncTask that gets a progress bar like that:
public abstract class BaseTask extends AsyncTask<String, Integer, String>
{
private ProgressBar m_progressBar;
protected BaseTask(ProgressBar p)
{
m_progressBar = p;
}
#Override
protected void onPreExecute()
{
if (m_progressBar != null)
{
m_progressBar.setProgress(0);
}
}
#Override
protected void onPostExecute(String result)
{
if (m_progressBar != null)
m_progressBar.setVisibility(ProgressBar.GONE);
}
public void OnProgress(int prog)
{
if (m_progressBar != null)
{
m_progressBar.setProgress(prog);
}
}
}
To add a progress bar in your xml:
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp" />
To initialize the progress bar in your code:
ProgressBar p = (ProgressBar)findViewById(R.id.progressBar);
p.setVisibility(ProgressBar.VISIBLE);
p.setMax(100);
I can't pass an integer value to ProgressUpdate() method inside doInBackground()
Yes, you can !
Use publishProgress with the required parameters inside doInBackground to trigger onProgressUpdate:
final class MyTask extends AsyncTask<Void, Integer, Void> {
private final ProgressBar progress;
public MyTask(final ProgressBar progress) {
this.progress = progress;
}
#Override
protected void onPreExecute() {
progress.setMax(100);
}
#SuppressWarnings("unchecked")
#Override
protected Void doInBackground(final Void... params) {
...
int progress_val = // What ever you want
publishProgress(progress_val); // Here we trigger 'onProgressUpdate'
// with the updated integer as parameter
return null;
}
#Override
protected void onProgressUpdate(final Integer... values) {
progress.incrementProgressBy(values[0]); // Here we update the bar
}
#Override
protected void onPostExecute(final Void result) {
parent.finish();
}
}
EDIT :
Suggestion to write by blocks:
int i = 0;
int offset = 0;
int buflen = mybytearray.length/100;
while (i<100) {
dos.write(mybytearray, offset, buflen);
offset += buflen;
i++;
}
dos.write(mybytearray, offset, mybytearray.length%100);
Related
I am downloading a zip file of 15 mb and then unzip it in the sd card.
I am using progress dialog to show the status. First time it works perfectly, and when I change the db version number on server to download new file and start the app again then progress dialog disappears in between and causes crash in the app.
Below is the code.
class CheckInAppUpdatesAsyncTask extends AsyncTask<Void, Void, Void> {
Dialog progress;
#Override
protected Void doInBackground(Void... params) {
try {
downloadDB();
} catch (Exception e) {
}
}
#Override
protected void onPostExecute(final Void result) {
stopWorking();
}
#Override
protected void onPreExecute() {
startWorking();
}
};5
private void startWorking() {
synchronized (this.diagSynch) {
if (this.pDiag != null) {
this.pDiag.dismiss();
}
this.pDiag = ProgressDialog.show(Browse.context, "Working...",
"Please wait while we load the encyclopedia.", true, false);
}
}
private void stopWorking() {
synchronized (this.diagSynch) {
if (this.pDiag != null) {
this.pDiag.dismiss();
}
}
}
Download code
URL url = new URL(serverFileURL);
Log.d("FILE_URLLINK", "serverFileURL " + serverFileURL);
URLConnection connection = url.openConnection();
InputStream input = connection.getInputStream();
connection.getContentLength();
byte data[] = new byte[1024];
input = new GZIPInputStream(input);
InputSource is = new InputSource(input);
InputStream in = new BufferedInputStream(is.getByteStream());
String inAppDBName = Constants.NEW_DB_NAME_TO_DOWNLOAD;
OutputStream output = new BufferedOutputStream(new FileOutputStream(dir + "/" + inAppDBName));
int length;
while ((length = in.read(data)) > 0) {
output.write(data, 0, length);
}
output.flush();
output.close();
input.close();
Any idea?
You should put unzip code before stopWorking(); in onPostExecute.
It will not close till all things happen.
I am trying to download multiple videos from server using AsyncTask, I have list of progress bar for videos but I am unable to maintain the progress for each progress bar on orientation change of my phone.
I am calling downlodThreadVideos() in adapter of listview
public UserVideoDTO downlodThreadVideos(final ProgressBar _progress, ImageView _imgLaunch, ImageView _imgDownload, UserVideoDTO vpideoDTO)
{
DownloadVideoFileAsyncTask mDownloadFileAsync = new DownloadVideoFileAsyncTask(videoDTO,_progress,_imgLaunch,_imgDownload);
mDownloadFileAsync.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,videoDTO);
return mDownloadFileAsync._videoDTO;
}
private class DownloadVideoFileAsyncTask extends AsyncTask<UserVideoDTO, Integer, UserVideoDTO> {
ProgressBar _progress;
ImageView _imgLaunch;
ImageView _imgDownload;
public UserVideoDTO _videoDTO;
String OfflinePath=null;
public DownloadVideoFileAsyncTask(UserVideoDTO videoDTO,ProgressBar progress, ImageView imgLaunch, ImageView imgDownload) {
// TODO Auto-generated constructor stub
_videoDTO=videoDTO;
_progress = progress;
_imgLaunch=imgLaunch;
_imgDownload=imgDownload;
}
protected UserVideoDTO doInBackground(UserVideoDTO... params) {
UserVideoDTO videoDTO = _videoDTO;
try {
String _videoURL="http://mylinkforvideodownload/videoDTO.onlinepath";
if (cancelThread)
return null;
String Path = new String(_videoURL);
Path = Path.replaceAll(" ", "%20");
URL url = new URL(Path);
long startTime = System.currentTimeMillis();
HttpURLConnection ucon = (HttpURLConnection) url.openConnection();
ucon.setConnectTimeout(60000);
File folder = new File(getExternalFilesDir(null).getAbsolutePath()+"/Download");
folder.mkdir();
String fileName = getExternalFilesDir(null).getAbsolutePath()+ "/Download/videos_";
File file = new File(fileName);
String offlineFileName = videoDTO.lmsvideoid;
String offlineFilePath = file + offlineFileName + ".mp4";
BufferedInputStream inStream = new BufferedInputStream(ucon.getInputStream());
FileOutputStream outStream = new FileOutputStream(offlineFilePath);
byte[] buff = new byte[1024];
int lengthOfFile = ucon.getContentLength();
int len;
long total = 0;
try {
while (!cancelThread && ((len = inStream.read(buff)) != -1)) {
total += len;
publishProgress((int) ((total * 100) / lengthOfFile));
outStream.write(buff, 0, len);
}
} catch (Exception e) {
cancelThread = true;
}
outStream.flush();
outStream.close();
inStream.close();
}
catch (Exception e) {
e.printStackTrace();
}
return videoDTO;
}
protected void onProgressUpdate(Integer... progress) {
Log.d("ANDRO_ASYNC", progress[0].toString());
_progress.setProgress(progress[0]);
}
protected void onPreExecute() {
super.onPreExecute();
_progress.setMax(100);
}
protected void onPostExecute(UserVideoDTO result) {
super.onPostExecute(result);
_progress.setProgress(100);
}
protected void onCancelled() {
super.onCancelled();
}
}
i have this url http://translate.google.com/translate_tts?ie=UTF-8&q=hi&tl=en&total=1&idx=0&textlen=2
when i place it to pc and android browser it makes me force to download
how can i make it download in my android application without browser.
i tried to make to download using this tutorial how can i download audio file from server by url
.but it did not work.
anyone please help
Thank you Kristijana Draca think it is working but where it save in emulator here is my code public class Main extends Activity {
EditText inputtext;
Button listen;
Button shareButton;
TextView tv;
ProgressBar proBar;
//ProgressDialog progress;
MediaPlayer player;
public Boolean isPlaying=true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
downloadContent();
}
private void downloadContent() {
DownloadFile downloadFile = new DownloadFile();
downloadFile.execute("http://translate.google.com/translate_a/t?client=t&source=baf&sl=ar&tl=en&hl=en&q=%D9%85%D8%B1%D8%AD%D8%A8%D8%A7&sc=1 ");
}
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
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();
int fileLength = connection.getContentLength();
InputStream input = new BufferedInputStream(
connection.getInputStream());
// Create db
OutputStream output = new FileOutputStream(
Environment.getDataDirectory() + "/data/"
+ "com.jony.com" + "/file.mp3");
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;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
Toast.makeText(getApplicationContext(), "download complete", 1000).show();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Toast.makeText(getApplicationContext(), "download complete", 1000).show();
}
}
});
You can download any file using AsyncTask.
downloadContent();
private void downloadContent() {
DownloadFile downloadFile = new DownloadFile();
downloadFile.execute("http://somehost.com/file.mp3");
}
// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
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();
int fileLength = connection.getContentLength();
InputStream input = new BufferedInputStream(
connection.getInputStream());
// Create db
OutputStream output = new FileOutputStream(
Environment.getDataDirectory() + "/data/"
+ PACKAGE_NAME + "/file.mp3");
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;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
When I try this code, it starts download but then stuck with alert "force close"
what should I do? Use some kind of background thread?
try {
long startTime = System.currentTimeMillis();
URL u = new URL("http://file.podfm.ru/3/33/332/3322/mp3/24785.mp3");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File("/sdcard/","logo.mp3"));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ( (len1 = in.read(buffer)) != -1 ) {
f.write(buffer,0, len1);
}
f.close();
Log.d("ImageManager", "download ready in" +
((System.currentTimeMillis() - startTime) / 1000) + " sec");
}
catch (IOException e)
{
Log.d("ImageManager", "Error" +
((System.currentTimeMillis()) / 1000) + e + " sec");
}
I was dealing with similar problem last week and ended up using AsyncTask with progress bar displayed since it could take some time for the file to be downloaded. One way of doing it is to have below class nested in your Activity and just call it where you need to simply like this:
new DownloadManager().execute("here be URL", "here be filename");
Or if the class is not located within an activity and calling from an activity..
new DownloadManager(this).execute("URL", "filename");
This passes the activity so we have access to method getSystemService();
Here is the actual code doing all the dirty work. You will probably have to modify it for your needs.
private class DownloadManager extends AsyncTask<String, Integer, Drawable>
{
private Drawable d;
private HttpURLConnection conn;
private InputStream stream; //to read
private ByteArrayOutputStream out; //to write
private Context mCtx;
private double fileSize;
private double downloaded; // number of bytes downloaded
private int status = DOWNLOADING; //status of current process
private ProgressDialog progressDialog;
private static final int MAX_BUFFER_SIZE = 1024; //1kb
private static final int DOWNLOADING = 0;
private static final int COMPLETE = 1;
public DownloadManager(Context ctx)
{
d = null;
conn = null;
fileSize = 0;
downloaded = 0;
status = DOWNLOADING;
mCtx = ctx;
}
public boolean isOnline()
{
try
{
ConnectivityManager cm = (ConnectivityManager)mCtx.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
catch (Exception e)
{
return false;
}
}
#Override
protected Drawable doInBackground(String... url)
{
try
{
String filename = url[1];
if (isOnline())
{
conn = (HttpURLConnection) new URL(url[0]).openConnection();
fileSize = conn.getContentLength();
out = new ByteArrayOutputStream((int)fileSize);
conn.connect();
stream = conn.getInputStream();
// loop with step
while (status == DOWNLOADING)
{
byte buffer[];
if (fileSize - downloaded > MAX_BUFFER_SIZE)
{
buffer = new byte[MAX_BUFFER_SIZE];
}
else
{
buffer = new byte[(int) (fileSize - downloaded)];
}
int read = stream.read(buffer);
if (read == -1)
{
publishProgress(100);
break;
}
// writing to buffer
out.write(buffer, 0, read);
downloaded += read;
// update progress bar
publishProgress((int) ((downloaded / fileSize) * 100));
} // end of while
if (status == DOWNLOADING)
{
status = COMPLETE;
}
try
{
FileOutputStream fos = new FileOutputStream(filename);
fos.write(out.toByteArray());
fos.close();
}
catch ( IOException e )
{
e.printStackTrace();
return null;
}
d = Drawable.createFromStream((InputStream) new ByteArrayInputStream(out.toByteArray()), "filename");
return d;
} // end of if isOnline
else
{
return null;
}
}
catch (Exception e)
{
e.printStackTrace();
return null;
}// end of catch
} // end of class DownloadManager()
#Override
protected void onProgressUpdate(Integer... changed)
{
progressDialog.setProgress(changed[0]);
}
#Override
protected void onPreExecute()
{
progressDialog = new ProgressDialog(/*ShowContent.this*/); // your activity
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Downloading ...");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected void onPostExecute(Drawable result)
{
progressDialog.dismiss();
// do something
}
}
You should try using an AsyncTask. You are getting the force quit dialog because you are trying to do too much work on the UI thread and Android judges that your application has become unresponsive.
The answers to this question have some good links.
Something like the following would be a good start:
private class DownloadLargeFileTask extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog;
public DownloadLargeFileTask(ProgressDialog dialog) {
this.dialog = dialog;
}
protected void onPreExecute() {
dialog.show();
}
protected void doInBackground(Void... unused) {
downloadLargeFile();
}
protected void onPostExecute(Void unused) {
dialog.dismiss();
}
}
and then execute the task with:
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Loading. Please Wait...");
new DownloadLargeFileTask(dialog).execute();
private class DownloadLargeFileTask extends AsyncTask<Void, Void, Void>
{
private final ProgressDialog dialog;
public DownloadLargeFileTask(ProgressDialog dialog) {
this.dialog = dialog;
}
protected void onPreExecute() {
dialog.show();
}
protected void onPostExecute(Void unused) {
dialog.dismiss();
}
#Override
protected Void doInBackground(Void... arg0) {
download();
return null;
}
}
private void download ()
{
try
{
long startTime = System.currentTimeMillis();
URL u = new URL("http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File("/sdcard/","my.mp3"));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
int downloadedSize = 0;
while ( (len1 = in.read(buffer)) != -1 )
{
f.write(buffer,0, len1);
downloadedSize += len1;
ReturnDownloadedBytes(downloadedSize);
}
f.close();
Log.d("ImageManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
}
catch (IOException e)
{
Log.d("ImageManager", "Error" + ((System.currentTimeMillis()) / 1000) + e + " sec");
}
}
private void ReturnDownloadedBytes(int size)
{
text.setText(String.valueOf(size));
}
Error says: Only the original thread that created a view hierarchy can touch its views.
i think this means that i create textview from one therad and trying to get access from another one (AsyncTask) but how to get it?
Thanks
EDIT
here is the all code. but even if i send in publishProgress(downloadedSize) int value = 10 it alwys outputs in text.setText(String.valueOf(progress)); different values like [Ljava.lang.float;#43ed62f78
public class list extends Activity {
private TextView text;
#Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.main);
text = (TextView)findViewById(R.id.result);
}
public void selfDestruct(View view) {
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("????????. ?????...");
new DownloadLargeFileTask(dialog).execute();
}
private class DownloadLargeFileTask extends AsyncTask<Void, Integer, Void>
{
private final ProgressDialog dialog;
public DownloadLargeFileTask(ProgressDialog dialog) {
this.dialog = dialog;
}
protected void onPreExecute() {
dialog.show();
}
protected void onPostExecute(Void unused) {
dialog.dismiss();
}
protected void onProgressUpdate(Integer...progress) {
text.setText(String.valueOf(progress));
}
#Override
protected Void doInBackground(Void... arg0) {
try
{
long startTime = System.currentTimeMillis();
URL u = new URL("http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File("/sdcard/","my.mp3"));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
int downloadedSize = 10;
while ( (len1 = in.read(buffer)) != -1 )
{
f.write(buffer,0, len1);
//downloadedSize += len1;
**publishProgress(downloadedSize);**
}
f.close();
Log.d("ImageManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
}
catch (IOException e)
{
Log.d("ImageManager", "Error" + ((System.currentTimeMillis()) / 1000) + e + " sec");
}
return null;
}
}
You are correct in your assessment of the error. I'm assuming that text is a TextView object that is defined in your Activity, and as such it is created in the UI thread. The code that runs within doInBackground() runs in a separate thread. Only the UI thread can perform updates to UI elements, so when you try to call setText you get the error message that you reported.
Abhinav is also correct in how to fix the issue, as AsyncTask has a method that you can call to send updates from the background thread to the UI thread: publishProgress, which calls onProgressUpdate().
Add this method to your AsyncTask:
#Override
protected void onProgressUpdate(Integer... integer){
text.setText(integer[0].toString());
}
And change the while loop in download():
while ( (len1 = in.read(buffer)) != -1 )
{
f.write(buffer,0, len1);
downloadedSize += len1;
publishProgress(downloadedSize);
}
You can change the UI by publishing the progress to the UI thread. Call publishProgress from doInBackground. This will call onProgressUpdate in your AsyncTask from where you can update the UI.
You will have to define onProgressUpdate in your AsyncTask. http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)