+ // Initialize the cipher.
+ cipher.init(Cipher.ENCRYPT_MODE, secretKey, gcmParameterSpec);
+
+ // Get the file name string.
+ String passwordEncryptionFileNameString = fileNameEditText.getText().toString();
+
+ // Get the export file output stream.
+ OutputStream exportFileOutputStream = getContentResolver().openOutputStream(Uri.parse(passwordEncryptionFileNameString));
+
+ // Add the salt and the initialization vector to the export file output stream.
+ exportFileOutputStream.write(saltByteArray);
+ exportFileOutputStream.write(initializationVector);
+
+ // Create a cipher output stream.
+ CipherOutputStream cipherOutputStream = new CipherOutputStream(exportFileOutputStream, cipher);
+
+ // Initialize variables to store data as it is moved from the unencrypted export file input stream to the cipher output stream. Move 128 bits (16 bytes) at a time.
+ int numberOfBytesRead;
+ byte[] encryptedBytes = new byte[16];
+
+ // Read up to 128 bits (16 bytes) of data from the unencrypted export file stream. `-1` will be returned when the end of the file is reached.
+ while ((numberOfBytesRead = unencryptedExportFileInputStream.read(encryptedBytes)) != -1) {
+ // Write the data to the cipher output stream.
+ cipherOutputStream.write(encryptedBytes, 0, numberOfBytesRead);
+ }
+
+ // Close the streams.
+ cipherOutputStream.flush();
+ cipherOutputStream.close();
+ exportFileOutputStream.close();
+ unencryptedExportFileInputStream.close();
+
+ // Wipe the encryption data from memory.
+ //noinspection UnusedAssignment
+ encryptionPasswordString = "";
+ Arrays.fill(saltByteArray, (byte) 0);
+ Arrays.fill(encryptionPasswordByteArray, (byte) 0);
+ Arrays.fill(encryptionPasswordWithSaltByteArray, (byte) 0);
+ Arrays.fill(hashedEncryptionPasswordWithSaltByteArray, (byte) 0);
+ Arrays.fill(truncatedHashedEncryptionPasswordWithSaltByteArray, (byte) 0);
+ Arrays.fill(initializationVector, (byte) 0);
+ Arrays.fill(encryptedBytes, (byte) 0);
+
+ // Delete the temporary unencrypted export file.
+ //noinspection ResultOfMethodCallIgnored
+ temporaryUnencryptedExportFile.delete();
+
+ // Display an export disposition snackbar.
+ if (passwordEncryptionExportStatus.equals(ImportExportDatabaseHelper.EXPORT_SUCCESSFUL)) {
+ Snackbar.make(fileNameEditText, getString(R.string.export_successful), Snackbar.LENGTH_SHORT).show();
+ } else {
+ Snackbar.make(fileNameEditText, getString(R.string.export_failed) + " " + passwordEncryptionExportStatus, Snackbar.LENGTH_INDEFINITE).show();
+ }
+ } catch (Exception exception) {
+ // Display a snackbar with the exception.
+ Snackbar.make(fileNameEditText, getString(R.string.export_failed) + " " + exception, Snackbar.LENGTH_INDEFINITE).show();