Question

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");
          }
        });
}
Was it helpful?

Solution 2

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

OTHER TIPS

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! :)

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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top