Làm cách nào để lấy URI từ một tệp tài sản?


127

Tôi đã cố gắng để có được đường dẫn URI cho một tệp tài sản.

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

Khi tôi kiểm tra xem tệp có tồn tại không, tôi thấy tệp đó không tồn tại

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

Ai đó có thể cho tôi biết làm thế nào tôi có thể đề cập đến đường dẫn tuyệt đối cho một tệp hiện có trong thư mục tài sản không

Câu trả lời:


160

Không có "đường dẫn tuyệt đối cho một tệp hiện có trong thư mục tài sản". Nội dung của assets/thư mục dự án của bạn được đóng gói trong tệp APK. Sử dụng một AssetManagerđối tượng để có được InputStreammột tài sản.

Đối với WebView, bạn có thể sử dụng file Urilược đồ theo cách tương tự như bạn sẽ sử dụng URL. Cú pháp của tài sản là file:///android_asset/...(lưu ý: ba dấu gạch chéo) trong đó dấu chấm lửng là đường dẫn của tệp từ trong assets/thư mục.


32
file://android_asset/..., đâu ...là đường dẫn tương đối trong thư mục dự án của bạn assets/.
CommonsWare

4
Đây là một dự án mẫu sử dụng file://android_asset/, mặc dù không dành cho Uri: github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
CommonsWare

20
@CommonsWare có vẻ như bạn đã bỏ lỡ một '/' trong URI của mình. Nó phải file:///.
ThomasW

7
Tôi đã thử điều này như new File("file:///android_asset/sounds/beep.mid");, nhưng tập tin kết quả không tồn tại. Có ý kiến ​​gì không? Tập tin PS nằm trong assets/sounds/thư mục.
chú Lem

3
Có đúng không khi đó, hayfile: ///android_asset/....
Lubbo

74

Url đúng là:

file:///android_asset/RELATIVEPATH

trong đó TƯƠNG THÍCH là đường dẫn đến tài nguyên của bạn so với thư mục tài sản.

Lưu ý 3 / 's trong sơ đồ. Chế độ xem web sẽ không tải bất kỳ tài sản nào của tôi nếu không có 3. Tôi đã thử 2 như (trước đây) được nhận xét bởi CommonsWare và nó sẽ không hoạt động. Sau đó, tôi nhìn vào nguồn của CommonsWare trên github và nhận thấy dấu gạch chéo về phía trước.

Thử nghiệm này mặc dù chỉ được thực hiện trên trình giả lập Android 1.6 nhưng tôi nghi ngờ sự khác biệt của nó trên một thiết bị thực hoặc phiên bản cao hơn.

EDIT: CommonsWare đã cập nhật câu trả lời của mình để phản ánh sự thay đổi nhỏ này. Vì vậy, tôi đã chỉnh sửa điều này để nó vẫn có ý nghĩa với câu trả lời hiện tại của anh ấy.


Không hoạt động nữa String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Elgirhath

@Elgirhath hàm tạo cho Fileviệc chấp nhận một chuỗi đang mong đợi một đường dẫn không phải là URI . Tôi đã không được mã hóa cho Android trong một vài năm và mọi thứ có thể đã thay đổi. Tôi không chắc chắn nếu bạn có thể truy cập thư mục tài sản được nhúng bằng lớp Tệp java bình thường. Tôi dường như nhớ rằng bạn phải sử dụng AssetManager . Các tệp trong thư mục tài sản được đặt trên thiết bị trong APK được đóng gói chỉ đọc và được nén (APK thực sự là các tệp zip), do đó sẽ cần nhiều công việc hơn để đọc lại. Hãy thử một cái gì đó nhưnew File(new URI(filename))
Russ

10

Vui lòng thử mã này hoạt động tốt

 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

Cuối cùng, tôi đã tìm ra cách để có được đường dẫn của một tệp có trong tài sản từ câu trả lời này trong Kotlin. Ở đây chúng tôi đang sao chép tệp tài sản vào bộ đệm và nhận đường dẫn tệp từ tệp bộ đệm đó.

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

Nhận đường dẫn đến tệp như:

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

1
Lưu ý rằng nếu fileNamecó thư mục dir/file. Nó sẽ sụp đổ với con đường cache/dir/filekhông tồn tại. Ngoài ra tôi nghĩ tốt hơn nên kiểm tra if(!it.exist)bên trong alsokhối, sau đó nó sẽ không sao chép tệp mỗi lần ngay cả khi tệp đã có trong bộ đệm
Yeung

@ShylendraMadda, @Yeung, if(!it.exist)đưa ra một lỗi không thể giải quyết được. bất kì giải pháp nào ?
binrebin

Kiểm tra tập tin đó tồn tại trong bộ đệm của bạn với tên tập tin đó? @binrebin
Shylendra Madda

@ShylendraMadda, tôi chỉ biết tên tệp. Chúng ta có thể tải nó với tập lệnh mà không biết uri thực tế
binrebin

Tôi nghĩ if(!it.exist)nên đặt trước it.outputStream()...
Yeung

7

nhập mô tả hình ảnh ở đây

Hãy chắc chắn, thư mục tài sản của bạn đặt ở vị trí chính xác.


Bạn có thể đặt nó bất cứ nơi nào bạn muốn và xác định đường dẫn trong tệp build.gradle của bạn như sausourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Marcel Bro

2
Làm cách nào để có đường dẫn của hello.html? vui lòng thêm
Rohit Singh

6

Hoạt động cho WebView nhưng dường như không thành công URL.openStream(). Vì vậy, bạn cần phân biệt tệp: // giao thức và xử lý chúng thông qua AssetManager theo đề xuất.


4

Hãy thử nó, nó hoạt động:

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

Nếu bạn nhận được một ngoại lệ giá trị Null, hãy thử điều này (với lớp TopBrandData):

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

Nếu không hoạt động, vui lòng Thử cái này: InputStream in_s1 = TopBrandData. Class.getResourceAsStream ("/ Tài sản / 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;
}

1

thử cái này :

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

Tôi đã làm nó và nó làm việc


2
Trên thực tế nó hoạt động. Kiểm tra ContentResolver.openAssetFileDescriptor
Hippo Seven

1
Đã làm việc. Cảm ơn rất nhiều. Lol, tôi chỉ tìm kiếm tập tin nội bộ URI // TẠO FILE RAW TRONG NỀN TẢNG, THÌ TÊN TÊN FILE CONTAIN CHỈ a..z0..9 ký tự, KHÔNG TĂNG CƯỜNG !!!
phnghue

0

Vâng, bạn không thể truy cập thư mục ổ đĩa từ điện thoại Android hoặc trình giả lập vì máy tính và Android của bạn là hai hệ điều hành khác nhau. Tôi sẽ chọn thư mục res của Android vì nó có phương pháp quản lý tài nguyên tốt. Cho đến khi và trừ khi bạn có lý do rất chính đáng để đặt tệp của bạn vào thư mục tài sản. Thay vào đó bạn có thể làm điều này

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

Làm việc cho tôi Hãy thử mã này

   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();
 }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.