use of androidx.documentfile.provider.DocumentFile in project syncthing-android by syncthing.
the class FolderActivity method onOptionsItemSelected.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.create:
if (TextUtils.isEmpty(mFolder.id)) {
Toast.makeText(this, R.string.folder_id_required, Toast.LENGTH_LONG).show();
return true;
}
if (TextUtils.isEmpty(mFolder.path)) {
Toast.makeText(this, R.string.folder_path_required, Toast.LENGTH_LONG).show();
return true;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mFolderUri != null) {
/**
* Normally, syncthing takes care of creating the ".stfolder" marker.
* This fails on newer android versions if the syncthing binary only has
* readonly access on the path and the user tries to configure a
* sendonly folder. To fix this, we'll precreate the marker using java code.
* We also create an empty file in the marker directory, to hopefully keep
* it alive in the face of overzealous disk cleaner apps.
*/
DocumentFile dfFolder = DocumentFile.fromTreeUri(this, mFolderUri);
if (dfFolder != null) {
Log.v(TAG, "Creating new directory " + mFolder.path + File.separator + FOLDER_MARKER_NAME);
DocumentFile marker = dfFolder.createDirectory(FOLDER_MARKER_NAME);
marker.createFile("text/plain", "empty");
}
}
getApi().createFolder(mFolder);
finish();
return true;
case R.id.remove:
showDeleteDialog();
return true;
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
use of androidx.documentfile.provider.DocumentFile in project kdeconnect-android by KDE.
the class CompositeReceiveFileJob method getDocumentFileFor.
private DocumentFile getDocumentFileFor(final String filename, final boolean open) throws RuntimeException {
final DocumentFile destinationFolderDocument;
String filenameToUse = filename;
// If the file should be opened immediately store it in the standard location to avoid the FileProvider trouble (See ReceiveNotification::setURI)
if (open || !ShareSettingsFragment.isCustomDestinationEnabled(getDevice().getContext())) {
final String defaultPath = ShareSettingsFragment.getDefaultDestinationDirectory().getAbsolutePath();
filenameToUse = FilesHelper.findNonExistingNameForNewFile(defaultPath, filenameToUse);
destinationFolderDocument = DocumentFile.fromFile(new File(defaultPath));
} else {
destinationFolderDocument = ShareSettingsFragment.getDestinationDirectory(getDevice().getContext());
}
String displayName = FilenameUtils.getBaseName(filenameToUse);
String mimeType = FilesHelper.getMimeTypeFromFile(filenameToUse);
if ("*/*".equals(mimeType)) {
displayName = filenameToUse;
}
DocumentFile fileDocument = destinationFolderDocument.createFile(mimeType, displayName);
if (fileDocument == null) {
throw new RuntimeException(getDevice().getContext().getString(R.string.cannot_create_file, filenameToUse));
}
return fileDocument;
}
use of androidx.documentfile.provider.DocumentFile in project kdeconnect-android by KDE.
the class CompositeReceiveFileJob method run.
@Override
public void run() {
boolean done;
OutputStream outputStream = null;
synchronized (lock) {
done = networkPacketList.isEmpty();
}
try {
DocumentFile fileDocument = null;
isRunning = true;
while (!done && !canceled) {
synchronized (lock) {
currentNetworkPacket = networkPacketList.get(0);
}
currentFileName = currentNetworkPacket.getString("filename", Long.toString(System.currentTimeMillis()));
currentFileNum++;
setProgress((int) prevProgressPercentage);
fileDocument = getDocumentFileFor(currentFileName, currentNetworkPacket.getBoolean("open", false));
if (currentNetworkPacket.hasPayload()) {
outputStream = new BufferedOutputStream(getDevice().getContext().getContentResolver().openOutputStream(fileDocument.getUri()));
InputStream inputStream = currentNetworkPacket.getPayload().getInputStream();
long received = receiveFile(inputStream, outputStream);
currentNetworkPacket.getPayload().close();
if (received != currentNetworkPacket.getPayloadSize()) {
fileDocument.delete();
if (!canceled) {
throw new RuntimeException("Failed to receive: " + currentFileName + " received:" + received + " bytes, expected: " + currentNetworkPacket.getPayloadSize() + " bytes");
}
} else {
publishFile(fileDocument, received);
}
} else {
// TODO: Only set progress to 100 if this is the only file/packet to send
setProgress(100);
publishFile(fileDocument, 0);
}
boolean listIsEmpty;
synchronized (lock) {
networkPacketList.remove(0);
listIsEmpty = networkPacketList.isEmpty();
}
if (listIsEmpty && !canceled) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
synchronized (lock) {
if (currentFileNum < totalNumFiles && networkPacketList.isEmpty()) {
throw new RuntimeException("Failed to receive " + (totalNumFiles - currentFileNum + 1) + " files");
}
}
}
synchronized (lock) {
done = networkPacketList.isEmpty();
}
}
isRunning = false;
if (canceled) {
receiveNotification.cancel();
return;
}
int numFiles;
synchronized (lock) {
numFiles = totalNumFiles;
}
if (numFiles == 1 && currentNetworkPacket.getBoolean("open", false)) {
receiveNotification.cancel();
openFile(fileDocument);
} else {
// Update the notification and allow to open the file from it
receiveNotification.setFinished(getDevice().getContext().getResources().getQuantityString(R.plurals.received_files_title, numFiles, getDevice().getName(), numFiles));
if (totalNumFiles == 1 && fileDocument != null) {
receiveNotification.setURI(fileDocument.getUri(), fileDocument.getType(), fileDocument.getName());
}
receiveNotification.show();
}
reportResult(null);
} catch (ActivityNotFoundException e) {
receiveNotification.setFinished(getDevice().getContext().getString(R.string.no_app_for_opening));
receiveNotification.show();
} catch (Exception e) {
isRunning = false;
Log.e("Shareplugin", "Error receiving file", e);
int failedFiles;
synchronized (lock) {
failedFiles = (totalNumFiles - currentFileNum + 1);
}
receiveNotification.setFinished(getDevice().getContext().getResources().getQuantityString(R.plurals.received_files_fail_title, failedFiles, getDevice().getName(), failedFiles, totalNumFiles));
receiveNotification.show();
reportError(e);
} finally {
closeAllInputStreams();
networkPacketList.clear();
try {
IOUtils.close(outputStream);
} catch (IOException ignored) {
}
}
}
use of androidx.documentfile.provider.DocumentFile in project Signal-Android by signalapp.
the class BackupUtil method getAllBackupsNewestFirstApi29.
@RequiresApi(29)
private static List<BackupInfo> getAllBackupsNewestFirstApi29() {
Uri backupDirectoryUri = SignalStore.settings().getSignalBackupDirectory();
if (backupDirectoryUri == null) {
Log.i(TAG, "Backup directory is not set. Returning an empty list.");
return Collections.emptyList();
}
DocumentFile backupDirectory = DocumentFile.fromTreeUri(ApplicationDependencies.getApplication(), backupDirectoryUri);
if (backupDirectory == null || !backupDirectory.exists() || !backupDirectory.canRead()) {
Log.w(TAG, "Backup directory is inaccessible. Returning an empty list.");
return Collections.emptyList();
}
DocumentFile[] files = backupDirectory.listFiles();
List<BackupInfo> backups = new ArrayList<>(files.length);
for (DocumentFile file : files) {
if (file.isFile() && file.getName() != null && file.getName().endsWith(".backup")) {
long backupTimestamp = getBackupTimestamp(file.getName());
if (backupTimestamp != -1) {
backups.add(new BackupInfo(backupTimestamp, file.length(), file.getUri()));
}
}
}
Collections.sort(backups, (a, b) -> Long.compare(b.timestamp, a.timestamp));
return backups;
}
use of androidx.documentfile.provider.DocumentFile in project Signal-Android by signalapp.
the class BackupUtil method canUserAccessBackupDirectory.
public static boolean canUserAccessBackupDirectory(@NonNull Context context) {
if (isUserSelectionRequired(context)) {
Uri backupDirectoryUri = SignalStore.settings().getSignalBackupDirectory();
if (backupDirectoryUri == null) {
return false;
}
DocumentFile backupDirectory = DocumentFile.fromTreeUri(context, backupDirectoryUri);
return backupDirectory != null && backupDirectory.exists() && backupDirectory.canRead() && backupDirectory.canWrite();
} else {
return Permissions.hasAll(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
}
Aggregations