จะรับ 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);
}

ช่วยบอกหน่อยได้ไหมว่าฉันจะพูดถึงพา ธ สัมบูรณ์สำหรับไฟล์ที่มีอยู่ในโฟลเดอร์เนื้อหาได้อย่างไร

คำตอบ:


160

ไม่มี "พา ธ สัมบูรณ์สำหรับไฟล์ที่มีอยู่ในโฟลเดอร์เนื้อหา" เนื้อหาของassets/โฟลเดอร์ของโครงการของคุณจะรวมอยู่ในไฟล์ APK ใช้AssetManagerวัตถุเพื่อรับInputStreamเนื้อหา

สำหรับWebViewคุณสามารถใช้file Uriโครงร่างในลักษณะเดียวกับที่คุณใช้ URL ไวยากรณ์สำหรับเนื้อหาคือfile:///android_asset/...(หมายเหตุ: เครื่องหมายทับสามตัว) โดยที่จุดไข่ปลาคือเส้นทางของไฟล์จากภายในassets/โฟลเดอร์


32
file://android_asset/...ซึ่ง...เป็นเส้นทางที่ญาติภายในโครงการของassets/ไดเรกทอรี
CommonsWare

4
นี่คือตัวอย่างโครงการที่ใช้file://android_asset/แม้ว่าจะไม่ใช่สำหรับUri: github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
CommonsWare

20
@CommonsWare ดูเหมือนว่าคุณพลาด "/" ใน URI ของคุณ file:///มันควรจะเป็น
ThomasW

7
ฉันลองเป็นnew File("file:///android_asset/sounds/beep.mid");แล้ว แต่ไม่มีไฟล์ผลลัพธ์ ความคิดใด ๆ ? ไฟล์ PS อยู่ในassets/sounds/โฟลเดอร์
ลุงเลม

3
ถูกต้องหรือไม่ที่´file: ///android_asset/...´ ใช้งานได้เฉพาะใน WebView และไม่สามารถรับ InputStream โดยใช้ URI / URL / Uri นอก WebView ได้
Lubbo

74

url ที่ถูกต้องคือ:

file:///android_asset/RELATIVEPATH

โดยที่ RELATIVEPATH เป็นเส้นทางไปยังทรัพยากรของคุณที่สัมพันธ์กับโฟลเดอร์ assets

สังเกต 3 / ของในโครงร่าง การดูเว็บจะไม่โหลดเนื้อหาใด ๆ ของฉันหากไม่มี 3 ฉันลอง 2 ตามที่ (ก่อนหน้านี้) แสดงความคิดเห็นโดย CommonsWare และมันจะไม่ทำงาน จากนั้นฉันดูแหล่งที่มาของ CommonsWare ใน github และสังเกตเห็นเครื่องหมายทับ

แม้ว่าการทดสอบนี้จะทำบนตัวจำลอง Android 1.6 แต่ฉันสงสัยว่ามันแตกต่างจากอุปกรณ์จริงหรือเวอร์ชันที่สูงกว่า

แก้ไข: CommonsWare อัปเดตคำตอบของเขาเพื่อสะท้อนการเปลี่ยนแปลงเล็ก ๆ นี้ ดังนั้นฉันจึงแก้ไขสิ่งนี้เพื่อให้ยังสมเหตุสมผลกับคำตอบปัจจุบันของเขา


ไม่ทำงานอีกต่อไป String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Elgirhath

@Elgirhath สร้างสำหรับFileที่ยอมรับสตริงคาดว่าเส้นทางที่ไม่ได้เป็นURI ฉันไม่ได้เขียนโค้ดสำหรับ Android มาสองสามปีแล้วและอาจมีการเปลี่ยนแปลงบางอย่าง ฉันไม่แน่ใจว่าคุณสามารถเข้าถึงโฟลเดอร์สินทรัพย์ที่ฝังโดยใช้คลาสไฟล์จาวาปกติได้หรือไม่ ฉันดูเหมือนจะจำไว้ว่าคุณต้องใช้AssetManager ไฟล์ในโฟลเดอร์ assets จะถูกวางไว้ในอุปกรณ์ใน 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

ในที่สุดฉันก็พบวิธีรับเส้นทางของไฟล์ที่มีอยู่ในเนื้อหาจากคำตอบนี้ใน Kotlin ที่นี่เรากำลังคัดลอกไฟล์สินทรัพย์ไปยังแคชและรับเส้นทางไฟล์จากไฟล์แคชนั้น

@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()...
Yeung

7

ใส่คำอธิบายภาพที่นี่

ตรวจสอบให้แน่ใจว่าโฟลเดอร์เนื้อหาของคุณอยู่ในตำแหน่งที่ถูกต้อง


คุณสามารถวางได้ทุกที่ที่คุณต้องการและกำหนดเส้นทางในไฟล์ build.gradle ของคุณดังนี้sourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Marcel Bro

2
วิธีรับเส้นทางของ hello.html โปรดเพิ่ม
Rohit Singh

6

การทำงานสำหรับ WebView URL.openStream()แต่ดูเหมือนว่าจะล้มเหลวใน ดังนั้นคุณต้องแยกแยะ file: // protocols และจัดการผ่าน AssetManager ตามที่แนะนำ


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

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); 

ฉันได้ทำและมันได้ผล


2
มันใช้งานได้จริง ตรวจสอบContentResolver.openAssetFileDescriptor
Hippo Seven

1
ทำงาน ขอบคุณมาก. ฮ่า ๆ ฉันแค่มองหาไฟล์ภายใน URI // สร้างไฟล์ RAW FOLDER INSIDE RES จากนั้นชื่อไฟล์ที่มีเพียง a..z0..9 ตัวอักษรไม่มีส่วนบน !!!
phnghue

0

ใช่คุณไม่สามารถเข้าถึงโฟลเดอร์ในไดรฟ์ของคุณจากโทรศัพท์ Android หรือโปรแกรมจำลองเนื่องจากคอมพิวเตอร์และ Android ของคุณเป็นระบบปฏิบัติการที่แตกต่างกันสองระบบฉันจะไปที่โฟลเดอร์ res ของ android เพราะมีวิธีการจัดการทรัพยากรที่ดี จนกว่าคุณจะมีเหตุผลที่ดีมากในการนำไฟล์ไปไว้ในโฟลเดอร์ assets คุณสามารถทำสิ่งนี้แทนได้

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();
 }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.