2014-02-06 34 views
3

使用KitKat中提供的SAF,MediaScanner不会调用保存到设备内部或外部存储点的文件。因此,我必须根据返回的URI确定是否应该尝试运行MediaScanner。存储访问框架不更新MediaScanner(MTP)

// The SAF uses content URI to pass meta about the file. The following host is used for internal storage. 
if (mExportServiceUri.getHost().equals("com.android.externalstorage.documents")) { 
    final File externalStorage = Environment.getExternalStorageDirectory(); 
    final String path = mExportServiceUri.getEncodedPath().replace("/document/primary%3A", ""); 
    MediaScannerConnection.scanFile(mService.getApplicationContext(), new String[] { new File(
      externalStorage, path).getAbsolutePath() }, null, null); 
} 

有没有其他人必须解决这个问题,如果是的话,有没有比这更好的方法?目前这仅支持设备外部存储,并且额外的存储空间(如SD卡)需要在单独的支票中处理。

+0

我相信这可以解决我的问题,但我担心它可能无法在所有设备上继续使用,甚至无法正常工作。我仍然乐于接受更好的MediaScanner处理建议。 –

回答

0

为了支持我认为所有可能的安装方式,包括通过OTG连接的USB拇指驱动器,甚至可能直接连接到某些平板电脑上的全尺寸USB端口(我没有平板电脑来测试它,存在一个全尺寸的端口?)我有以下似乎在Galaxy S4(Play商店版)和N5上运行良好。

// The SAF uses content URI to pass meta about the file. The following host is used for SD storage. 
if (mExportServiceUri.getHost().equals("com.android.externalstorage.documents")) { 
    final String encodedPath = mExportServiceUri.getEncodedPath(); 
    final String path = encodedPath.substring(encodedPath.indexOf("%3A") + 3); 
    final File[] storagePoints = new File("/storage").listFiles(); 

    // document/primary is in /storage/emulated/legacy and thus will fail the exists check in the else handling loop check 
    if (encodedPath.startsWith("/document/primary")) { 
     // External file stored in Environment path 
     final File externalFile = new File(Environment.getExternalStorageDirectory(), path); 
     MediaScannerConnection.scanFile(mService.getApplicationContext(), 
       new String[] { externalFile.getAbsolutePath() }, null, null); 
    } else { 
     // External file stored in one of the mount points, check each mount point for the file 
     for (int i = 0, j = storagePoints.length; i < j; ++i) { 
      final File externalFile = new File(storagePoints[i], path); 
      if (externalFile.exists()) { 
       MediaScannerConnection.scanFile(mService.getApplicationContext(), 
         new String[] { externalFile.getAbsolutePath() }, null, null); 
       break; 
      } 
     } 
    } 
} 
+0

我试图使用SAF为Nexus 5和其他无法以其他方式安装USB的手机添加海量USB存储支持。但是,我很难弄清楚SAF如何适用,以及这些代码片段如何适合SAF。看起来我们应该扩展DocumentsProvider,然后将挂载点添加到queryRoots()。但是,如果我们可以通过上述方法找到根,那么如果我的目标是在我的应用程序中打开一个文件,而不是将其提供给其他应用程序,那么SAF会添加什么值? –

+0

SAF适用于手机上的世界可读文件,无需知道它们的位置,也无需使用其他应用程序或云存储中无法访问的文件。如果您希望处理应用程序内部的文件,而您不希望其他应用程序使用该文件,则SAF不是您要查找的内容。一个内部浏览器将是明智的,因为您可能显示内部文件的方式对于您的应用程序来说比通用文件浏览器可以做到的更有意义。 –