Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package org.opendatakit.utilities;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.rule.GrantPermissionRule;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opendatakit.services.utilities.FileSystemHelper;

@RunWith(AndroidJUnit4.class)
public class ODKFileUtilsTest {

private static final String ODK_FOLDER_NAME = "opendatakit";
private FileSystemHelper fileSystemHelper;
private Context context;

@Rule
public GrantPermissionRule permissionRule = GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);

@Before
public void setUp() {
context = ApplicationProvider.getApplicationContext();
fileSystemHelper = new FileSystemHelper(context);
}

@Test
public void testCreateDirectory() {
String folderName = "testFolder";
String relativePath = Environment.DIRECTORY_DOCUMENTS + "/" + ODK_FOLDER_NAME + "/" + folderName;

Uri directoryUri = fileSystemHelper.getFolderUri(relativePath);
if (directoryUri == null) {
directoryUri = fileSystemHelper.createDirectory(relativePath);
}
assertNotNull("Directory URI should not be null after creation", directoryUri);

Uri externalUri = MediaStore.Files.getContentUri("external");
String[] projection = {MediaStore.Files.FileColumns.RELATIVE_PATH};
String selection = MediaStore.Files.FileColumns.RELATIVE_PATH + "=?";
String[] selectionArgs = {relativePath + "/"};
try (Cursor cursor = context.getContentResolver().query(externalUri, projection, selection, selectionArgs, null)) {
boolean directoryExists = cursor != null && cursor.getCount() > 0;
assertTrue("Directory should exist after creation", directoryExists);
}
}

@Test
public void testGetOdkFolderUri() {
Uri resultUri = fileSystemHelper.getOdkFolder();
assertNotNull(resultUri);
String[] projection = {MediaStore.MediaColumns.RELATIVE_PATH};
String selection = MediaStore.MediaColumns.RELATIVE_PATH + "=?";
String[] selectionArgs = {Environment.DIRECTORY_DOCUMENTS + "/" + ODK_FOLDER_NAME + "/"};

Cursor cursor = context.getContentResolver().query(
MediaStore.Files.getContentUri("external"),
projection,
selection,
selectionArgs,
null
);
assertNotNull(cursor);
assertTrue(cursor.getCount() > 0);
cursor.close();
}


@Test
public void testAssertDirectoryStructure() {
String appName = ODK_FOLDER_NAME;

try {
fileSystemHelper.assertDirectoryStructure(appName);
} catch (Exception e) {
fail("Exception thrown while asserting directory structure: " + e.getMessage());
}

String[] folderNames = {"config", "data", "output", "system", "permanent"};
for (String folderName : folderNames) {
String relativePath = Environment.DIRECTORY_DOCUMENTS + "/" + appName + "/" + folderName;

Uri folderUri = fileSystemHelper.getFolderUri(relativePath);
assertNotNull("Folder " + folderName + " does not exist", folderUri);

// Uri nomediaUri = fileSystemHelper.getFileUri(relativePath, ".nomedia");
// assertNotNull(".nomedia file does not exist in folder " + folderName, nomediaUri);
}
}


}


Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package org.opendatakit.services.utilities;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class FileSystemHelper {
private static final String ODK_FOLDER_NAME = "opendatakit";
private final Context context;

public FileSystemHelper(Context context) {
this.context = context;
}

public Uri getOdkFolder() {
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS + "/" + ODK_FOLDER_NAME);
Uri folderUri = context.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);
return folderUri;
}

public void assertDirectoryStructure(String appName) {
String[] folderNames = {"config", "data", "output", "system", "permanent"};

// Create each directory and check for existence
for (String folderName : folderNames) {
String relativePath = Environment.DIRECTORY_DOCUMENTS + "/" + appName + "/" + folderName;
if (getFolderUri(relativePath) == null) {
createDirectory(relativePath);
}

// Ensure .nomedia file is created inside each folder
String nomediaFilePath = relativePath;
if (getFileUri(nomediaFilePath, ".nomedia") == null) {
createNomediaFile(nomediaFilePath);
}
}
}

// Helper method to create a .nomedia file inside a specific directory
private void createNomediaFile(String relativePath) {
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, ".nomedia");
values.put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath + "/");
values.put(MediaStore.MediaColumns.MIME_TYPE, "application/octet-stream"); // MIME type for generic binary data

context.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);
}

// Helper method to create a directory using MediaStore
public Uri createDirectory(String relativePath) {
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, relativePath.substring(relativePath.lastIndexOf("/") + 1)); // Directory name
values.put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath);
values.put(MediaStore.MediaColumns.MIME_TYPE, DocumentsContract.Document.MIME_TYPE_DIR); // MIME type for a directory

return context.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);
}

// Helper method to get the folder Uri using MediaStore
public Uri getFolderUri(String relativePath) {
String[] projection = {MediaStore.MediaColumns._ID};
String selection = MediaStore.MediaColumns.RELATIVE_PATH + "=?";
String[] selectionArgs = {relativePath + "/"};

try (Cursor cursor = context.getContentResolver().query(
MediaStore.Files.getContentUri("external"),
projection,
selection,
selectionArgs,
null
)) {
if (cursor != null && cursor.moveToFirst()) {
long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID));
return ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), id);
}
}
return null;
}

// Helper method to get the file Uri using MediaStore
public Uri getFileUri(String relativePath, String fileName) {
String[] projection = {MediaStore.MediaColumns._ID};
String selection = MediaStore.MediaColumns.RELATIVE_PATH + "=? AND " + MediaStore.MediaColumns.DISPLAY_NAME + "=?";
String[] selectionArgs = {relativePath + "/", fileName};

try (Cursor cursor = context.getContentResolver().query(
MediaStore.Files.getContentUri("external"),
projection,
selection,
selectionArgs,
null
)) {
if (cursor != null && cursor.moveToFirst()) {
long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID));
return ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), id);
}
}
return null;
}

}