diff --git a/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java b/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java
index e880e2b9c0055c86691f58d60cb94ff748d39f4f..cceebcd308e4e9f85fee38196fc10feb51f937a3 100644
--- a/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java
+++ b/ring-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.java
@@ -31,6 +31,7 @@ import android.graphics.SurfaceTexture;
 import android.graphics.drawable.Drawable;
 import android.media.MediaPlayer;
 import android.net.Uri;
+import android.os.Build;
 import android.text.format.DateUtils;
 import android.text.format.Formatter;
 import android.util.Log;
@@ -588,6 +589,10 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationViewHo
             if (file.getStatus() == InteractionStatus.TRANSFER_FINISHED) {
                 viewHolder.mMsgDetailTxt.setText(String.format("%s - %s",
                         timeString, Formatter.formatFileSize(viewHolder.itemView.getContext(), file.getTotalSize())));
+            } else if (file.getStatus() == InteractionStatus.TRANSFER_ONGOING) {
+                viewHolder.mMsgDetailTxt.setText(String.format("%s / %s - %s",
+                        Formatter.formatFileSize(viewHolder.itemView.getContext(), file.getBytesProgress()), Formatter.formatFileSize(viewHolder.itemView.getContext(), file.getTotalSize()),
+                        ResourceMapper.getReadableFileTransferStatus(conversationFragment.getActivity(), file.getStatus())));
             } else {
                 viewHolder.mMsgDetailTxt.setText(String.format("%s - %s - %s",
                         timeString, Formatter.formatFileSize(viewHolder.itemView.getContext(), file.getTotalSize()),
@@ -648,13 +653,19 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationViewHo
 
         longPressView.setOnCreateContextMenuListener((menu, v, menuInfo) -> {
             menu.setHeaderTitle(file.getDisplayName());
-            conversationFragment.onCreateContextMenu(menu, v, menuInfo);
-            MenuInflater inflater = conversationFragment.getActivity().getMenuInflater();
-            inflater.inflate(R.menu.conversation_item_actions_file, menu);
-            if (!file.isComplete()) {
+            new MenuInflater(v.getContext()).inflate(R.menu.conversation_item_actions_file, menu);
+            if (file.getStatus() == InteractionStatus.TRANSFER_ONGOING) {
+                menu.findItem(R.id.conv_action_delete).setTitle(android.R.string.cancel);
                 menu.removeItem(R.id.conv_action_download);
                 menu.removeItem(R.id.conv_action_share);
+                menu.removeItem(R.id.conv_action_open);
+            } else {
+                if (!file.isComplete()) {
+                    menu.removeItem(R.id.conv_action_download);
+                    menu.removeItem(R.id.conv_action_share);
+                }
             }
+            conversationFragment.onCreateContextMenu(menu, v, menuInfo);
         });
         longPressView.setOnLongClickListener(v -> {
             if (type == TransferMsgType.AUDIO || type == TransferMsgType.FILE) {
@@ -706,6 +717,17 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationViewHo
                 });
             } else {
                 viewHolder.mAnswerLayout.setVisibility(View.GONE);
+                if (file.getStatus() == InteractionStatus.TRANSFER_ONGOING) {
+                    viewHolder.progress.setMax((int) (file.getTotalSize() / 1024));
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                        viewHolder.progress.setProgress((int) (file.getBytesProgress() / 1024), true);
+                    } else {
+                        viewHolder.progress.setProgress((int) (file.getBytesProgress() / 1024));
+                    }
+                    viewHolder.progress.show();
+                } else {
+                    viewHolder.progress.hide();
+                }
             }
         }
     }
diff --git a/ring-android/app/src/main/java/cx/ring/views/ConversationViewHolder.java b/ring-android/app/src/main/java/cx/ring/views/ConversationViewHolder.java
index de764a619a60dc111067e07b9a3a56a8f8f54b2f..a43ec078c7c4dad5e3a4f44c2480dce215a0b08d 100644
--- a/ring-android/app/src/main/java/cx/ring/views/ConversationViewHolder.java
+++ b/ring-android/app/src/main/java/cx/ring/views/ConversationViewHolder.java
@@ -20,6 +20,7 @@
  */
 package cx.ring.views;
 
+import androidx.core.widget.ContentLoadingProgressBar;
 import androidx.recyclerview.widget.RecyclerView;
 
 import android.animation.ValueAnimator;
@@ -30,7 +31,6 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import cx.ring.R;
@@ -54,7 +54,7 @@ public class ConversationViewHolder extends RecyclerView.ViewHolder {
     public ViewGroup mAnswerLayout;
     public View btnAccept;
     public View btnRefuse;
-    public ProgressBar progress;
+    public ContentLoadingProgressBar progress;
     public MediaPlayer player;
     public TextureView video;
     public Surface surface = null;
diff --git a/ring-android/app/src/main/res/layout/item_conv_file_me.xml b/ring-android/app/src/main/res/layout/item_conv_file_me.xml
index e31c3434ce9aa8e58c2c74749b22dceb632a5ed5..1bcd36c30605e9532a12a094365ead6bb01390ea 100644
--- a/ring-android/app/src/main/res/layout/item_conv_file_me.xml
+++ b/ring-android/app/src/main/res/layout/item_conv_file_me.xml
@@ -92,6 +92,15 @@
                     android:textSize="16sp"
                     tools:text="long_file_name_gtest_long_file_name_gtest.jpg" />
 
+                <androidx.core.widget.ContentLoadingProgressBar
+                    android:id="@+id/progress"
+                    style="@style/Widget.AppCompat.ProgressBar.Horizontal"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:indeterminate="false"
+                    android:visibility="gone"
+                    tools:visibility="visible" />
+
                 <TextView
                     android:id="@+id/file_details_txt"
                     android:layout_width="wrap_content"
@@ -104,15 +113,6 @@
                     android:textSize="12sp"
                     tools:text="1 mo - 12 mars" />
 
-                <ProgressBar
-                    android:id="@+id/progress"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:indeterminate="false"
-                    android:paddingBottom="8dp"
-                    android:visibility="gone"
-                    tools:visibility="gone" />
-
                 <LinearLayout
                     android:id="@+id/llAnswer"
                     android:layout_width="match_parent"
diff --git a/ring-android/app/src/main/res/layout/item_conv_file_me_tv.xml b/ring-android/app/src/main/res/layout/item_conv_file_me_tv.xml
index bd9278b8d480e593b4a4599eac26926a59987926..a765d3b6f10449a394822ecfe3b1a7bf569a3453 100644
--- a/ring-android/app/src/main/res/layout/item_conv_file_me_tv.xml
+++ b/ring-android/app/src/main/res/layout/item_conv_file_me_tv.xml
@@ -91,6 +91,15 @@
                     android:textSize="16sp"
                     tools:text="long_file_name_gtest_long_file_name_gtest.jpg" />
 
+                <androidx.core.widget.ContentLoadingProgressBar
+                    android:id="@+id/progress"
+                    style="@style/Widget.AppCompat.ProgressBar.Horizontal"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:indeterminate="false"
+                    android:visibility="gone"
+                    tools:visibility="gone" />
+
                 <TextView
                     android:id="@+id/file_details_txt"
                     android:layout_width="wrap_content"
@@ -103,15 +112,6 @@
                     android:textSize="12sp"
                     tools:text="1 mo - 12 mars" />
 
-                <ProgressBar
-                    android:id="@+id/progress"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:indeterminate="false"
-                    android:paddingBottom="8dp"
-                    android:visibility="gone"
-                    tools:visibility="gone" />
-
                 <LinearLayout
                     android:id="@+id/llAnswer"
                     android:layout_width="match_parent"
diff --git a/ring-android/app/src/main/res/layout/item_conv_file_peer.xml b/ring-android/app/src/main/res/layout/item_conv_file_peer.xml
index 60ebb46ab09d19c969cf71562863c4e87e781a03..42cfad350edcf9492247436f4e155b01ffcaa1cc 100644
--- a/ring-android/app/src/main/res/layout/item_conv_file_peer.xml
+++ b/ring-android/app/src/main/res/layout/item_conv_file_peer.xml
@@ -17,51 +17,50 @@
   ~ along with this program; if not, write to the Free Software
   ~  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/file_layout"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingBottom="8dp"
     android:clickable="true"
     android:descendantFocusability="blocksDescendants"
     android:focusable="true"
+    android:gravity="center"
     android:orientation="vertical"
-    android:gravity="center">
+    android:paddingBottom="8dp">
 
     <TextView
         android:id="@+id/msg_details_txt_perm"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:visibility="gone"
         android:textColor="@color/textColorSecondary"
         android:textSize="@dimen/conversation_timestamp_textsize"
+        android:visibility="gone"
         tools:text="@string/time_just_now" />
 
     <RelativeLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingTop="8dp"
         android:paddingStart="@dimen/padding_medium"
+        android:paddingTop="8dp"
         android:paddingEnd="@dimen/padding_large">
 
         <ImageView
             android:id="@+id/photo"
             android:layout_width="@dimen/conversation_avatar_size"
             android:layout_height="@dimen/conversation_avatar_size"
-            android:background="@null"
             android:layout_alignBottom="@id/fileInfoLayout"
-            android:scaleType="centerCrop"/>
+            android:background="@null"
+            android:scaleType="centerCrop" />
 
         <LinearLayout
             android:id="@+id/fileInfoLayout"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_toEndOf="@+id/photo"
             android:layout_marginStart="@dimen/padding_medium"
             android:layout_marginEnd="20dp"
+            android:layout_toEndOf="@+id/photo"
             android:background="@drawable/textmsg_call_background"
             android:orientation="horizontal">
 
@@ -98,6 +97,17 @@
                     android:textSize="16sp"
                     tools:text="long_file_name_gtest.jpg" />
 
+                <androidx.core.widget.ContentLoadingProgressBar
+                    android:id="@+id/progress"
+                    style="@style/Widget.AppCompat.ProgressBar.Horizontal"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:indeterminate="false"
+                    android:visibility="gone"
+                    tools:max="100"
+                    tools:progress="40"
+                    tools:visibility="visible" />
+
                 <TextView
                     android:id="@+id/file_details_txt"
                     android:layout_width="wrap_content"
@@ -110,15 +120,6 @@
                     android:textSize="12sp"
                     tools:text="1 mo - 12 mars" />
 
-                <ProgressBar
-                    android:id="@+id/progress"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:indeterminate="false"
-                    android:paddingBottom="8dp"
-                    android:visibility="gone"
-                    tools:visibility="gone" />
-
                 <LinearLayout
                     android:id="@+id/llAnswer"
                     android:layout_width="match_parent"
@@ -126,7 +127,7 @@
                     android:minWidth="350dp"
                     android:orientation="horizontal"
                     android:visibility="gone"
-                    tools:visibility="visible">
+                    tools:visibility="gone">
 
                     <com.google.android.material.button.MaterialButton
                         android:id="@+id/btnRefuse"
diff --git a/ring-android/app/src/main/res/layout/item_conv_file_peer_tv.xml b/ring-android/app/src/main/res/layout/item_conv_file_peer_tv.xml
index aa2a4c1c1d9ff6a8afbee2fc309e91275aa2b29f..ab8876d141dc958c1b0d129c718c293ebead7c78 100644
--- a/ring-android/app/src/main/res/layout/item_conv_file_peer_tv.xml
+++ b/ring-android/app/src/main/res/layout/item_conv_file_peer_tv.xml
@@ -97,6 +97,15 @@
                     android:textSize="16sp"
                     tools:text="long_file_name_gtest.jpg" />
 
+                <androidx.core.widget.ContentLoadingProgressBar
+                    android:id="@+id/progress"
+                    style="@style/Widget.AppCompat.ProgressBar.Horizontal"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:indeterminate="false"
+                    android:visibility="gone"
+                    tools:visibility="gone" />
+
                 <TextView
                     android:id="@+id/file_details_txt"
                     android:layout_width="wrap_content"
@@ -109,15 +118,6 @@
                     android:textSize="12sp"
                     tools:text="1 mo - 12 mars" />
 
-                <ProgressBar
-                    android:id="@+id/progress"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:indeterminate="false"
-                    android:paddingBottom="8dp"
-                    android:visibility="gone"
-                    tools:visibility="gone" />
-
                 <LinearLayout
                     android:id="@+id/llAnswer"
                     android:layout_width="match_parent"
diff --git a/ring-android/libringclient/src/main/java/cx/ring/facades/ConversationFacade.java b/ring-android/libringclient/src/main/java/cx/ring/facades/ConversationFacade.java
index e603c789842be6428fcb934a3451b5a1826ec7be..bdcb9c405a94a49e0d650b8f860807a98c1e7ba7 100644
--- a/ring-android/libringclient/src/main/java/cx/ring/facades/ConversationFacade.java
+++ b/ring-android/libringclient/src/main/java/cx/ring/facades/ConversationFacade.java
@@ -290,13 +290,17 @@ public class ConversationFacade {
     public void deleteConversationItem(Interaction element) {
         if (element.getType() == InteractionType.DATA_TRANSFER) {
             DataTransfer transfer = (DataTransfer) element;
-            File file = mDeviceRuntimeService.getConversationPath(transfer.getPeerId(), transfer.getStoragePath());
-            mDisposableBag.add(Completable.mergeArrayDelayError(
-                    mHistoryService.deleteInteraction(element.getId(), element.getAccount()),
-                    Completable.fromAction(file::delete).subscribeOn(Schedulers.io()))
-                    .andThen(startConversation(transfer.getAccount(), new Uri(transfer.getConversation().getParticipant())))
-                    .subscribe(c -> c.removeInteraction(transfer),
-                            e -> Log.e(TAG, "Can't delete file transfer", e)));
+            if (transfer.getStatus() == InteractionStatus.TRANSFER_ONGOING) {
+                mAccountService.cancelDataTransfer(transfer.getDaemonId());
+            } else {
+                File file = mDeviceRuntimeService.getConversationPath(transfer.getPeerId(), transfer.getStoragePath());
+                mDisposableBag.add(Completable.mergeArrayDelayError(
+                        mHistoryService.deleteInteraction(element.getId(), element.getAccount()),
+                        Completable.fromAction(file::delete).subscribeOn(Schedulers.io()))
+                        .andThen(startConversation(transfer.getAccount(), new Uri(transfer.getConversation().getParticipant())))
+                        .subscribe(c -> c.removeInteraction(transfer),
+                                e -> Log.e(TAG, "Can't delete file transfer", e)));
+            }
         } else {
             // handling is the same for calls and texts
             mDisposableBag.add(Completable.mergeArrayDelayError(mHistoryService.deleteInteraction(element.getId(), element.getAccount()).subscribeOn(Schedulers.io()))
diff --git a/ring-android/libringclient/src/main/java/cx/ring/services/AccountService.java b/ring-android/libringclient/src/main/java/cx/ring/services/AccountService.java
index cac1bd493d26e21019c8543a8254417b6c47caea..27664c503a1069b04ee6524a1927226f6d5c1210 100644
--- a/ring-android/libringclient/src/main/java/cx/ring/services/AccountService.java
+++ b/ring-android/libringclient/src/main/java/cx/ring/services/AccountService.java
@@ -34,9 +34,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
-import java.util.Timer;
-import java.util.TimerTask;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -114,7 +114,6 @@ public class AccountService {
 
     private final HashMap<Long, DataTransfer> mDataTransfers = new HashMap<>();
     private DataTransfer mStartingTransfer = null;
-    private Timer mTransferRefreshTimer = null;
 
     private final BehaviorSubject<List<Account>> accountsSubject = BehaviorSubject.create();
     private final Subject<Account> accountSubject = PublishSubject.create();
@@ -1518,8 +1517,9 @@ public class AccountService {
         mExecutor.execute(() -> Ringservice.cancelDataTransfer(dataTransferId));
     }
 
-    private class DataTransferRefreshTask extends TimerTask {
+    private class DataTransferRefreshTask implements Runnable {
         private final DataTransfer mToUpdate;
+        public ScheduledFuture<?> scheduledTask;
 
         DataTransferRefreshTask(DataTransfer t) {
             mToUpdate = t;
@@ -1527,13 +1527,12 @@ public class AccountService {
 
         @Override
         public void run() {
-            Interaction.InteractionStatus transferStatus;
             synchronized (mToUpdate) {
-                transferStatus = mToUpdate.getStatus();
-                if (transferStatus == Interaction.InteractionStatus.TRANSFER_ONGOING) {
+                if (mToUpdate.getStatus() == Interaction.InteractionStatus.TRANSFER_ONGOING) {
                     dataTransferEvent(mToUpdate.getDaemonId(), 5);
                 } else {
-                    cancel();
+                    scheduledTask.cancel(false);
+                    scheduledTask = null;
                 }
             }
         }
@@ -1568,12 +1567,10 @@ public class AccountService {
             InteractionStatus oldState = transfer.getStatus();
             if (oldState != transferStatus) {
                 if (transferStatus == Interaction.InteractionStatus.TRANSFER_ONGOING) {
-                    if (mTransferRefreshTimer == null)
-                        mTransferRefreshTimer = new Timer();
-                    mTransferRefreshTimer.scheduleAtFixedRate(
-                            new DataTransferRefreshTask(transfer),
+                    DataTransferRefreshTask task = new DataTransferRefreshTask(transfer);
+                    task.scheduledTask = mExecutor.scheduleAtFixedRate(task,
                             DATA_TRANSFER_REFRESH_PERIOD,
-                            DATA_TRANSFER_REFRESH_PERIOD);
+                            DATA_TRANSFER_REFRESH_PERIOD, TimeUnit.MILLISECONDS);
                 } else if (transferStatus.isError()) {
                     if (!transfer.isOutgoing()) {
                         File tmpPath = mDeviceRuntimeService.getTemporaryPath(transfer.getPeerId(), transfer.getStoragePath());