0
votes

Am using the aws SDK to upload set of images. I have a ListView with each list item containing a ProgressBar(Style:Horizontal), I need to set the progress to it based on the file uploaded.

I used the TransferManager from the aws SDK (http://aws.amazon.com/releasenotes/Java/3538638977238478) to get the uploaded data.

I tried this, But its not working:

public class SyncFragment extends Fragment {

    ListView uploadList;
    public UploadAdapter uploadAdapter;

    public ArrayList<QueueItem> queueList = new ArrayList<QueueItem>();

    AWSCredentials myCredentials = new BasicAWSCredentials(Constants.ACCESS_KEY_ID, Constants.SECRET_KEY);
    TransferManager tm = new TransferManager(myCredentials);

    // Empty cons as per documentation of Fragments
    public SyncFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        setHasOptionsMenu(true);
        // Set the queue list
        queueList = ((NSApplication) getActivity().getApplication()).queueList;
        // Init Adapter
        uploadAdapter = new UploadAdapter(getActivity());
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.upload_list, container, false);

        uploadList = (ListView) view.findViewById(R.id.uploadList);
        uploadList.setAdapter(uploadAdapter);

        return view;
    }

    class UploadAdapter extends ArrayAdapter<QueueItem> {

        private LayoutInflater layoutInflater;
        private BitmapFromId bitmapFromId;
        QueueItem item;

        public UploadAdapter(Context context) {
            super(context, 0);
            layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            bitmapFromId = new BitmapFromId(context);
        }

        @Override
        public int getCount() {
            // Set the total list item count
            return queueList.size();
        }

        @Override
        public QueueItem getItem(int position) {
            return queueList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolder holder;
            if (convertView == null) {
                convertView = layoutInflater.inflate(R.layout.listitem_upload, null);
                holder = new ViewHolder();

                holder.albumName = (TextView) convertView.findViewById(R.id.albumTitle);
                holder.thumb = (ImageView) convertView.findViewById(R.id.thumb);
                holder.progressBar = (ProgressBar) convertView.findViewById(R.id.progressbar_Horizontal);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            item = getItem(position);

            item.progress = 0;

            // load bitmap from id
            bitmapFromId.DisplayImage(Long.parseLong(item.itemId), holder.thumb);

            holder.albumName.setText(item.itemName);

            S3PutObjectTask task = new S3PutObjectTask();
            task.execute(item.itemActualPath, item.itemId);

            holder.progressBar.setProgress(item.progress);

            return convertView;
        }

        private class S3PutObjectTask extends AsyncTask<String, Integer, S3TaskResult> {

            int progress;

            protected void onPreExecute() {
                progress = 0;
            }

            protected S3TaskResult doInBackground(String... params) {

                S3TaskResult result = new S3TaskResult();
                // The file location of the image selected.
                String imagePath = params[0];

                // Put the image data into S3.
                try {

                    File image = new java.io.File(imagePath);

                    Transfer myUpload = tm.upload(Constants.getPictureBucket(), params[1] + ".jpg", image);

                    while (myUpload.isDone() == false) {
                        progress = (int) (myUpload.getProgress().getBytesTransfered() * 100 / image.length());
                        publishProgress(progress);
                    }

                    myUpload.waitForCompletion();

                } catch (Exception exception) {

                    result.setErrorMessage(exception.getMessage());
                }

                return result;
            }

            @Override
            protected void onProgressUpdate(Integer... values) {
                item.progress = values[0];
                uploadAdapter.notifyDataSetChanged();
            }

            protected void onPostExecute(S3TaskResult result) {

                Toast.makeText(getActivity(), "uploaded sucessfully!", Toast.LENGTH_SHORT).show();

                if (result.getErrorMessage() != null) {

                    Toast.makeText(getActivity(), "upload failed...", Toast.LENGTH_SHORT).show();
                }
            }

        }

        public class S3TaskResult {
            String errorMessage = null;
            Uri uri = null;

            public String getErrorMessage() {
                return errorMessage;
            }

            public void setErrorMessage(String errorMessage) {
                this.errorMessage = errorMessage;
            }

            public Uri getUri() {
                return uri;
            }

            public void setUri(Uri uri) {
                this.uri = uri;
            }
        }
    }

    public static class ViewHolder {
        ImageView thumb;
        TextView albumName;
        ProgressBar progressBar;
    }

}
1
Could you clarify what's not working? Is the upload completing but you're just not getting progress? Have you tried using the ProgressListener interface? docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/com/amazonaws/… - Bob Kinney
@BobKinney Hi bob thanks for the comment, I tried even with the 'ProgressListner' but it does not give the progress or the number of bytes transfered.. Any ways the Transfer should also return me the bytes transfered right. - sukarno
Sorry, just to be clear, the upload is completing but you're just not getting correct progress updates? - Bob Kinney
@BobKinney Yes! the uploading is completed and onPostExecute am settings the progress to 100 this works, (One done the progress from 0 to it jumps to 100) but am not able to set the progress timely.. :( - sukarno

1 Answers

1
votes

Here is what I see from your code:

  • The way you use TransferManager and the idea to update transfer progress are correct. However I suggest you update the progress once more outside the while loop to get the finish state right.
  • "QueueItem item" in UploadAdapter is very suspicious. All your S3PutObjectTask objects share one item whose value is assigned in getView and is overwritten when Android draws every list item. I believe the progress will mess up when there are more than one tasks running. It's better to associate a queue item and a task together, so that the task can update its progress via associated queue item.
  • Due to view recycling in Android, tasks can be restarted when a list item is redrawn.

I hope the above helps you diagnose the problem.