diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/local_file_transfer/FileListAdapter.java b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/local_file_transfer/FileListAdapter.java index f96c752e3..9c6fd6938 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/local_file_transfer/FileListAdapter.java +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/local_file_transfer/FileListAdapter.java @@ -47,8 +47,8 @@ public class FileListAdapter extends RecyclerView.Adapter fileUriArrayList; // For sender device, stores uris of the files - public @NonNull Boolean isFileSender = false;// Whether the device is the file sender or not + private ArrayList fileUriArrayList;// For sender device, stores uris of the files + public boolean isFileSender = false; // Whether the device is the file sender or not public @NonNull WifiDirectManager wifiDirectManager = new WifiDirectManager(this); @@ -104,7 +104,7 @@ public class LocalFileTransferActivity extends AppCompatActivity implements private boolean fileTransferStarted = false; private PeerGroupHandshakeAsyncTask peerGroupHandshakeAsyncTask; - private SenderDeviceAsyncTask[] senderDeviceAsyncTaskArray; + private SenderDeviceAsyncTask senderDeviceAsyncTaskArray; private ReceiverDeviceAsyncTask receiverDeviceAsyncTask; @Override @@ -295,11 +295,8 @@ public class LocalFileTransferActivity extends AppCompatActivity implements showToast(this, R.string.preparing_files, Toast.LENGTH_LONG); for (int i = 0; i < 20000000; i++) ; - senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask[totalFilesForTransfer]; - for (int i = 0; i < totalFilesForTransfer; i++) { - senderDeviceAsyncTaskArray[i] = new SenderDeviceAsyncTask(this, i); - senderDeviceAsyncTaskArray[i].execute(fileUriArrayList.get(i)); - } + senderDeviceAsyncTaskArray = new SenderDeviceAsyncTask(this); + senderDeviceAsyncTaskArray.execute(fileUriArrayList.toArray(new Uri[0])); } } } @@ -559,9 +556,8 @@ public class LocalFileTransferActivity extends AppCompatActivity implements } if (senderDeviceAsyncTaskArray != null) { - for (SenderDeviceAsyncTask task : senderDeviceAsyncTaskArray) { - task.cancel(true); - } + senderDeviceAsyncTaskArray.cancel(true); + } else if (receiverDeviceAsyncTask != null) { receiverDeviceAsyncTask.cancel(true); } diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/local_file_transfer/SenderDeviceAsyncTask.java b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/local_file_transfer/SenderDeviceAsyncTask.java index 5ac11bf04..69c4f1685 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/local_file_transfer/SenderDeviceAsyncTask.java +++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/local_file_transfer/SenderDeviceAsyncTask.java @@ -28,59 +28,74 @@ import static org.kiwix.kiwixmobile.zim_manager.local_file_transfer.LocalFileTra * Once the handshake between the two connected devices has taked place, this async-task is used * on the sender device to transfer the file to the receiver device at the FILE_TRANSFER_PORT port. * - * It takes in the uri of a single file, and copies all the bytes from input stream of the file to - * the output stream of the receiver device. Also changes the status of the corresponding FileItem - * on the list of files for transfer. + * It takes in the uri of all the files to be shared. For each file uri, creates a new connection & + * copies all the bytes from input stream of the file to the output stream of the receiver device. + * Also changes the status of the corresponding FileItem on the list of files for transfer. * - * A new task is created by the sender for every file to be transferred + * A single task is used by the sender for the entire transfer */ -class SenderDeviceAsyncTask extends AsyncTask { +class SenderDeviceAsyncTask extends AsyncTask { private static final String TAG = "SenderDeviceAsyncTask"; private WeakReference weakReferenceToActivity; - private int fileItemIndex; + private int fileItemIndex = -1; - public SenderDeviceAsyncTask(LocalFileTransferActivity localFileTransferActivity, int fileItemIndex) { + public SenderDeviceAsyncTask(LocalFileTransferActivity localFileTransferActivity) { this.weakReferenceToActivity = new WeakReference<>(localFileTransferActivity); - this.fileItemIndex = fileItemIndex; - } - - @Override - protected void onPreExecute() { - final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get(); - localFileTransferActivity.changeStatus(fileItemIndex, SENDING); } @Override protected Boolean doInBackground(Uri... fileUris) { - Uri fileUri = fileUris[0]; // Uri of file to be transferred final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get(); ContentResolver contentResolver = localFileTransferActivity.getContentResolver(); - try (Socket socket = new Socket(); // Represents the sender device - InputStream fileInputStream = contentResolver.openInputStream(fileUri)) { + Boolean result = true; + + for(Uri fileUri : fileUris) { // Uri of file to be transferred + fileItemIndex++; + + try (Socket socket = new Socket(); // Represents the sender device + InputStream fileInputStream = contentResolver.openInputStream(fileUri)) { + + if (isCancelled()) { + result = false; + return result; + } + socket.bind(null); + + String hostAddress = localFileTransferActivity.getFileReceiverDeviceAddress().getHostAddress(); + socket.connect((new InetSocketAddress(hostAddress, FILE_TRANSFER_PORT)), 15000); + + if (BuildConfig.DEBUG) Log.d(TAG, "Sender socket - " + socket.isConnected()); + publishProgress(fileItemIndex, SENDING); + + OutputStream socketOutputStream = socket.getOutputStream(); + + copyToOutputStream(fileInputStream, socketOutputStream); + if (BuildConfig.DEBUG) Log.d(TAG, "Sender: Data written"); + + publishProgress(fileItemIndex, SENT); + + } catch (IOException e) { + Log.e(TAG, e.getMessage()); + result = false; + showToast(localFileTransferActivity, localFileTransferActivity.getString(R.string.error_sending, getFileName(localFileTransferActivity.getFileUriArrayList().get(fileItemIndex))), Toast.LENGTH_SHORT); + publishProgress(fileItemIndex, ERROR); - if (isCancelled()) { - return false; } - socket.bind(null); - - String hostAddress = localFileTransferActivity.getFileReceiverDeviceAddress().getHostAddress(); - socket.connect((new InetSocketAddress(hostAddress, FILE_TRANSFER_PORT)), 15000); - - if (BuildConfig.DEBUG) Log.d(TAG, "Sender socket - " + socket.isConnected()); - - OutputStream socketOutputStream = socket.getOutputStream(); - - copyToOutputStream(fileInputStream, socketOutputStream); - if (BuildConfig.DEBUG) Log.d(TAG, "Sender: Data written"); - - return true; - } catch (IOException e) { - Log.e(TAG, e.getMessage()); - return false; + localFileTransferActivity.incrementTotalFilesSent(); } + + return result; + } + + @Override + protected void onProgressUpdate(Integer... values) { + int fileIndex = values[0]; + int fileStatus = values[1]; + final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get(); + localFileTransferActivity.changeStatus(fileIndex, fileStatus); } @Override protected void onCancelled() { @@ -90,15 +105,6 @@ class SenderDeviceAsyncTask extends AsyncTask { @Override protected void onPostExecute(Boolean fileSendSuccessful) { final LocalFileTransferActivity localFileTransferActivity = weakReferenceToActivity.get(); - localFileTransferActivity.incrementTotalFilesSent(); - - if (fileSendSuccessful) { // Whether this task was successful in sending the file - localFileTransferActivity.changeStatus(fileItemIndex, SENT); - } else { - showToast(localFileTransferActivity, localFileTransferActivity.getString(R.string.error_sending, - getFileName(localFileTransferActivity.getFileUriArrayList().get(fileItemIndex))), Toast.LENGTH_SHORT); - localFileTransferActivity.changeStatus(fileItemIndex, ERROR); - } if (localFileTransferActivity.allFilesSent()) { showToast(localFileTransferActivity, R.string.file_transfer_complete,