如何从资产文件获取URI?


127

我一直在尝试获取资产文件的URI路径。

uri = Uri.fromFile(new File("//assets/mydemo.txt"));

当我检查文件是否存在时,我看到该文件不存在

File f = new File(filepath);
if (f.exists() == true) {
    Log.e(TAG, "Valid :" + filepath);
} else {
    Log.e(TAG, "InValid :" + filepath);
}

有人可以告诉我如何提及资产文件夹中现有文件的绝对路径吗?

Answers:


160

没有“资产文件夹中现有文件的绝对路径”。项目assets/文件夹的内容打包在APK文件中。使用AssetManager对象获取InputStream资产。

对于WebView,您可以使用与file Uri使用URL几乎相同的方式来使用该方案。资产的语法是file:///android_asset/...(请注意:三个斜杠),其中省略号是文件assets/夹中文件的路径。


32
file://android_asset/...,其中...是项目assets/目录中的相对路径。
CommonsWare

4
下面是一个使用示例项目file://android_asset/,虽然不是一个Urigithub.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
CommonsWare

20
@CommonsWare似乎您在URI中错过了“ /”。应该是file:///
ThomasW 2011年

7
我尝试将其作为new File("file:///android_asset/sounds/beep.mid");,但结果文件不存在。有任何想法吗?PS文件在assets/sounds/文件夹中。
林叔叔

3
是“ file:/// android_asset / ...”仅在WebView中起作用,并且无法在WebView之外使用URI / URL / Uri获取InputStream吗?
卢博

74

正确的网址是:

file:///android_asset/RELATIVEPATH

其中RELATIVEPATH是资源相对于资产文件夹的路径。

注意方案中的3 /。如果没有3,则Web视图将无法加载我的任何资产。我尝试了2(以前)由CommonsWare进行了评论,但它不起作用。然后,我在github上查看了CommonsWare的源代码,并注意到了额外的正斜杠。

虽然此测试仅在1.6 Android模拟器上进行,但我怀疑它在真实设备或更高版本上是否有所不同。

编辑:CommonsWare更新了他的答案以反映这一微小的变化。因此,我对其进行了编辑,因此对于他当前的回答仍然有意义。


不再工作了 String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Elgirhath

@Elgirhath的File接受字符串的构造函数期望路径不是URI。几年来我没有为Android编写代码,但情况可能已经改变。我不确定您是否可以使用普通的Java File类访问嵌入式资产文件夹。我似乎记得您必须使用AssetManager。资产文件夹中的文件以只读捆绑的APK放置在设备上并进行了压缩(APK实际上是zip文件),因此需要更多的工作来将其读回。尝试类似的方法new File(new URI(filename))
Russ

10

请尝试正常运行此代码

 Uri imageUri = Uri.fromFile(new File("//android_asset/luc.jpeg"));

    /* 2) Create a new Intent */
    Intent imageEditorIntent = new AdobeImageIntent.Builder(this)
            .setData(imageUri)
            .build();

8

最后,我找到一种方式来获得一个文件,该文件存在于资产的路径这个答案在科特林。在这里,我们将资产文件复制到缓存,并从该缓存文件获取文件路径。

@Throws(IOException::class)
    fun getFileFromAssets(context: Context, fileName: String): File = File(context.cacheDir, fileName)
            .also {
               if (!it.exists()) {
                it.outputStream().use { cache ->
                    context.assets.open(fileName).use { inputStream ->
                            inputStream.copyTo(cache)
                    }
                  }
                }
            }

获取文件的路径,例如:

val filePath =  getFileFromAssets(context, "fileName.extension").absolutePath

1
注意,如果fileName有目录dir/file。它将崩溃,路径cache/dir/file不存在。我也认为最好if(!it.exist)also块内进行检查,这样即使文件已经在缓存中,它也不会每次都复制文件
Yeung

@ ShylendraMadda,@ Yeung,if(!it.exist)引发了一个错误的未解决引用。有什么办法吗?
binrebin

检查该文件名是否存在于您的缓存中?@binrebin
Shylendra Madda,

@ShylendraMadda,我只知道文件名。我们可以用脚本加载它不知道实际的URI
binrebin

我觉得if(!it.exist)应该把前it.outputStream()...

7

在此处输入图片说明

确保将您的资产文件夹放置在正确的位置。


您可以将其放置在所需的位置,并在build.gradle文件中定义路径,如下所示sourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Marcel Bro,

2
如何获取hello.html的路径?请添加
Rohit Singh,


4

试试看,它的工作原理:

InputStream in_s = 
    getClass().getClassLoader().getResourceAsStream("TopBrands.xml");

如果您收到Null值异常,请尝试此操作(与类一起使用TopBrandData):

InputStream in_s1 =
    TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");

如果不起作用,请尝试以下操作:InputStream in_s1 = TopBrandData.class.getResourceAsStream(“ / assets / TopBrands.xml”);
Jaspreet Singh 2014年

3
InputStream is = getResources().getAssets().open("terms.txt");
String textfile = convertStreamToString(is);
    
public static String convertStreamToString(InputStream is)
        throws IOException {

    Writer writer = new StringWriter();
    char[] buffer = new char[2048];

    try {
        Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        int n;
        while ((n = reader.read(buffer)) != -1) {
            writer.write(buffer, 0, n);
        }
    } finally {
        is.close();
    }

    String text = writer.toString();
    return text;
}

1

试试这个 :

Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.cat); 

我做到了,它奏效了



1
工作了 非常感谢。大声笑,我只是想获取URI内部文件//在RES中创建RAW文件夹,然后仅将名称文件包含a..z0..9字符,不要大写!!!
phnghue

0

是的,您无法从android手机或仿真器访问驱动器文件夹,因为您的计算机和android是两个不同的操作系统。我会选择android的res文件夹,因为它具有良好的资源管理方法。直到且除非您有充分的理由将文件放入资产文件夹。相反,您可以这样做

try {
      Resources res = getResources();
      InputStream in_s = res.openRawResource(R.raw.yourfile);

      byte[] b = new byte[in_s.available()];
      in_s.read(b);
      String str = new String(b);
    } catch (Exception e) {
      Log.e(LOG_TAG, "File Reading Error", e);
 }

-7

为我工作尝试此代码

   uri = Uri.fromFile(new File("//assets/testdemo.txt"));
   String testfilepath = uri.getPath();
    File f = new File(testfilepath);
    if (f.exists() == true) {
    Toast.makeText(getApplicationContext(),"valid :" + testfilepath, 2000).show();
    } else {
   Toast.makeText(getApplicationContext(),"invalid :" + testfilepath, 2000).show();
 }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.