diff --git a/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java b/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java index 3210ac35b..91274a962 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java @@ -9,6 +9,7 @@ import android.os.Build; import android.os.Bundle; import androidx.documentfile.provider.DocumentFile; +import android.os.Environment; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; @@ -537,6 +538,10 @@ private void checkWriteAndUpdateUI() { * Access level readwrite: folder can be configured "sendonly" or "sendreceive". */ mCanWriteToPath = Util.nativeBinaryCanWriteToPath(FolderActivity.this, mFolder.path); + if (!mCanWriteToPath){ + final File externalStorageDirectory = Environment.getExternalStorageDirectory(); + mCanWriteToPath = Util.nativeBinaryCanWriteToPath2(externalStorageDirectory, mFolder.path); + } if (mCanWriteToPath) { binding.accessExplanationView.setText(R.string.folder_path_readwrite); binding.folderType.setEnabled(true); diff --git a/app/src/main/java/com/nutomic/syncthingandroid/util/Util.java b/app/src/main/java/com/nutomic/syncthingandroid/util/Util.java index 1b8c32dc6..56c83b847 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/util/Util.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/util/Util.java @@ -7,7 +7,6 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Build; import android.preference.PreferenceManager; import androidx.appcompat.app.AlertDialog; import android.util.Log; @@ -172,6 +171,38 @@ public static boolean nativeBinaryCanWriteToPath(Context context, String absolut return true; } + /** + * Returns if the syncthing binary would be able to write a file into + * the given folder given the configured access level. + * + * This uses the Android-native File API. + */ + public static Boolean nativeBinaryCanWriteToPath2(File externalStorageDir, String absoluteFolderPath) { + final String TOUCH_FILE_NAME = ".stwritetest"; + + // Normalize path replacing ~ with external storage directory. + // This is consistent with what $HOME is set to in SyncthingRunnable. + final String normalizedPath = absoluteFolderPath.replaceFirst("^~", externalStorageDir.getAbsolutePath()); + + // Write permission test file. + File touchFile = new File(normalizedPath, TOUCH_FILE_NAME); + final String touchFilePath = touchFile.getAbsolutePath(); + try { + Boolean fileCreated = touchFile.createNewFile(); + Log.d(TAG, String.format("%s createNewFile result %b", touchFilePath, fileCreated)); + Boolean fileDeleted = touchFile.delete(); + Log.d(TAG, String.format("%s delete result %b", touchFilePath, fileDeleted)); + } catch (IOException e) { + Log.e(TAG, String.format("Failed to write test file '%s'", touchFilePath), e); + return false; + } + + // Detected we have write permission. + Log.i(TAG, String.format("Successfully wrote test file '%s'", touchFile)); + + return true; + } + /** * Run command in a shell and return the exit code. */