Search code examples
androidfileandroid-10.0android-contentresolver

Can't create file with deleted file name at android 10


I want to keep a log text file for each day in the download folder. I want to store day based text files in my own Log folder(MyApp Log folder) in the Download folder.

When I delete the My App Log folder, I can't create this folder in the same location with the same name. Likewise, when the text file I created is deleted, I can't create a file with the same text file name. resolver.insert(downloadUri, contentValues); always returns null.

Even though I get a null result when I query whether there is a file belonging to that path, I can't create the same file.

The function where I created the file:

public static void createFile(){
    
        String contentType = "text/log";
        Date cDate = new Date(System.currentTimeMillis());
        String today = new SimpleDateFormat("yyyy_MM_dd").format(cDate);
        long seconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
       
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    
        ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, today + ".txt");//2021_10_13.txt
        contentValues.put(MediaStore.MediaColumns.MIME_TYPE, contentType);//text/log
        contentValues.put(MediaStore.MediaColumns.DATE_ADDED, seconds);//System.currentTimeMillis
        contentValues.put(MediaStore.MediaColumns.DATE_MODIFIED, seconds);//System.currentTimeMillis
        contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1);
        contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + File.separator + "MyApp Log");//Download/MyApp Log
    
        ContentResolver resolver = getContext().getContentResolver();
    
        outputUri = resolver.insert(getDownloadUri(), contentValues);
    
        if (outputUri == null)
            throw new IOException("Failed to create new MediaStore record.");
    
        try (final OutputStream stream = resolver.openOutputStream(outputUri)) {
            if (stream == null)
                return;

        } finally {
            ContentValues updateValues = new ContentValues();
            updateValues.put(MediaStore.MediaColumns.IS_PENDING, 0);
            resolver.update(outputUri, updateValues, null, null);
        }
    }

    public static @NonNull
        Uri getDownloadUri() {
            if (Build.VERSION.SDK_INT < 29) {
                return getLegacyUri(Environment.DIRECTORY_DOWNLOADS);
            } else {
                return MediaStore.Downloads.EXTERNAL_CONTENT_URI;
            }
        }

The function I am querying if the file exists:

    public static Uri getExternalContentUriFromFile(Uri externalUri, String filePath) {
        if (externalUri == null)
            return null;

        try (Cursor cursor = getContentResolver().query(externalUri, new String[]{MediaStore.MediaColumns._ID},
                MediaStore.MediaColumns.DATA + "=? ", new String[]{filePath}, null)) {

            if (cursor != null && cursor.moveToFirst()) {
                int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
                return Uri.withAppendedPath(externalUri, "" + id);
            }
            return null;
        }
    }

Solution

  • I found a solution myself:

            int fileNo = 0;
            Uri uri = saveToUri(fileName, contentType, seconds, relativePath);
            if (uri == null) {
                while (fileNo < 4 && uri == null) {
                    fileNo++;
                    fileName = AttachmentUtil.removeExtensionForName(fileName) + "(" + fileNo + ")" + extension;
                    uri = saveToUri(fileName, contentType, seconds, storageName + File.separator + myDirName, storageUri);
                }
            }
    

    @Will V :

     public static String removeExtensionForName(String fileName) {
            int i = fileName.lastIndexOf('.');
            if (i > 0) {
                return fileName.substring(0, i);
            }
            return fileName;
        }
    

    And I got my code in above question into saveToUri function.