刷新Media Scanner扫描的文本文件

时间:2015-12-09 07:29:06

标签: java android android-mediascanner

我的Android应用程序正在生成一些数据并将其写入文本文件。应用程序将新信息附加到此文件,然后生成新信息。

我需要不时从PC上重新下载此文件。但是,一旦我扫描文件,然后修改它,我就无法从PC上看到这种变化。

我尝试使用两者扫描/重新扫描文件 MediaScannerConnection.scanFile()sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(textFile)));

例如,如果我在将任何数据写入文件之前扫描文件,则PC会正确地看到它,大小为零。但是当我在文件中添加文本并重新扫描它时,PC一直看到文件大小为零,我只能下载一个空文件。

如何重新扫描/刷新此特定文件而不删除并重新创建它?

2 个答案:

答案 0 :(得分:0)

修改文件后尝试通知数据:

private static void notifyData(Context context, URI fileUri) throws URISyntaxException {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File f = new File(fileUri);
        Uri contentUri = Uri.fromFile(f);
        mediaScanIntent.setData(contentUri);
        context.sendBroadcast(mediaScanIntent);
    }
祝你好运。

答案 1 :(得分:0)

过去一个月我一直在同一个问题上狂奔-终于有了解决该问题的肮脏解决方法。虽然不漂亮,但到目前为止唯一有效的方法。我是java newb,所以希望有更好的方法允许并发调用阻止并等待。随时建议...

工作原理:

  • 创建一个调用MediaScannerConnection.scanFile()的函数,该函数将阻塞直到完成。

  • 将原始文件重命名为file.tmp

  • 在原始文件的Uri上调用getContentResolver()。delete()。这样可以安排删除媒体数据的时间,但不等待媒体扫描仪执行删除操作。文件的内容不会因为我们移动而丢失。

  • 调用我们的scanFile()函数以阻止,直到至少执行了删除操作为止(介质扫描仪会按顺序处理请求)。

  • 将临时文件重命名为原始名称

  • 调用scanFile()将正确的数据导入媒体数据库。

等待扫描和删除操作完成至关重要,否则,媒体扫描仪(最终运行时)将不会意识到文件已更改,因此也不会更新。

    static boolean mediaScanFile_inMediaScanFile = false; // multi-thread re-entrancy lock.
    static boolean mediaScanFile_completed = false;

    private static void mediaScanFile (Context context, String filepath)
    {
        while (mediaScanFile_inMediaScanFile) // wait till any active thread has exited.
        {
            try
            {
                Thread.sleep (50);
            } catch (InterruptedException ex)
            {
                // so it broke out early. Don't care.
                //Log.d(TAG, "Early exit from mediaScanFile_inMediaScanFile loop");
            }
        }
        mediaScanFile_inMediaScanFile = true; // grab exclusive lock.
        mediaScanFile_completed = false;
        //Log.i("updateFileInMediaLibrary", "Scanning " + filepath);

        // get the Media Scanner to re-add the file so that it's details are up-to-date.
        MediaScannerConnection.scanFile(
            context,
            new String[] {filepath},
            new String[] {"*/*"},
            new MediaScannerConnection.OnScanCompletedListener()
            {
                public void onScanCompleted(String path, Uri uri)
                {
                    //Log.i("updateFileInMediaLibrary", "Scanned " + path);
                    //Log.i("updateFileInMediaLibrary", "-> uri=" + uri);
                    mediaScanFile_completed = true;
                }
            });

        while (!mediaScanFile_completed)
        {
            try
            {
                Thread.sleep (50);
            } catch (InterruptedException ex)
            {
                // so it broke out early. Don't care.
                //Log.d(TAG, "Early exit from mediaScanFile_completed loop");
            }
        }
        //Log.i("updateFileInMediaLibrary", "Completed " + filepath);
        mediaScanFile_inMediaScanFile = false;
    }


    // Function to tell the USB Media Server about new or changed files, so that browsing the filesystem
    // from an external computer will see changes to files.
    public void updateFileInMediaLibrary(String filepath)
    {
        // Add or update the MediaLibrary entry for the file.
        File file = new File(filepath);
        Uri origUri = FileProvider.getUriForFile(this, "com.yourapp.fileprovider", file);
        Cursor cursor = getContentResolver().query(origUri,null,null,null,null);
        if (cursor.moveToFirst()) // an entry exists, that needs updating.
        {
            if (!file.exists())
            {
                getContentResolver().delete(origUri,null,null);
                mediaScanFile (this, filepath); // make sure the process has run, by waiting for a subsequent run to complete.
                return;
            }

            long new_size = file.length();
            //Log.i("updateFileInMediaLibrary", "new_size = "+new_size+" bytes");

            String tempFilePath = filepath+".tmp";

            File tempFile = new File(tempFilePath);

            //Log.i("updateFileInMediaLibrary","renaming original to temp: "+tempFilePath);
            file.renameTo(tempFile);
            // No need to call mediaScanFile() on tempFilePath as we don't care about seeing it. It will be gone again shortly.

            // delete original file entry.
            //Log.i("updateFileInMediaLibrary. Deleting original file entry: ", origUri+"");
            getContentResolver().delete(origUri,null,null);
            mediaScanFile (this, filepath); // make sure the process has run, by waiting for a subsequent run to complete.

            File original = new File(filepath);
            // move temp back to original name
            //Log.i("updateFileInMediaLibrary","Renaming temp back to original: "+filepath);
            tempFile.renameTo(original);
            mediaScanFile (this, filepath); // Finally get the correct details into the MTP database.

            //Log.i("updateFileInMediaLibrary", "Updated");
            return;
        }
        else // media scanner entry doesn't exist
        {
            if (file.exists())
            {
                mediaScanFile (this, filepath); // make sure the process has run, by waiting for a subsequent run to complete.
            }
            // else nothing to do so don't waste time trying.
        }
    }

希望这对某人有帮助:-)