Como obter URI de um arquivo de ativo?

127

Eu tenho tentado obter o caminho do URI para um arquivo de ativos.

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

Quando verifico se o arquivo existe, vejo que ele não existe

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

Alguém pode me dizer como posso mencionar o caminho absoluto para um arquivo existente na pasta do ativo

Titus
fonte

Respostas:

160

Não há "caminho absoluto para um arquivo existente na pasta do ativo". O conteúdo da assets/pasta do seu projeto está empacotado no arquivo APK. Use um AssetManagerobjeto para obter InputStreamum ativo.

Para WebView, você pode usar o file Uriesquema da mesma maneira que usaria um URL. A sintaxe dos ativos é file:///android_asset/...(nota: três barras) em que as reticências são o caminho do arquivo dentro da assets/pasta.

CommonsWare
fonte
32
file://android_asset/..., onde ...é o caminho relativo no assets/diretório do seu projeto .
CommonsWare
4
Aqui está um projeto de amostra usando file://android_asset/, embora não seja para Uri: github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
CommonsWare
20
@CommonsWare parece que você perdeu um '/' no seu URI. Deveria ser file:///.
21411 Thomas
7
Eu tentei isso como new File("file:///android_asset/sounds/beep.mid");, mas o arquivo de resultado não existe. Alguma ideia? O arquivo PS está na assets/sounds/pasta
uncle Lem
3
É verdade que o arquivo: ///android_asset/... funciona apenas no WebView e não é possível obter o InputStream usando URI / URL / Uri fora do WebView?
Lubbo
74

O URL correto é:

file:///android_asset/RELATIVEPATH

em que RELATIVEPATH é o caminho para o seu recurso em relação à pasta de ativos.

Observe os 3 / 's no esquema. A exibição na Web não carregaria nenhum dos meus ativos sem o 3. Tentei o 2 como (anteriormente) comentado pelo CommonsWare e não funcionou. Então olhei a fonte do CommonsWare no github e notei a barra extra para a frente.

Este teste, porém, foi feito apenas no emulador Android 1.6, mas duvido que seja diferente em um dispositivo real ou em uma versão superior.

EDIT: O CommonsWare atualizou sua resposta para refletir essa pequena alteração. Então, eu editei isso para que ainda faça sentido com a resposta atual.

Russ
fonte
Não funciona mais String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Elgirhath 19/06
@ Elgirhath, o construtor Fileque aceita uma string está esperando um caminho e não um URI . Não codifico para o Android há alguns anos e as coisas podem ter mudado. Não tenho certeza se você pode acessar a pasta de ativos incorporados usando uma classe Java normal. Parece que me lembro que você precisa usar um AssetManager . Os arquivos na pasta de ativos são colocados no dispositivo no APK empacotado somente leitura e compactados (APKs são, na verdade, arquivos zip), portanto, é mais trabalhoso lê-lo novamente. Tente algo comonew File(new URI(filename))
Russ
10

Por favor, tente este código funcionando bem

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

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

Por fim, encontrei uma maneira de obter o caminho de um arquivo presente nos ativos a partir desta resposta no Kotlin. Aqui, estamos copiando o arquivo de ativos para o cache e obtendo o caminho do arquivo desse arquivo de cache.

@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)
                    }
                  }
                }
            }

Obtenha o caminho para o arquivo como:

val filePath =  getFileFromAssets(context, "fileName.extension").absolutePath
Shylendra Madda
fonte
1
Observe que se o fileNamediretório tiver dir/file. Ele falhará com o caminho que cache/dir/filenão existe. Também acho melhor ter uma verificação if(!it.exist)no interior do alsobloco, então ele não irá copiar o arquivo de cada vez até mesmo o arquivo já está em cache
Yeung
@ShylendraMadda, @Yeung, if(!it.exist)lança uma referência não resolvida de erro. qualquer solução ?
binrebin
Verifique se o arquivo existe no seu cache com esse nome? @binrebin
Shylendra Madda
@ShylendraMadda, eu sei apenas o nome do arquivo. Podemos carregá-lo com script sem saber uri real
binrebin
Eu acho que if(!it.exist)deveria colocar antes it.outputStream()...
Yeung
7

insira a descrição da imagem aqui

Certifique-se de que sua pasta de ativos esteja na posição correta.

Chuanhang.gu
fonte
Você pode colocá-lo onde quiser, e definir o caminho no seu arquivo build.gradle da seguinte formasourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Marcel Bro
2
Como encontrar o caminho de hello.html? Por favor, adicione
Rohit Singh
6

Funciona para o WebView, mas parece falhar URL.openStream(). Portanto, você precisa distinguir os protocolos file: // e manipulá-los via AssetManager, conforme sugerido.

Gaylord Zach
fonte
4

Experimente isso, funciona:

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

Se você receber uma exceção de valor nulo, tente o seguinte (com classe TopBrandData):

InputStream in_s1 =
    TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");
Jaspreet Singh
fonte
Se não estiver funcionando, tente este: InputStream in_s1 = TopBrandData.class.getResourceAsStream ("/ assets / TopBrands.xml");
Jaspreet Singh
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;
}
jayesh kavathiya
fonte
1

tente isto:

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

Eu tinha feito e funcionou

Nyle
fonte
2
Na verdade funciona. Verifique o ContentResolver.openAssetFileDescriptor
Hippo Seven
1
Trabalhou. Muito obrigado. Lol, estou apenas procurando obter o arquivo interno do URI // CRIAR PASTA RAW DENTRO DE RES, ENTÃO NOME ARQUIVO CONTÉM APENAS um caractere..z0..9, SEM MAIÚSCULAS !!!
Phnghue
0

Sim, você não pode acessar a pasta da unidade a partir do seu telefone ou emulador Android, porque o seu computador e o Android são dois sistemas operacionais diferentes. Eu iria para a pasta res do Android, porque possui bons métodos de gerenciamento de recursos. Até e a menos que você tenha um bom motivo para colocar seu arquivo na pasta de ativos. Em vez disso, você pode fazer isso

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);
 }
não vai desistir
fonte
-7

Trabalhou para mim Experimente este código

   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();
 }
Irfan Ali
fonte