0fcf68399f7250fe64f88874c8d38f5f8a8482f4
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / fragment / FileDetailFragment.java
1 /* ownCloud Android client application
2 * Copyright (C) 2011 Bartek Przybylski
3 * Copyright (C) 2012-2013 ownCloud Inc.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2,
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18 package com.owncloud.android.ui.fragment;
19
20 import java.lang.ref.WeakReference;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import android.accounts.Account;
25 import android.content.Intent;
26 import android.os.Bundle;
27 import android.view.LayoutInflater;
28 import android.view.View;
29 import android.view.View.OnClickListener;
30 import android.view.ViewGroup;
31 import android.widget.CheckBox;
32 import android.widget.ImageView;
33 import android.widget.ProgressBar;
34 import android.widget.TextView;
35
36 import com.actionbarsherlock.view.Menu;
37 import com.actionbarsherlock.view.MenuInflater;
38 import com.actionbarsherlock.view.MenuItem;
39 import com.owncloud.android.R;
40 import com.owncloud.android.datamodel.FileDataStorageManager;
41 import com.owncloud.android.datamodel.OCFile;
42 import com.owncloud.android.files.services.FileObserverService;
43 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
44 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
45 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
46 import com.owncloud.android.ui.activity.FileActivity;
47 import com.owncloud.android.ui.activity.FileDisplayActivity;
48 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
49 import com.owncloud.android.ui.dialog.EditNameDialog;
50 import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
51 import com.owncloud.android.utils.DisplayUtils;
52 import com.owncloud.android.utils.Log_OC;
53
54
55 /**
56 * This Fragment is used to display the details about a file.
57 *
58 * @author Bartek Przybylski
59 * @author David A. Velasco
60 */
61 public class FileDetailFragment extends FileFragment implements
62 OnClickListener,
63 ConfirmationDialogFragment.ConfirmationDialogFragmentListener, EditNameDialogListener {
64
65 private int mLayout;
66 private View mView;
67 private Account mAccount;
68
69 public ProgressListener mProgressListener;
70
71 private static final String TAG = FileDetailFragment.class.getSimpleName();
72 public static final String FTAG_CONFIRMATION = "REMOVE_CONFIRMATION_FRAGMENT";
73
74
75 /**
76 * Creates an empty details fragment.
77 *
78 * It's necessary to keep a public constructor without parameters; the system uses it when tries to reinstantiate a fragment automatically.
79 */
80 public FileDetailFragment() {
81 super();
82 mAccount = null;
83 mLayout = R.layout.file_details_empty;
84 mProgressListener = null;
85 }
86
87 /**
88 * Creates a details fragment.
89 *
90 * When 'fileToDetail' or 'ocAccount' are null, creates a dummy layout (to use when a file wasn't tapped before).
91 *
92 * @param fileToDetail An {@link OCFile} to show in the fragment
93 * @param ocAccount An ownCloud account; needed to start downloads
94 */
95 public FileDetailFragment(OCFile fileToDetail, Account ocAccount) {
96 super(fileToDetail);
97 mAccount = ocAccount;
98 mLayout = R.layout.file_details_empty;
99 mProgressListener = null;
100 }
101
102
103 @Override
104 public void onCreate(Bundle savedInstanceState) {
105 super.onCreate(savedInstanceState);
106 setHasOptionsMenu(true);
107 }
108
109
110 @Override
111 public View onCreateView(LayoutInflater inflater, ViewGroup container,
112 Bundle savedInstanceState) {
113 //super.onCreateView(inflater, container, savedInstanceState);
114
115 if (savedInstanceState != null) {
116 setFile((OCFile)savedInstanceState.getParcelable(FileActivity.EXTRA_FILE));
117 mAccount = savedInstanceState.getParcelable(FileActivity.EXTRA_ACCOUNT);
118 }
119
120 if(getFile() != null && mAccount != null) {
121 mLayout = R.layout.file_details_fragment;
122 }
123
124 View view = null;
125 view = inflater.inflate(mLayout, null);
126 mView = view;
127
128 if (mLayout == R.layout.file_details_fragment) {
129 mView.findViewById(R.id.fdKeepInSync).setOnClickListener(this);
130 ProgressBar progressBar = (ProgressBar)mView.findViewById(R.id.fdProgressBar);
131 mProgressListener = new ProgressListener(progressBar);
132 mView.findViewById(R.id.fdCancelBtn).setOnClickListener(this);
133 }
134
135 updateFileDetails(false, false);
136 return view;
137 }
138
139 /**
140 * {@inheritDoc}
141 */
142 @Override
143 public void onActivityCreated(Bundle savedInstanceState) {
144 super.onActivityCreated(savedInstanceState);
145 if (mAccount != null) {
146 OCFile file = ((FileActivity)getActivity()).getStorageManager().
147 getFileByPath(getFile().getRemotePath());
148 if (file != null) {
149 setFile(file);
150 }
151 }
152 }
153
154
155 @Override
156 public void onSaveInstanceState(Bundle outState) {
157 super.onSaveInstanceState(outState);
158 outState.putParcelable(FileActivity.EXTRA_FILE, getFile());
159 outState.putParcelable(FileActivity.EXTRA_ACCOUNT, mAccount);
160 }
161
162 @Override
163 public void onStart() {
164 super.onStart();
165 listenForTransferProgress();
166 }
167
168 @Override
169 public void onStop() {
170 super.onStop();
171 leaveTransferProgress();
172 }
173
174
175 @Override
176 public View getView() {
177 return super.getView() == null ? mView : super.getView();
178 }
179
180
181 /**
182 * {@inheritDoc}
183 */
184 @Override
185 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
186 super.onCreateOptionsMenu(menu, inflater);
187 inflater.inflate(R.menu.file_actions_menu, menu);
188 MenuItem item = menu.findItem(R.id.action_see_details);
189 if (item != null) {
190 item.setVisible(false);
191 item.setEnabled(false);
192 }
193
194 // Send file
195 item = menu.findItem(R.id.action_send_file);
196 boolean sendEnabled = getString(R.string.send_files_to_other_apps).equalsIgnoreCase("on");
197 if (item != null) {
198 if (sendEnabled) {
199 item.setVisible(true);
200 item.setEnabled(true);
201 } else {
202 item.setVisible(false);
203 item.setEnabled(false);
204
205 }
206 }
207 }
208
209
210 /**
211 * {@inheritDoc}
212 */
213 @Override
214 public void onPrepareOptionsMenu (Menu menu) {
215 super.onPrepareOptionsMenu(menu);
216
217 List<Integer> toHide = new ArrayList<Integer>();
218 List<Integer> toShow = new ArrayList<Integer>();
219 OCFile file = getFile();
220
221 FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder();
222 boolean downloading = downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file);
223 FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder();
224 boolean uploading = uploaderBinder != null && uploaderBinder.isUploading(mAccount, getFile());
225
226 if (downloading || uploading) {
227 toHide.add(R.id.action_download_file);
228 toHide.add(R.id.action_rename_file);
229 toHide.add(R.id.action_remove_file);
230 toHide.add(R.id.action_open_file_with);
231 if (!downloading) {
232 toHide.add(R.id.action_cancel_download);
233 toShow.add(R.id.action_cancel_upload);
234 } else {
235 toHide.add(R.id.action_cancel_upload);
236 toShow.add(R.id.action_cancel_download);
237 }
238
239 } else if (file != null && file.isDown()) {
240 toHide.add(R.id.action_download_file);
241 toHide.add(R.id.action_cancel_download);
242 toHide.add(R.id.action_cancel_upload);
243
244 toShow.add(R.id.action_rename_file);
245 toShow.add(R.id.action_remove_file);
246 toShow.add(R.id.action_open_file_with);
247 toShow.add(R.id.action_sync_file);
248
249 } else if (file != null) {
250 toHide.add(R.id.action_open_file_with);
251 toHide.add(R.id.action_cancel_download);
252 toHide.add(R.id.action_cancel_upload);
253 toHide.add(R.id.action_sync_file);
254
255 toShow.add(R.id.action_rename_file);
256 toShow.add(R.id.action_remove_file);
257 toShow.add(R.id.action_download_file);
258
259 } else {
260 toHide.add(R.id.action_open_file_with);
261 toHide.add(R.id.action_cancel_download);
262 toHide.add(R.id.action_cancel_upload);
263 toHide.add(R.id.action_sync_file);
264 toHide.add(R.id.action_download_file);
265 toHide.add(R.id.action_rename_file);
266 toHide.add(R.id.action_remove_file);
267
268 }
269
270 // Options shareLink
271 if (!file.isShareByLink()) {
272 toHide.add(R.id.action_unshare_file);
273 } else {
274 toShow.add(R.id.action_unshare_file);
275 }
276
277 MenuItem item = null;
278 for (int i : toHide) {
279 item = menu.findItem(i);
280 if (item != null) {
281 item.setVisible(false);
282 item.setEnabled(false);
283 }
284 }
285 for (int i : toShow) {
286 item = menu.findItem(i);
287 if (item != null) {
288 item.setVisible(true);
289 item.setEnabled(true);
290 }
291 }
292 }
293
294
295 /**
296 * {@inheritDoc}
297 */
298 @Override
299 public boolean onOptionsItemSelected(MenuItem item) {
300 switch (item.getItemId()) {
301 case R.id.action_share_file: {
302 mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile());
303 return true;
304 }
305 case R.id.action_unshare_file: {
306 mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile());
307 return true;
308 }
309 case R.id.action_open_file_with: {
310 mContainerActivity.getFileOperationsHelper().openFile(getFile());
311 return true;
312 }
313 case R.id.action_remove_file: {
314 showDialogToRemoveFile();
315 return true;
316 }
317 case R.id.action_rename_file: {
318 showDialogToRenameFile();
319 return true;
320 }
321 case R.id.action_cancel_download:
322 case R.id.action_cancel_upload: {
323 ((FileDisplayActivity)mContainerActivity).cancelTransference(getFile());
324 return true;
325 }
326 case R.id.action_download_file:
327 case R.id.action_sync_file: {
328 mContainerActivity.getFileOperationsHelper().syncFile(getFile());
329 return true;
330 }
331 case R.id.action_send_file: {
332 // Obtain the file
333 if (!getFile().isDown()) { // Download the file
334 Log_OC.d(TAG, getFile().getRemotePath() + " : File must be downloaded");
335 ((FileDisplayActivity)mContainerActivity).startDownloadForSending(getFile());
336
337 } else {
338 ((FileDisplayActivity)mContainerActivity).getFileOperationsHelper().sendDownloadedFile(getFile());
339 }
340 return true;
341 }
342 default:
343 return false;
344 }
345 }
346
347 @Override
348 public void onClick(View v) {
349 switch (v.getId()) {
350 case R.id.fdKeepInSync: {
351 toggleKeepInSync();
352 break;
353 }
354 case R.id.fdCancelBtn: {
355 ((FileDisplayActivity)mContainerActivity).cancelTransference(getFile());
356 break;
357 }
358 default:
359 Log_OC.e(TAG, "Incorrect view clicked!");
360 }
361 }
362
363
364 private void toggleKeepInSync() {
365 CheckBox cb = (CheckBox) getView().findViewById(R.id.fdKeepInSync);
366 OCFile file = getFile();
367 file.setKeepInSync(cb.isChecked());
368 mContainerActivity.getStorageManager().saveFile(file);
369
370 /// register the OCFile instance in the observer service to monitor local updates;
371 /// if necessary, the file is download
372 Intent intent = new Intent(getActivity().getApplicationContext(),
373 FileObserverService.class);
374 intent.putExtra(FileObserverService.KEY_FILE_CMD,
375 (cb.isChecked()?
376 FileObserverService.CMD_ADD_OBSERVED_FILE:
377 FileObserverService.CMD_DEL_OBSERVED_FILE));
378 intent.putExtra(FileObserverService.KEY_CMD_ARG_FILE, file);
379 intent.putExtra(FileObserverService.KEY_CMD_ARG_ACCOUNT, mAccount);
380 getActivity().startService(intent);
381
382 if (file.keepInSync()) {
383 mContainerActivity.getFileOperationsHelper().syncFile(getFile());
384 }
385 }
386
387 private void showDialogToRemoveFile() {
388 OCFile file = getFile();
389 ConfirmationDialogFragment confDialog = ConfirmationDialogFragment.newInstance(
390 R.string.confirmation_remove_alert,
391 new String[]{file.getFileName()},
392 file.isDown() ? R.string.confirmation_remove_remote_and_local : R.string.confirmation_remove_remote,
393 file.isDown() ? R.string.confirmation_remove_local : -1,
394 R.string.common_cancel);
395 confDialog.setOnConfirmationListener(this);
396 confDialog.show(getFragmentManager(), FTAG_CONFIRMATION);
397 }
398
399
400 private void showDialogToRenameFile() {
401 OCFile file = getFile();
402 String fileName = file.getFileName();
403 int extensionStart = file.isFolder() ? -1 : fileName.lastIndexOf(".");
404 int selectionEnd = (extensionStart >= 0) ? extensionStart : fileName.length();
405 EditNameDialog dialog = EditNameDialog.newInstance(getString(R.string.rename_dialog_title), fileName, 0, selectionEnd, this);
406 dialog.show(getFragmentManager(), "nameeditdialog");
407 }
408
409
410 @Override
411 public void onConfirmation(String callerTag) {
412 OCFile file = getFile();
413 if (callerTag.equals(FTAG_CONFIRMATION)) {
414 if (mContainerActivity.getStorageManager().getFileById(file.getFileId()) != null) {
415 mContainerActivity.getFileOperationsHelper().removeFile(file, true);
416 }
417 }
418 }
419
420 @Override
421 public void onNeutral(String callerTag) {
422 OCFile file = getFile();
423 mContainerActivity.getStorageManager().removeFile(file, false, true); // TODO perform in background task / new thread
424 if (file.getStoragePath() != null) {
425 file.setStoragePath(null);
426 updateFileDetails(file, mAccount);
427 }
428 }
429
430 @Override
431 public void onCancel(String callerTag) {
432 Log_OC.d(TAG, "REMOVAL CANCELED");
433 }
434
435
436 /**
437 * Check if the fragment was created with an empty layout. An empty fragment can't show file details, must be replaced.
438 *
439 * @return True when the fragment was created with the empty layout.
440 */
441 public boolean isEmpty() {
442 return (mLayout == R.layout.file_details_empty || getFile() == null || mAccount == null);
443 }
444
445
446 /**
447 * Use this method to signal this Activity that it shall update its view.
448 *
449 * @param file : An {@link OCFile}
450 */
451 public void updateFileDetails(OCFile file, Account ocAccount) {
452 setFile(file);
453 mAccount = ocAccount;
454 updateFileDetails(false, false);
455 }
456
457 /**
458 * Updates the view with all relevant details about that file.
459 *
460 * TODO Remove parameter when the transferring state of files is kept in database.
461 *
462 * TODO REFACTORING! this method called 5 times before every time the fragment is shown!
463 *
464 * @param transferring Flag signaling if the file should be considered as downloading or uploading,
465 * although {@link FileDownloaderBinder#isDownloading(Account, OCFile)} and
466 * {@link FileUploaderBinder#isUploading(Account, OCFile)} return false.
467 *
468 * @param refresh If 'true', try to refresh the whole file from the database
469 */
470 public void updateFileDetails(boolean transferring, boolean refresh) {
471
472 if (readyToShow()) {
473 FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
474 if (refresh && storageManager != null) {
475 setFile(storageManager.getFileByPath(getFile().getRemotePath()));
476 }
477 OCFile file = getFile();
478
479 // set file details
480 setFilename(file.getFileName());
481 setFiletype(file.getMimetype());
482 setFilesize(file.getFileLength());
483 if(ocVersionSupportsTimeCreated()){
484 setTimeCreated(file.getCreationTimestamp());
485 }
486
487 setTimeModified(file.getModificationTimestamp());
488
489 CheckBox cb = (CheckBox)getView().findViewById(R.id.fdKeepInSync);
490 cb.setChecked(file.keepInSync());
491
492 // configure UI for depending upon local state of the file
493 FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder();
494 FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder();
495 if (transferring || (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) || (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file))) {
496 setButtonsForTransferring();
497
498 } else if (file.isDown()) {
499
500 setButtonsForDown();
501
502 } else {
503 // TODO load default preview image; when the local file is removed, the preview remains there
504 setButtonsForRemote();
505 }
506 }
507 getView().invalidate();
508 }
509
510 /**
511 * Checks if the fragment is ready to show details of a OCFile
512 *
513 * @return 'True' when the fragment is ready to show details of a file
514 */
515 private boolean readyToShow() {
516 return (getFile() != null && mAccount != null && mLayout == R.layout.file_details_fragment);
517 }
518
519
520 /**
521 * Updates the filename in view
522 * @param filename to set
523 */
524 private void setFilename(String filename) {
525 TextView tv = (TextView) getView().findViewById(R.id.fdFilename);
526 if (tv != null)
527 tv.setText(filename);
528 }
529
530 /**
531 * Updates the MIME type in view
532 * @param mimetype to set
533 */
534 private void setFiletype(String mimetype) {
535 TextView tv = (TextView) getView().findViewById(R.id.fdType);
536 if (tv != null) {
537 String printableMimetype = DisplayUtils.convertMIMEtoPrettyPrint(mimetype);;
538 tv.setText(printableMimetype);
539 }
540 ImageView iv = (ImageView) getView().findViewById(R.id.fdIcon);
541 if (iv != null) {
542 iv.setImageResource(DisplayUtils.getResourceId(mimetype));
543 }
544 }
545
546 /**
547 * Updates the file size in view
548 * @param filesize in bytes to set
549 */
550 private void setFilesize(long filesize) {
551 TextView tv = (TextView) getView().findViewById(R.id.fdSize);
552 if (tv != null)
553 tv.setText(DisplayUtils.bytesToHumanReadable(filesize));
554 }
555
556 /**
557 * Updates the time that the file was created in view
558 * @param milliseconds Unix time to set
559 */
560 private void setTimeCreated(long milliseconds){
561 TextView tv = (TextView) getView().findViewById(R.id.fdCreated);
562 TextView tvLabel = (TextView) getView().findViewById(R.id.fdCreatedLabel);
563 if(tv != null){
564 tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
565 tv.setVisibility(View.VISIBLE);
566 tvLabel.setVisibility(View.VISIBLE);
567 }
568 }
569
570 /**
571 * Updates the time that the file was last modified
572 * @param milliseconds Unix time to set
573 */
574 private void setTimeModified(long milliseconds){
575 TextView tv = (TextView) getView().findViewById(R.id.fdModified);
576 if(tv != null){
577 tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
578 }
579 }
580
581 /**
582 * Enables or disables buttons for a file being downloaded
583 */
584 private void setButtonsForTransferring() {
585 if (!isEmpty()) {
586 // let's protect the user from himself ;)
587 getView().findViewById(R.id.fdKeepInSync).setEnabled(false);
588
589 // show the progress bar for the transfer
590 getView().findViewById(R.id.fdProgressBlock).setVisibility(View.VISIBLE);
591 TextView progressText = (TextView)getView().findViewById(R.id.fdProgressText);
592 progressText.setVisibility(View.VISIBLE);
593 FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder();
594 FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder();
595 if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, getFile())) {
596 progressText.setText(R.string.downloader_download_in_progress_ticker);
597 } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, getFile())) {
598 progressText.setText(R.string.uploader_upload_in_progress_ticker);
599 }
600 }
601 }
602
603 /**
604 * Enables or disables buttons for a file locally available
605 */
606 private void setButtonsForDown() {
607 if (!isEmpty()) {
608 getView().findViewById(R.id.fdKeepInSync).setEnabled(true);
609
610 // hides the progress bar
611 getView().findViewById(R.id.fdProgressBlock).setVisibility(View.GONE);
612 TextView progressText = (TextView)getView().findViewById(R.id.fdProgressText);
613 progressText.setVisibility(View.GONE);
614 }
615 }
616
617 /**
618 * Enables or disables buttons for a file not locally available
619 */
620 private void setButtonsForRemote() {
621 if (!isEmpty()) {
622 getView().findViewById(R.id.fdKeepInSync).setEnabled(true);
623
624 // hides the progress bar
625 getView().findViewById(R.id.fdProgressBlock).setVisibility(View.GONE);
626 TextView progressText = (TextView)getView().findViewById(R.id.fdProgressText);
627 progressText.setVisibility(View.GONE);
628 }
629 }
630
631
632 /**
633 * In ownCloud 3.X.X and 4.X.X there is a bug that SabreDAV does not return
634 * the time that the file was created. There is a chance that this will
635 * be fixed in future versions. Use this method to check if this version of
636 * ownCloud has this fix.
637 * @return True, if ownCloud the ownCloud version is supporting creation time
638 */
639 private boolean ocVersionSupportsTimeCreated(){
640 /*if(mAccount != null){
641 AccountManager accManager = (AccountManager) getActivity().getSystemService(Context.ACCOUNT_SERVICE);
642 OwnCloudVersion ocVersion = new OwnCloudVersion(accManager
643 .getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));
644 if(ocVersion.compareTo(new OwnCloudVersion(0x030000)) < 0) {
645 return true;
646 }
647 }*/
648 return false;
649 }
650
651
652 public void onDismiss(EditNameDialog dialog) {
653 if (dialog.getResult()) {
654 String newFilename = dialog.getNewFilename();
655 Log_OC.d(TAG, "name edit dialog dismissed with new name " + newFilename);
656 mContainerActivity.getFileOperationsHelper().renameFile(getFile(), newFilename);
657 }
658 }
659
660
661 public void listenForTransferProgress() {
662 if (mProgressListener != null) {
663 if (mContainerActivity.getFileDownloaderBinder() != null) {
664 mContainerActivity.getFileDownloaderBinder().addDatatransferProgressListener(mProgressListener, mAccount, getFile());
665 }
666 if (mContainerActivity.getFileUploaderBinder() != null) {
667 mContainerActivity.getFileUploaderBinder().addDatatransferProgressListener(mProgressListener, mAccount, getFile());
668 }
669 }
670 }
671
672
673 public void leaveTransferProgress() {
674 if (mProgressListener != null) {
675 if (mContainerActivity.getFileDownloaderBinder() != null) {
676 mContainerActivity.getFileDownloaderBinder().removeDatatransferProgressListener(mProgressListener, mAccount, getFile());
677 }
678 if (mContainerActivity.getFileUploaderBinder() != null) {
679 mContainerActivity.getFileUploaderBinder().removeDatatransferProgressListener(mProgressListener, mAccount, getFile());
680 }
681 }
682 }
683
684
685
686 /**
687 * Helper class responsible for updating the progress bar shown for file uploading or downloading
688 *
689 * @author David A. Velasco
690 */
691 private class ProgressListener implements OnDatatransferProgressListener {
692 int mLastPercent = 0;
693 WeakReference<ProgressBar> mProgressBar = null;
694
695 ProgressListener(ProgressBar progressBar) {
696 mProgressBar = new WeakReference<ProgressBar>(progressBar);
697 }
698
699 @Override
700 public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filename) {
701 int percent = (int)(100.0*((double)totalTransferredSoFar)/((double)totalToTransfer));
702 if (percent != mLastPercent) {
703 ProgressBar pb = mProgressBar.get();
704 if (pb != null) {
705 pb.setProgress(percent);
706 pb.postInvalidate();
707 }
708 }
709 mLastPercent = percent;
710 }
711
712 };
713
714 }